with(String target) {
return with(target, Object.class);
}
}
上述代码就实现了一个通信总线的全部功能,并且还具有生命周期感知功能,并且使用起来也及其简单:
注册订阅:
LiveDataBus.get().with("key_test", Boolean.class)
.observe(this, new Observer() {
@Override
public void onChanged(@Nullable Boolean aBoolean) {
}
});
发送消息:
LiveDataBus.get().with("key_test").setValue(true);
发送了一个名为”key_test”,值为 true 的事件。这个时候订阅者就会收到消息,并作相应的处理。
4.1.1 问题
在使用实现一这个 LiveDataBus 的过程中,订阅者会收到订阅之前发布的消息。无论 EventBus 或者 RxBus,订阅方都不会收到订阅之前发出的消息。对于一个消息总线,LiveDataBus 必须要解决这个问题
4.1.2 问题分析
当 LifeCircleOwner 的状态发生变化的时候,会调用 LiveData.ObserverWrapper 的 activeStateChanged 函数,如果这个时候 ObserverWrapper 的状态是 active,就会调用 LiveData 的 dispatchingValue。
在 LiveData 的 dispatchingValue 中,又会调用 LiveData 的 considerNotify 方法。
在 LiveData 的 considerNotify 方法中,红框中的逻辑是关键,如果 ObserverWrapper 的 mLastVersion 小于 LiveData 的 mVersion,就会去回调 mObserver 的 onChanged 方法。而每个新的订阅者,其 version 都是-1,LiveData 一旦设置过其 version 是大于-1的(每次 LiveData 设置值都会使其 version 加1),这样就会导致 LiveDataBus 每注册一个新的订阅者,这个订阅者立刻会收到一个回调,即使这个设置的动作发生在订阅之前。
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// 观察者没有处于活跃状态则不分发。
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// 观察者接收消息的次数 >= LiveData 发送消息的次数,不分发。
// 如果之前已经发送过数据,新注册的 observer 也能收到最后一条数据。
if (observer.mLastVersion >= mVersion) {
return;
}
// 根本原因在于 ObserverWrapper 的 version 字段在创建时 = -1,没有主动和 LiveData 的 mVersion 字段对齐。
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
核心原因: 对于 LiveData,其初始的 version 是-1,当我们调用了其 setValue或者 postValue,其 vesion 会+1;对于每一个观察者的封装 ObserverWrapper,其初始 version 也为-1,也就是说,每一个新注册的观察者,其 version 为-1;当LiveData 设置这个 ObserverWrapper 的时候,如果 LiveData 的 version 大于 ObserverWrapper 的 version,LiveData 就会强制把当前 value 推送给 Observer。
private int mVersion = START_VERSION;
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
4.1.3 如何解决这个问题
只需要在注册一个新的订阅者的时候把 ObserverWrapper 的 version 设置成跟 LiveData 的 version 一致即可。
在 LiveData 的 observe 方法中,会创建一个 LifecycleBoundObserver,LifecycleBoundObserver 是 ObserverWrapper 的派生类。然后把这个LifecycleBoundObserver 放入一个私有 Map 容器 mObservers 中。无论ObserverWrapper 还是 LifecycleBoundObserver 都是私有的或者包可见的,所以无法通过继承的方式更改 LifecycleBoundObserver 的 version。
从 Map 容器 mObservers 中取到 LifecycleBoundObserver,然后再更改 version,通过查看 SafeIterableMap 的源码我们发现有一个 protected 的 get 方法。因此,在调用 observe 的时候,我们可以通过反射拿到 LifecycleBoundObserver,再把 LifecycleBoundObserver 的 version 设置成和 LiveData 一致即可。
对非生命周期感知的 observeForever 方法,生成的 wrapper 不是 LifecycleBoundObserver 而是 AlwaysActiveObserver,没有办法在 observeForever 调用完后再改 AlwaysActiveObserver 的 version,因为注册监听时直接调了 wrapper.activeStateChanged(true) 而不是在 LifeCircleOwner 的状态变化时。
那么对于 observeForever,如何解决这个问题呢? 既然是在调用内回调的,那么我们可以写一个 ObserverWrapper,包装真正的回调传给 observeForever。把 ObserverWrapper 传给 observeForever,回调时检查调用栈,如果回调是 observeForever 方法引起的,那么就不回调真正的订阅者。
// 包装类包裹真正的Observer,处理非生命周期感知的注册监听
private static class ObserverWrapper implements Observer {
private Observer observer;
public ObserverWrapper(Observer observer) {
this.observer = observer;
}
public void onChanged(@Nullable T t) {
if (observer != null) {
// 目标方法不调onChanged
if (isCallOnObserve()) {
return;
}
observer.onChanged(t);
}
}
private boolean isCallOnObserve() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
if (stackTrace != null && stackTrace.length > 0) {
for (StackTraceElement element : stackTrace) {
// 如果当前是LiveData对象且为observeForever方法
if ("android.arch.lifecycle.LiveData".equals(element.getClassName()) &&
"observeForever".equals(element.getMethodName())) {
return true;
}
}
}
return false;
}
}
Hook
在事件传递过程中拦截并监控事件的传输,修改事件传递流程 只要调用 setValue 版本号 mVersion 就会加1,此时版本号已经不一致导致 onChange 的调用,触发粘性事件,如果将 mObservers.observer.mLastVersion 修改为 mVersion 当前版本,就会在 mObservers.observer.onChange 调用前,也就是数据变化通知前 return 结束,这样就不调 onChange 方法 mObservers 是 Map 对象,Map 的 item 是键值对,observer 是键值对的 value,反射 Map 获取到 Entry 并获取到 value 也就是 observer 继承 MutableLiveData,重写 observe 方法,在注册监听时进行 hook 逻辑。
LiveDataBus最终实现
/**
* @desciption : 利用LivaData来实现数据传递,可用来替换EventBus
*/
public class LiveDataBus {
private final Map> bus;
private LiveDataBus() {
bus = new HashMap<>();
}
private static class SingletonHolder {
private static final LiveDataBus DEFAULT_BUS = new LiveDataBus();
}
public static LiveDataBus get() {
return SingletonHolder.DEFAULT_BUS;
}
public MutableLiveData with(String key, Class type) {
if (!bus.containsKey(key)) {
bus.put(key, new BusMutableLiveData<>());
}
return (MutableLiveData) bus.get(key);
}
public MutableLiveData with(String key) {
return with(key, Object.class);
}
private static class ObserverWrapper implements Observer {
private Observer observer;
public ObserverWrapper(Observer observer) {
this.observer = observer;
}
@Override
public void onChanged(@Nullable T t) {
if (observer != null) {
if (isCallOnObserve()) {
return;
}
observer.onChanged(t);
}
}
private boolean isCallOnObserve() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
if (stackTrace != null && stackTrace.length > 0) {
for (StackTraceElement element : stackTrace) {
if ("android.arch.lifecycle.LiveData".equals(element.getClassName()) &&
"observeForever".equals(element.getMethodName())) {
return true;
}
}
}
return false;
}
}
private static class BusMutableLiveData extends MutableLiveData {
private Map observerMap = new HashMap<>();
// 生命周期感知的注册监听处理,去除粘性事件
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
super.observe(owner, observer);
try {
hook(observer);
} catch (Exception e) {
e.printStackTrace();
}
}
// 非生命周期感知的注册监听处理,去除粘性事件
@Override
public void observeForever(@NonNull Observer observer) {
if (!observerMap.containsKey(observer)) {
observerMap.put(observer, new ObserverWrapper(observer));
}
super.observeForever(observerMap.get(observer));
}
// 非生命周期感知取消注册监听
@Override
public void removeObserver(@NonNull Observer observer) {
Observer realObserver = null;
if (observerMap.containsKey(observer)) {
realObserver = observerMap.remove(observer);
} else {
realObserver = observer;
}
super.removeObserver(realObserver);
}
// 去除粘性事件
private void hook(@NonNull Observer observer) throws Exception {
//get wrapper's version
//1.得到mLastVersion
//获取到LivData的类中的mObservers对象
Class classLiveData = LiveData.class;
Field fieldObservers = classLiveData.getDeclaredField("mObservers");
fieldObservers.setAccessible(true);
//获取到这个成员变量的对象
Object objectObservers = fieldObservers.get(this);
//得到map对象的class对象
Class classObservers = objectObservers.getClass();
//获取到mObservers对象的get方法
Method methodGet = classObservers.getDeclaredMethod("get", Object.class);
methodGet.setAccessible(true);
//执行get方法
Object objectWrapperEntry = methodGet.invoke(objectObservers, observer);
//取到entry中的value
Object objectWrapper = null;
if (objectWrapperEntry instanceof Map.Entry) {
objectWrapper = ((Map.Entry) objectWrapperEntry).getValue();
}
if (objectWrapper == null) {
throw new NullPointerException("Wrapper can not be bull!");
}
//得到observerWraperr的类对象
Class classObserverWrapper = objectWrapper.getClass().getSuperclass();
Field fieldLastVersion = classObserverWrapper.getDeclaredField("mLastVersion");
fieldLastVersion.setAccessible(true);
//get livedata's version
//2.得到mVersion
Field fieldVersion = classLiveData.getDeclaredField("mVersion");
fieldVersion.setAccessible(true);
//3.mLastVersion=mVersion
Object objectVersion = fieldVersion.get(this);
//set wrapper's version
fieldLastVersion.set(objectWrapper, objectVersion);
}
}
}
注册订阅:
LiveDataBus.get()
.with("key_test", String.class)
.observe(this, new Observer() {
@Override
public void onChanged(@Nullable String s) {
}
});
发送消息:
LiveDataBus.get().with("key_test").setValue(s);
引用:
Android消息总线的演进之路:用LiveDataBus替代RxBus、EventBus
你可能感兴趣的:(基于 LiveData 封装 LiveDataBus 消息总线)
怎么使用DeepSeek?DeepSeek使用教程
轻创思维
网络
1.简介DeepSeek是一款基于人工智能技术的智能搜索引擎和信息检索工具。它能够通过自然语言处理技术理解用户的查询需求,并提供精准、全面的搜索结果。无论您是想查找信息、解答问题还是进行创意写作,DeepSeek都能为您提供高效的支持。2.主要功能智能搜索:支持自然语言输入,快速获取精准结果。多语言支持:支持中文、英文及其他多种语言的输入和输出。知识库覆盖:整合海量互联网信息,覆盖百科、新闻、学术
延迟任务的11种实现方式(下)!!
架构文摘JGWZ
学习 后端 Java 编程语言
接上文:Redisson的RDelayedQueueRedisson他是Redis的儿子(Redisson),基于Redis实现了非常多的功能,其中最常使用的就是Redis分布式锁的实现,但是除了实现Redis分布式锁之外,它还实现了延迟队列的功能。先来个demo引入pom org.redisson redisson 3.13.1封装了一个RedissonDelayQueue类@
探索TotalSegmentator:一款强大的全场景图像分割工具
计蕴斯Lowell
探索TotalSegmentator:一款强大的全场景图像分割工具项目地址:https://gitcode.com/gh_mirrors/to/TotalSegmentator项目简介是一个开源的、基于深度学习的全场景图像分割框架。它由开发者Wasserth创建,旨在为医学影像分析、自动驾驶、遥感图像处理等多个领域提供高效且准确的像素级分类能力。该项目的亮点在于其模型的通用性和易用性,能够处理多种
IPoIB 接收数据流程分析
109702008
编程 # C语言 网络 人工智能 linux 网络
1.引言IPoIB(InfiniBandoverIP)是一种将InfiniBand协议封装在IP网络中的技术,允许通过标准的以太网基础设施传输InfiniBand数据。本文将详细分析IPoIB驱动程序中接收数据的处理流程,重点关注关键函数的实现和数据处理的关键步骤。2.网络设备操作结构体staticconststructnet_device_opsipoib_netdev_default_pf_r
DeepSeek接入大数据能做什么
PersistDZ
大数据与AI 大数据
DeepSeek作为一家专注于AGI和AI大模型技术的公司,在大数据领域可以通过以下方式切入,结合其核心能力提供创新解决方案:一、DeepSeek接入大数据领域的技术路径多模态数据处理能力支持文本/图像/视频/传感器数据的统一处理自主研发的MoE(MixtureofExperts)架构可并行处理异构数据超大规模特征工程基于千亿参数模型的自动特征提取支持非结构化数据的深度语义解析实时计算优化自研分布
Web开发中的可专利性分析:透过一个案例学习
CodePatentMaster
前端 学习
Web开发工程师在创新过程中经常面临是否能申请专利并获得专利权的问题。本文通过一个详细的Web开发领域案例来阐释可专利性的分析过程。案例分析假设您是一名Web开发工程师,您开发了一种名为“动态响应式前端框架”(DynamicResponsiveFrontendFramework,DRFF)的新型前端框架。与传统前端框架相比,DRFF通过引入一种基于AI的组件化设计方法和实时数据流处理机制,显著提高
SpringBoot 新手入门(实操)
李恩11
spring boot 后端 java
SpringBoot是一个开源框架,旨在简化基于Spring的Java应用程序的开发。它通过提供一系列默认配置和约定大于配置的理念,让开发者可以更快速地创建和部署应用。以下是一个SpringBoot新手入门的实操指南,帮助你从零开始创建一个简单的SpringBoot应用程序。环境准备安装JDK:SpringBoot需要JavaDevelopmentKit(JDK)8或更高版本。你可以从Oracle
从零到入门:人工智能学习路径全解析
这题有点难度
人工智能 学习
一、打破迷雾:重新认识人工智能人工智能(AI)早已不再是科幻电影中的专属概念,而是渗透到我们生活的方方面面。从手机里的语音助手到电商平台的推荐系统,从自动驾驶到医疗影像分析,AI技术正在重塑人类社会的运行方式。对于初学者而言,建立正确的认知框架至关重要:1.技术图谱解析:机器学习(ML):AI的核心驱动力,使计算机具备从数据中学习的能力深度学习(DL):基于神经网络的进阶技术,擅长处理图像、语音等
今日-Vue框架
幼儿园口算大王
vue.js 前端 javascript java
什么是VUE框架?Vue是一款用于构建用户界面的JavaScript框架。它基于标准HTML、CSS和JavaScript构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。Vue的核心是一个响应的数据绑定系统,它让数据与DOM保持同步非常简单。Vue的目标是通过尽可能简单的API实现响应的数据绑定和组合的视图组件。它不仅易于上手,还便于与第三方库或既有项目整合。Vue也被称为
python分布式爬虫去重_Python分布式爬虫(三) - 爬虫基础知识
weixin_39997311
python分布式爬虫去重
0相关源码1技术选型爬虫能做什么1.1scrapyVSrequests+beautifulsoup做爬虫的时候,经常都会听到scrapyVSrequests+beautifulsoup的组合在本次分布式爬虫实现中只用scrapy而不用后者的原因是:requests和beautifulsoup都是库,scrapy是一个框架框架中可以应用requests等,可以集合很多第三方库基于twisted(异步
量子计算威胁下Java应用的安全防护:技术剖析与实践
老猿讲编程
量子计算 java 安全
在科技飞速发展的当下,众多公司与研究团队全力投入实现量子霸权的研究,使得量子计算机超越传统计算机运算效率的未来愈发临近。量子计算虽蕴含着巨大的潜力,但也给现有加密体系带来了严峻挑战。一旦量子计算机具备破解当前加密算法的能力,大量基于现有加密技术保护的数据和通信都将面临风险,“先窃取,后解密”的攻击策略可能成为现实。在此背景下,Java应用如何构建有效的防御机制,抵御量子攻击,成为了亟待解决的关键问
Intel i7系列CPU替换为Xeon X79或X99架构的CPU替代方案和对比分析
gzgenius
CPU 个人PC采购 XEON 电脑
Inteli7系列CPU替换为XeonX79或X99架构的CPU,需要从性能、功耗、兼容性、价格和应用场景等多方面进行分析。以下是针对不同用户群体的替代方案和对比分析:1.XeonX79和X99架构简介XeonX79:基于IntelSandyBridge架构,支持三路或四路处理器扩展,适合高端服务器和工作站。XeonX99:基于IntelBroadwell架构,支持双路扩展,适合高性能计算和虚拟化
游戏出海 | 游戏本地化需要注意的10条规则
Alconost
Alconost出海本地化 游戏
Alconost是一家美国本地化服务的公司,业务涉及120多种语言。Alconost基于过去20多年服务数百游戏的本地化经验,总结分析出这篇文章。Alconost游戏本地化https://blog.alconost.com/zh-cn/translation-game?utm_source=CSDN&utm_medium=article&utm_campaign=game_loc_ten_rule
海量日志接入 Serverless 应用降本70%以上
概述随着互联网业务的快速发展,日志数据量日益庞大,传统的日志处理方式面临着成本高、扩展性差等问题。为了应对这一挑战,越来越多的企业开始转向更先进的解决方案——阿里云ElasticsearchServerless。本文档将探讨在日志场景下,使用阿里云ElasticsearchServerless相较于基于ECS自建Elasticsearch集群的成本与性能优势,展示如何通过Serverless架构实
ColD Fusion,分布式多任务微调的协同 “密码”
人工智能
ColDFusion,分布式多任务微调的协同“密码”发布时间:2025-02-19近日热文:1.全网最全的神经网络数学原理(代码和公式)直观解释2.大模型进化史:从Transformer到DeepSeek-R1的AI变革之路3.2W8000字深度剖析25种RAG变体:全网最全~没有之一知乎【柏企】公众号【柏企科技说】【柏企阅文】在预训练模型的基础上进行改进,有望提升所有基于它微调的模型性能。然而,
寻找可接入正版音乐库的音乐API,可了解HIFIVE音乐开放平台!
apisdkapi文档音乐
HIFIVE音乐开放平台基于HIFIVE数百万正版音乐版权内容,为直播、短视频、工具应用、智能硬件等场景提供音乐解决方案。点击了解:(https://open.haifanwu.com/)HIFIVE音乐开放平台提供以下接入服务:服务服务描述获取音乐列表通过歌单获取音乐列表,通过关键词搜索获取音乐列表,通AI音乐推荐获取音乐列表音乐播放获取音乐试听版本,获取完整音乐文件AI剪辑结合AI推荐技术完成
AI技术在音乐产品中有哪些应用场景?
大数据人工智能音乐大数据
自动标注、平滑过渡、音乐鉴权、AI创作,当AI技术应用于音乐行业为人类的精神文化与娱乐生活带来便利和更多选择时,也是一件让人激动不已的事情。随着深度学习算法的出现、大数据和5G技术的成熟,AI人工智能已逐渐融入我们的生产生活中,在教育、医疗、政务办公、城市管理等多个方面发挥作用。随着AI技术在音乐行业研究及应用的深入,音乐人工智能已经不新鲜,很多新的应用和产品已经惊艳亮相。基于对于音乐技术及产品的
IP SSL—国产信创级SSL证书申请步骤
ssl证书https
IPSSL即针对IP地址申请的SSL证书,可以确保网络通信安全。以下是国产信创级SSL证书的申请步骤一、准备阶段确定公网IP地址:确保拥有一个独立的公网IP地址,该IP地址需要能够开启常用端口中的一个(验证过程中需短暂开放),验证通过后,可以关闭或者制定任意端口打开。选择证书颁发机构(CA):选择一个受信任的国产信创级SSL证书供应商,如JoySSL等,这些机构已证实具备处理基于IP的SSL证书签
【深度学习入门:基于python的理论与实现读书笔记】第五章误差反向传播法
Bin二叉
深度学习 python 人工智能
目录摘要第五章误差反向传播法简单层的实现乘法层的实现加法层的实现激活函数层的实现ReLU层Sigmoid层Affine层和Softmax层的实现Affine层Softmax-with-Loss层误差反向传播法的实现摘要该文章简要介绍了神经网络的误差反向传播法,省去了大量的推理过程,重点讲述了神经网络误差反向传播法的代码实现。第五章误差反向传播法反向传播就是从后到前局部计算偏导数并将其与从上游传来的
VeighNa:强大的Python开源量化交易平台
@Unity打怪升级
Python python 开发语言 开源软件 开源 人工智能 机器学习 深度学习
VeighNa(简称VN或vn.py)是一个基于Python的开源量化交易平台,专为量化交易爱好者和专业交易员设计。VeighNa是由国内开发者社区推动的开源项目,旨在提供一个功能丰富、灵活且易于扩展的量化交易解决方案。该框架不仅支持多种资产类别的交易,如股票、期货、期权、加密货币等,还支持多种交易接口和协议,使得用户能够轻松进行多市场、多品种的交易策略开发和部署。VeighNa提供了丰富的量化交
力扣 跳跃游戏 II
孑么
力扣 leetcode 算法 职场和发展 java 动态规划 贪心算法
贪心算法,存下每一步的最远,去达到全局的最小跳跃次数。题目从题中要达到最少次数,肯定是每一步尽可能走远一点。但注意j被限制了范围,这种不用想每一步遍历时肯定选最大的num[i],但要注意,题中是可以到达不是刚好到达,因此最后一步只要大于最后一个数都是可以的。从第一个数开始遍历,每一步贪心去选最远的距离,然后每个数都存下一个可达到的最远距离便于更新,因为贪心每一次都是基于当前数的最优,并不是全局最优
AGP 8.0 适配 - 问题列表
zhuzhumouse
gradle android-studio android
不管是基于编译速度,包体积,新特性等那个方面的考虑,大家都应该开始AGP8.0的适配了,下面使我适配过程中遇到的各种问题,这里列出来,给大家的适配做一个参考。问题一:编译失败@TaskAction解决方案:在根目录的setting.gradle或者build.gradle里面添加如下代码:classpath'com.android.tools.build:gradle:8.0.0'原因说明:AGP
AI编程赋能Python实现零编程决策树算法
智享食事
算法 AI编程 python
1.概念理解决策树算法是一种监督学习算法,用于分类和回归任务。它是一种基于树结构的模型,通过一系列的决策规则来对数据进行分类或预测。决策树的每个节点代表一个特征,每个分支代表该特征的一个属性值,而每个叶节点表示一个类别或一个数值。决策树的构建过程通常分为以下几个步骤:1.特征选择:选择最佳的特征来作为当前节点的划分特征,通常使用信息增益、基尼指数或者信息熵等准则来选择最优的特征。2.建立树结构:根
【Linux】FTP文件服务器
FixPng
运维 服务器 linux 网络
FTP文件服务器一、FTP介绍二、应用场景三、FTP的权限四、FTP的工作模式五、FTP安装部署六、FTP配置文件6.1)相关文件6.2)主配文件详解七、FTP客户端访问7.1)文本界面登陆7.2)FTP客户端常用命令八、基于虚拟用户配置安全的ftp8.1)修改配置文件8.2)生成虚拟用户账号密码文件8.3)配置pam认证,注意先后顺序8.3)重启服务生效8.4)验证登陆一、FTP介绍FTP(Fi
【AI中数学-信号处理】信号的清道夫:精通信号过滤技巧
云博士的AI课堂
AI中的数学 人工智能 信号处理 高频去噪 带通滤波 滤波处理 信号过滤 机器学习
第3节信号的清道夫:精通信号过滤技巧在信号处理中,过滤技术是一项至关重要的工具。通过对信号的处理与过滤,我们能够去除不必要的成分,如噪声、干扰等,从而提高信号质量,增强其后续处理效果。在本节中,我们将介绍三种实际应用中常用的精通信号过滤技巧,包括基于小波变换的信号分离、带通滤波在心电图分析中的应用,以及图像中的高频噪声去除技术。通过这些案例,我们将深入探讨信号过滤在不同领域中的应用。案例1:基于小
Linux线程封装(c++)
laimaxgg
linux c++ java
Linux线程封装(c++)1.前言c++对Linux的pthread.h库进行了封装,使我们能以类和对象的形式创建和管理线程。本篇将模拟c++封装pthread.h库的线程相关函数,使我们也能在外部以类和对象的形式创建和管理线程。2.代码实现2.1成员变量、构造函数#pragmaonce#include#include#includeusingfunc_t=std::function;class
Linux下基于Bluez开发USB蓝牙SPP服务端
zanglengyu
Qt上位机开发 linux c++ bluez SPP socket
由于是在linux上运行的,所以参考的bluez的代码,用C语言实现了蓝牙的Server端。原理也很简单,在服务器端,通过命令添加SPP服务前提是先安装好bluez,一般是安装好的,没安装的话可以用sudoapt-getinstallbluez安装后设置蓝牙关闭蓝牙sudohciconfighci0down重置蓝牙sudohciconfighci0reset打开蓝牙sudohciconfighci
Python基础知识9
ylfhpy
Python基础 python 开发语言 爬虫
1.列表推导式核心概念列表推导式(ListComprehension)是Python中基于现有可迭代对象快速生成新列表的语法结构,具有以下特点:简洁性:用单行代码替代多行循环,极大地简化了代码的编写。例如,要生成一个包含1到10的平方数的列表,使用普通循环需要多行代码,而列表推导式只需一行[x**2forxinrange(1,11)],代码量大幅减少,编程效率显著提高。高效性:执行速度通常快于普通
青稞RISC-V通用系列
ws137517175
risc-v
青稞RISC-V通用系列的特点:高性能与低功耗:青稞系列处理器针对不同应用场景进行了优化,能够在提供高性能的同时保持低功耗,适合电池供电的设备和物联网终端。模块化设计:青稞系列采用模块化设计,用户可以根据需求选择不同的功能模块,如浮点运算单元(FPU)、数字信号处理(DSP)扩展、向量处理单元等。可扩展性:基于RISC-V的开放架构,青稞系列处理器支持用户自定义指令集扩展,能够满足特定应用场景的需
Java中的hashCode和equals方法之间有什么联系
我荔枝呢!
java 开发语言 equals hashCode
定义及作用:equals方法:用于判断两个对象的内容是否相等。默认情况下,它比较的是对象的引用地址,在很多类中会重写该方法以实现基于内容的比较。hashCode方法:返回对象的哈希码值,是一个整数。哈希码主要用于在哈希表等数据结构中快速定位和存储对象,提高数据的存储和查找效率。两者关系:一致性:如果两个对象通过equals方法比较返回true,即两个对象相等,那么它们的hashCode值必须相等。
iOS http封装
374016526
ios 服务器交互 http 网络请求
程序开发避免不了与服务器的交互,这里打包了一个自己写的http交互库。希望可以帮到大家。
内置一个basehttp,当我们创建自己的service可以继承实现。
KuroAppBaseHttp *baseHttp = [[KuroAppBaseHttp alloc] init];
[baseHttp setDelegate:self];
[baseHttp
lolcat :一个在 Linux 终端中输出彩虹特效的命令行工具
brotherlamp
linux linux教程 linux视频 linux自学 linux资料
那些相信 Linux 命令行是单调无聊且没有任何乐趣的人们,你们错了,这里有一些有关 Linux 的文章,它们展示着 Linux 是如何的有趣和“淘气” 。
在本文中,我将讨论一个名为“lolcat”的小工具 – 它可以在终端中生成彩虹般的颜色。
何为 lolcat ?
Lolcat 是一个针对 Linux,BSD 和 OSX 平台的工具,它类似于 cat 命令,并为 cat
MongoDB索引管理(1)——[九]
eksliang
mongodb MongoDB管理索引
转载请出自出处:http://eksliang.iteye.com/blog/2178427 一、概述
数据库的索引与书籍的索引类似,有了索引就不需要翻转整本书。数据库的索引跟这个原理一样,首先在索引中找,在索引中找到条目以后,就可以直接跳转到目标文档的位置,从而使查询速度提高几个数据量级。
不使用索引的查询称
Informatica参数及变量
18289753290
Informatica 参数 变量
下面是本人通俗的理解,如有不对之处,希望指正 info参数的设置:在info中用到的参数都在server的专门的配置文件中(最好以parma)结尾 下面的GLOBAl就是全局的,$开头的是系统级变量,$$开头的变量是自定义变量。如果是在session中或者mapping中用到的变量就是局部变量,那就把global换成对应的session或者mapping名字。
[GLOBAL] $Par
python 解析unicode字符串为utf8编码字符串
酷的飞上天空
unicode
php返回的json字符串如果包含中文,则会被转换成\uxx格式的unicode编码字符串返回。
在浏览器中能正常识别这种编码,但是后台程序却不能识别,直接输出显示的是\uxx的字符,并未进行转码。
转换方式如下
>>> import json
>>> q = '{"text":"\u4
Hibernate的总结
永夜-极光
Hibernate
1.hibernate的作用,简化对数据库的编码,使开发人员不必再与复杂的sql语句打交道
做项目大部分都需要用JAVA来链接数据库,比如你要做一个会员注册的 页面,那么 获取到用户填写的 基本信后,你要把这些基本信息存入数据库对应的表中,不用hibernate还有mybatis之类的框架,都不用的话就得用JDBC,也就是JAVA自己的,用这个东西你要写很多的代码,比如保存注册信
SyntaxError: Non-UTF-8 code starting with '\xc4'
随便小屋
python
刚开始看一下Python语言,传说听强大的,但我感觉还是没Java强吧!
写Hello World的时候就遇到一个问题,在Eclipse中写的,代码如下
'''
Created on 2014年10月27日
@author: Logic
'''
print("Hello World!");
运行结果
SyntaxError: Non-UTF-8
学会敬酒礼仪 不做酒席菜鸟
aijuans
菜鸟
俗话说,酒是越喝越厚,但在酒桌上也有很多学问讲究,以下总结了一些酒桌上的你不得不注意的小细节。
细节一:领导相互喝完才轮到自己敬酒。敬酒一定要站起来,双手举杯。
细节二:可以多人敬一人,决不可一人敬多人,除非你是领导。
细节三:自己敬别人,如果不碰杯,自己喝多少可视乎情况而定,比如对方酒量,对方喝酒态度,切不可比对方喝得少,要知道是自己敬人。
细节四:自己敬别人,如果碰杯,一
《创新者的基因》读书笔记
aoyouzi
读书笔记 《创新者的基因》
创新者的基因
创新者的“基因”,即最具创意的企业家具备的五种“发现技能”:联想,观察,实验,发问,建立人脉。
第一部分破坏性创新,从你开始
第一章破坏性创新者的基因
如何获得启示:
发现以下的因素起到了催化剂的作用:(1) -个挑战现状的问题;(2)对某项技术、某个公司或顾客的观察;(3) -次尝试新鲜事物的经验或实验;(4)与某人进行了一次交谈,为他点醒
表单验证技术
百合不是茶
JavaScript DOM对象 String对象 事件
js最主要的功能就是验证表单,下面是我对表单验证的一些理解,贴出来与大家交流交流 ,数显我们要知道表单验证需要的技术点, String对象,事件,函数
一:String对象;通常是对字符串的操作;
1,String的属性;
字符串.length;表示该字符串的长度;
var str= "java"
web.xml配置详解之context-param
bijian1013
java servlet web.xml context-param
一.格式定义:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>contextConfigLocationValue></param-value>
</context-param>
作用:该元
Web系统常见编码漏洞(开发工程师知晓)
Bill_chen
sql PHP Web fckeditor 脚本
1.头号大敌:SQL Injection
原因:程序中对用户输入检查不严格,用户可以提交一段数据库查询代码,根据程序返回的结果,
获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。
本质:
对于输入检查不充分,导致SQL语句将用户提交的非法数据当作语句的一部分来执行。
示例:
String query = "SELECT id FROM users
【MongoDB学习笔记六】MongoDB修改器
bit1129
mongodb
本文首先介绍下MongoDB的基本的增删改查操作,然后,详细介绍MongoDB提供的修改器,以完成各种各样的文档更新操作 MongoDB的主要操作
show dbs 显示当前用户能看到哪些数据库
use foobar 将数据库切换到foobar
show collections 显示当前数据库有哪些集合
db.people.update,update不带参数,可
提高职业素养,做好人生规划
白糖_
人生
培训讲师是成都著名的企业培训讲师,他在讲课中提出的一些观点很新颖,在此我收录了一些分享一下。注:讲师的观点不代表本人的观点,这些东西大家自己揣摩。
1、什么是职业规划:职业规划并不完全代表你到什么阶段要当什么官要拿多少钱,这些都只是梦想。职业规划是清楚的认识自己现在缺什么,这个阶段该学习什么,下个阶段缺什么,又应该怎么去规划学习,这样才算是规划。
国外的网站你都到哪边看?
bozch
技术 网站 国外
学习软件开发技术,如果没有什么英文基础,最好还是看国内的一些技术网站,例如:开源OSchina,csdn,iteye,51cto等等。
个人感觉如果英语基础能力不错的话,可以浏览国外的网站来进行软件技术基础的学习,例如java开发中常用的到的网站有apache.org 里面有apache的很多Projects,springframework.org是spring相关的项目网站,还有几个感觉不错的
编程之美-光影切割问题
bylijinnan
编程之美
package a;
public class DisorderCount {
/**《编程之美》“光影切割问题”
* 主要是两个问题:
* 1.数学公式(设定没有三条以上的直线交于同一点):
* 两条直线最多一个交点,将平面分成了4个区域;
* 三条直线最多三个交点,将平面分成了7个区域;
* 可以推出:N条直线 M个交点,区域数为N+M+1。
关于Web跨站执行脚本概念
chenbowen00
Web 安全 跨站执行脚本
跨站脚本攻击(XSS)是web应用程序中最危险和最常见的安全漏洞之一。安全研究人员发现这个漏洞在最受欢迎的网站,包括谷歌、Facebook、亚马逊、PayPal,和许多其他网站。如果你看看bug赏金计划,大多数报告的问题属于 XSS。为了防止跨站脚本攻击,浏览器也有自己的过滤器,但安全研究人员总是想方设法绕过这些过滤器。这个漏洞是通常用于执行cookie窃取、恶意软件传播,会话劫持,恶意重定向。在
[开源项目与投资]投资开源项目之前需要统计该项目已有的用户数
comsci
开源项目
现在国内和国外,特别是美国那边,突然出现很多开源项目,但是这些项目的用户有多少,有多少忠诚的粉丝,对于投资者来讲,完全是一个未知数,那么要投资开源项目,我们投资者必须准确无误的知道该项目的全部情况,包括项目发起人的情况,项目的维持时间..项目的技术水平,项目的参与者的势力,项目投入产出的效益.....
oracle alert log file(告警日志文件)
daizj
oracle 告警日志文件 alert log file
The alert log is a chronological log of messages and errors, and includes the following items:
All internal errors (ORA-00600), block corruption errors (ORA-01578), and deadlock errors (ORA-00060)
关于 CAS SSO 文章声明
denger
SSO
由于几年前写了几篇 CAS 系列的文章,之后陆续有人参照文章去实现,可都遇到了各种问题,同时经常或多或少的收到不少人的求助。现在这时特此说明几点:
1. 那些文章发表于好几年前了,CAS 已经更新几个很多版本了,由于近年已经没有做该领域方面的事情,所有文章也没有持续更新。
2. 文章只是提供思路,尽管 CAS 版本已经发生变化,但原理和流程仍然一致。最重要的是明白原理,然后
初二上学期难记单词
dcj3sjt126com
english word
lesson 课
traffic 交通
matter 要紧;事物
happy 快乐的,幸福的
second 第二的
idea 主意;想法;意见
mean 意味着
important 重要的,重大的
never 从来,决不
afraid 害怕 的
fifth 第五的
hometown 故乡,家乡
discuss 讨论;议论
east 东方的
agree 同意;赞成
bo
uicollectionview 纯代码布局, 添加头部视图
dcj3sjt126com
Collection
#import <UIKit/UIKit.h>
@interface myHeadView : UICollectionReusableView
{
UILabel *TitleLable;
}
-(void)setTextTitle;
@end
#import "myHeadView.h"
@implementation m
N 位随机数字串的 JAVA 生成实现
FX夜归人
java Math 随机数 Random
/**
* 功能描述 随机数工具类<br />
* @author FengXueYeGuiRen
* 创建时间 2014-7-25<br />
*/
public class RandomUtil {
// 随机数生成器
private static java.util.Random random = new java.util.R
Ehcache(09)——缓存Web页面
234390216
ehcache 页面缓存
页面缓存
目录
1 SimplePageCachingFilter
1.1 calculateKey
1.2 可配置的初始化参数
1.2.1 cach
spring中少用的注解@primary解析
jackyrong
primary
这次看下spring中少见的注解@primary注解,例子
@Component
public class MetalSinger implements Singer{
@Override
public String sing(String lyrics) {
return "I am singing with DIO voice
Java几款性能分析工具的对比
lbwahoo
java
Java几款性能分析工具的对比
摘自:http://my.oschina.net/liux/blog/51800
在给客户的应用程序维护的过程中,我注意到在高负载下的一些性能问题。理论上,增加对应用程序的负载会使性能等比率的下降。然而,我认为性能下降的比率远远高于负载的增加。我也发现,性能可以通过改变应用程序的逻辑来提升,甚至达到极限。为了更详细的了解这一点,我们需要做一些性能
JVM参数配置大全
nickys
jvm 应用服务器
JVM参数配置大全
/usr/local/jdk/bin/java -Dresin.home=/usr/local/resin -server -Xms1800M -Xmx1800M -Xmn300M -Xss512K -XX:PermSize=300M -XX:MaxPermSize=300M -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=5 -
搭建 CentOS 6 服务器(14) - squid、Varnish
rensanning
varnish
(一)squid
安装
# yum install httpd-tools -y
# htpasswd -c -b /etc/squid/passwords squiduser 123456
# yum install squid -y
设置
# cp /etc/squid/squid.conf /etc/squid/squid.conf.bak
# vi /etc/
Spring缓存注解@Cache使用
tom_seed
spring
参考资料
http://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/
http://swiftlet.net/archives/774
缓存注解有以下三个:
@Cacheable @CacheEvict @CachePut
dom4j解析XML时出现"java.lang.noclassdeffounderror: org/jaxen/jaxenexception"错误
xp9802
java.lang.NoClassDefFoundError: org/jaxen/JaxenExc
关键字: java.lang.noclassdeffounderror: org/jaxen/jaxenexception
使用dom4j解析XML时,要快速获取某个节点的数据,使用XPath是个不错的方法,dom4j的快速手册里也建议使用这种方式
执行时却抛出以下异常:
Exceptio