Android 中 Handler (创建时)内存泄漏问题及解决方案
一、Handler 内存泄漏核心原理
真题 1:分析 Handler 内存泄漏场景
题目描述:
在 Activity 中使用非静态内部类 Handler 发送延迟消息,旋转屏幕后 Activity 无法释放,分析原因并给出解决方案。
内存泄漏链路分析:
- 引用链关系:Message -> Handler -> Activity
- 关键节点:
- MessageQueue 持有 Message 的强引用
- Message 持有 Handler 的强引用
- 非静态 Handler 隐式持有 Activity 的强引用
- 生命周期冲突:
- Activity 销毁时,若 Message 尚未处理完毕
- 整个引用链会阻止 Activity 被 GC 回收
解决方案:
public class MainActivity extends AppCompatActivity {// 使用静态内部类 + WeakReferenceprivate static class SafeHandler extends Handler {// 持有对Activity的弱引用,防止内存泄漏private final WeakReference<MainActivity> activityRef;public SafeHandler(MainActivity activity) {// 初始化弱引用this.activityRef = new WeakReference<>(activity);}@Overridepublic void handleMessage(Message msg) {// 获取Activity实例MainActivity activity = activityRef.get();if (activity != null) {// 安全操作Activity引用// 在这里添加具体的消息处理逻辑}}}private final SafeHandler mHandler = new SafeHandler(this);@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 发送延迟消息,延迟60秒mHandler.sendMessageDelayed(Message.obtain(), 60 * 1000);}@Overrideprotected void onDestroy() {super.onDestroy();// 双重保障:移除所有消息和RunnablemHandler.removeCallbacksAndMessages(null);}
}
“这是由 Java 引用机制和 Android 生命周期特性共同导致的。
- 引用链关系:MessageQueue 持有 Message,Message 持有 Handler,非静态内部类 Handler 会隐式持有外部 Activity 的强引用,形成 MessageQueue → Message → Handler → Activity 的引用链。
- 生命周期冲突:当 Activity 销毁(如旋转屏幕)时,若 Handler 还有未处理的延迟消息(如
sendMessageDelayed
),这些消息会通过引用链阻止 Activity 被 GC 回收,导致内存泄漏。 - 源码层面:
Message
类的target
字段指向发送消息的 Handler(msg.target = this
),而 Handler 的非静态特性使其依赖 Activity 实例,最终造成泄漏。”
面试官追问:
- 问:为什么静态内部类不会持有外部类引用?
- 答:静态内部类不依赖外部类实例,在编译时,它不会自动生成对外部类的引用字段(如
this$0
)。普通的非静态内部类会隐式持有外部类的引用,这是因为非静态内部类的实例与外部类的实例相关联,而静态内部类的实例独立于外部类的实例。所以静态内部类不会阻止外部类被回收,从而避免了因内部类持有外部类引用导致的内存泄漏问题。
二、进阶解决方案实战
真题 2:复杂场景下的 Handler 优化
题目描述:
在短视频播放 Activity 中,需要使用 Handler 定时更新进度条(100ms 间隔),同时处理网络回调。如何设计 Handler 避免内存泄漏?
分层解决方案:
- 静态内部类 + 弱引用:
private static class ProgressHandler extends Handler {// 持有对VideoActivity的弱引用,防止内存泄漏private final WeakReference<VideoActivity> activityRef;public ProgressHandler(VideoActivity activity) {// 初始化弱引用this.activityRef = new WeakReference<>(activity);}@Overridepublic void handleMessage(Message msg) {// 获取Activity实例VideoActivity activity = activityRef.get();// 检查Activity是否为空或正在销毁if (activity == null || activity.isFinishing()) return;switch (msg.what) {case MSG_UPDATE_PROGRESS:// 调用Activity的更新进度条方法activity.updateProgress();break;case MSG_PLAY_COMPLETED:// 调用Activity的播放完成方法activity.playCompleted();break;}}
}
- 生命周期管理:
@Override
protected void onResume() {super.onResume();// 启动周期性任务,每100ms发送一次消息mHandler.sendEmptyMessageDelayed(MSG_UPDATE_PROGRESS, 100);
}@Override
protected void onPause() {super.onPause();// 暂停时移除周期性任务mHandler.removeMessages(MSG_UPDATE_PROGRESS);
}@Override
protected void onDestroy() {super.onDestroy();// 销毁时移除所有任务mHandler.removeCallbacksAndMessages(null);
}
回答话术:
“可以从三个层面解决:
- 基础方案:使用 静态内部类 + WeakReference。静态内部类不依赖外部实例,不会自动持有 Activity 引用;通过
WeakReference
弱引用 Activity,即使 Activity 被回收,也不会影响 Handler 正常工作。例如:
private static class SafeHandler extends Handler {private final WeakReference<MainActivity> activityRef;public SafeHandler(MainActivity activity) {activityRef = new WeakReference<>(activity);}@Overridepublic void handleMessage(Message msg) {MainActivity activity = activityRef.get();if (activity != null) {// 处理消息}}
}
- 进阶优化:在 Activity 生命周期中 主动管理消息队列。例如,在
onDestroy
中调用mHandler.removeCallbacksAndMessages(null)
,清除所有未处理的消息和任务,避免残留引用。 - 替代方案:使用 LiveData 或 Kotlin 协程。它们自动绑定组件生命周期,无需手动管理线程和消息,从根本上规避泄漏风险。例如,LiveData 的
observe
方法会在 Activity 销毁时自动解除订阅,安全性更高。”
性能优化点:
- 使用
Message.obtain()
复用 Message 对象,减少内存分配。因为Message.obtain()
可以从消息池中获取已存在的Message
对象,避免频繁创建新的Message
对象,从而减少内存开销。 - 周期性任务采用
sendEmptyMessageDelayed
而非postDelayed
,避免匿名 Runnable 引用。sendEmptyMessageDelayed
发送的是空消息,不会创建匿名内部类的Runnable
,防止因匿名内部类持有外部类引用导致的内存泄漏风险。
真题 3: HandlerThread vs IntentService
题目描述:
在图片下载场景中,需要后台线程处理 IO 操作并通过 Handler 回主线程更新 UI,选择 HandlerThread 还是 IntentService?说明理由。
对比分析:
特性 | HandlerThread | IntentService |
---|---|---|
生命周期管理 | 需要手动调用 quit () | 自动管理,任务完成后自动停止 |
任务队列 | 单线程顺序执行 | 单线程顺序执行 |
线程安全 | 需要手动处理线程切换 | 自动在后台线程执行 |
适用场景 | 轻量级异步任务 + UI 回调 | 独立于 Activity 的后台任务 |
最佳实践:
// HandlerThread方案
private HandlerThread mHandlerThread;
private Handler mWorkerHandler;
private Handler mMainHandler;@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 初始化HandlerThread,命名为"ImageLoader"mHandlerThread = new HandlerThread("ImageLoader");// 启动HandlerThreadmHandlerThread.start();// 创建工作线程的Handler,关联到HandlerThread的LoopermWorkerHandler = new Handler(mHandlerThread.getLooper());// 创建主线程的Handler,关联到主线程的LoopermMainHandler = new Handler(Looper.getMainLooper());// 在工作线程执行下载任务mWorkerHandler.post(() -> {// 调用下载图片的方法,获取BitmapBitmap bitmap = downloadImage(url);// 切换到主线程更新UImMainHandler.post(() -> imageView.setImageBitmap(bitmap));});
}@Override
protected void onDestroy() {super.onDestroy();// 安全停止HandlerThreadmHandlerThread.quitSafely();
}
回答话术:
“两者的选择取决于具体场景:
- HandlerThread:适用于 轻量级异步任务 + UI 回调,例如短视频 APP 中定时更新进度条。它需要手动管理生命周期(
start()
和quitSafely()
),线程切换需开发者处理。例如,在 HandlerThread 的 Looper 上创建 Handler,可在后台执行下载任务,再通过主线程 Handler 更新 UI:
mHandlerThread = new HandlerThread("ImageLoader");
mHandlerThread.start();
mWorkerHandler = new Handler(mHandlerThread.getLooper());
mWorkerHandler.post(() -> {Bitmap bitmap = downloadImage(url);mMainHandler.post(() -> imageView.setImageBitmap(bitmap));
});
- IntentService:适合 独立于 Activity 的后台任务,如文件下载、数据备份。它自动管理生命周期(任务完成后自动停止),所有任务在后台线程顺序执行,无需担心线程安全问题。例如,在 Service 中重写
onHandleIntent
处理下载逻辑,系统会在任务结束后自动销毁 Service。
总结:若任务需与 UI 强关联,选 HandlerThread;若任务需长期可靠运行且无需 UI 交互,选 IntentService。”
三、内存泄漏检测与排查
真题 4: 如何定位 Handler 内存泄漏
题目描述:
APP 频繁出现内存泄漏,怀疑与 Handler 有关,如何快速定位问题?
排查工具链:
- LeakCanary:
- 检测 Activity/Fragment 泄漏
- 生成引用链分析报告
- Profiler 内存分析:
- 查看堆转储文件
- 分析实例数量和引用关系
- StrictMode:
public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();if (BuildConfig.DEBUG) {// 设置StrictMode的VmPolicyStrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedClosableObjects() // 检测未关闭的可关闭对象.detectLeakedRegistrationObjects() // 检测泄漏的注册对象.detectLeakedSqlLiteObjects() // 检测泄漏的SQLite对象.penaltyLog() // 记录违规日志.penaltyDeath() // 终止进程.build());}}
}
排查步骤:
- 触发泄漏场景(如旋转屏幕、快速切换 Activity),模拟可能导致内存泄漏的操作。
- 使用 LeakCanary 捕获泄漏,LeakCanary 会监测应用的内存情况,当检测到 Activity 或 Fragment 泄漏时,会生成详细的引用链分析报告,帮助开发者定位泄漏源。
- 在 Profiler 中分析堆转储:
- 搜索 Handler 实例,通过 Profiler 的内存分析功能,查找 Handler 实例的引用关系。
- 查看其引用的 Activity 是否已销毁,判断 Handler 是否持有已销毁的 Activity 的引用。
- 追踪 MessageQueue 中待处理的消息,检查是否有未处理的消息导致 Handler 无法被回收。
回答话术:
“可通过以下流程定位:
- 工具选择:
- LeakCanary:自动检测 Activity/Fragment 泄漏,生成引用链报告,快速定位泄漏源头。
- Profiler 内存分析:抓取堆转储文件,搜索 Handler 实例,分析其引用关系,查看是否持有已销毁的 Activity。
- StrictMode:在 Debug 模式下开启,检测未关闭的资源(如
detectLeakedClosableObjects
),通过日志定位潜在泄漏点。
- 排查步骤:
- 触发疑似泄漏场景(如旋转屏幕、快速切换页面);
- 使用 LeakCanary 捕获泄漏,查看引用链中是否存在 Handler → Activity 的路径;
- 在 Profiler 中分析 Handler 实例的生命周期,检查 MessageQueue 是否存在大量未处理消息。”
四、高级解决方案
真题 5:LiveData 替代 Handler
题目描述:
如何使用 LiveData 完全替代 Handler,避免内存泄漏?
实现方案:
public class MyViewModel extends ViewModel {// 创建MutableLiveData对象,用于存储数据private final MutableLiveData<String> mData = new MutableLiveData<>();// 提供获取LiveData的方法public LiveData<String> getData() {return mData;}// 定义获取数据的方法public void fetchData() {// 在后台线程获取数据Executors.newSingleThreadExecutor().execute(() -> {// 调用加载数据的方法,获取结果String result = loadDataFromNetwork();// 在主线程更新LiveDatamData.postValue(result);});}
}public class MyActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 使用ViewModelProvider获取MyViewModel实例MyViewModel viewModel = ViewModelProvider(this).get(MyViewModel.class);// 观察LiveData的变化,自动在主线程更新UIviewModel.getData().observe(this, data -> {// 设置TextView的文本为获取到的数据textView.setText(data);});// 调用ViewModel的fetchData方法获取数据viewModel.fetchData();}
}
优势分析:
- 自动生命周期管理:
- Observer 绑定 Activity/Fragment 生命周期,当 Activity 或 Fragment 销毁时,Observer 会自动解除订阅,避免内存泄漏。
- 宿主销毁时自动解除订阅,LiveData 会感知宿主的生命周期状态,在宿主销毁时自动清理相关资源。
- 避免内存泄漏:
- 无需手动管理消息队列,LiveData 内部管理数据的变化和分发,不需要开发者手动处理消息队列,减少了因消息队列管理不当导致的内存泄漏风险。
- 无 Handler 引用链问题,LiveData 没有像 Handler 那样的引用链,不会出现因 Handler 持有 Activity 引用导致的内存泄漏问题。
- 线程安全:
- postValue () 自动切换到主线程,LiveData 的 postValue () 方法会自动将数据更新操作切换到主线程,保证数据更新在主线程进行,避免线程切换带来的问题。
- 无需担心线程切换问题,使用 LiveData 时,开发者无需手动处理线程切换逻辑,减少了因线程切换不当导致的内存泄漏和其他线程安全问题。
回答话术:
“我会采用以下方案:
- 静态内部类 + 弱引用:定义
ProgressHandler
,使用WeakReference
持有 Activity,确保 Activity 可被回收。 - 生命周期管理:在
onResume
启动周期性任务(sendEmptyMessageDelayed
),onPause
暂停任务,onDestroy
移除所有消息,避免残留任务。 - 性能优化:使用
Message.obtain()
复用消息对象,减少内存分配;避免使用postDelayed
的匿名 Runnable,改用静态Runnable
类。
示例代码:
private static class ProgressHandler extends Handler {private final WeakReference<VideoActivity> activityRef;public ProgressHandler(VideoActivity activity) {activityRef = new WeakReference<>(activity);}@Overridepublic void handleMessage(Message msg) {VideoActivity activity = activityRef.get();if (activity != null) {activity.updateProgress();}}
}
这样既能保证进度条实时更新,又能避免内存泄漏风险。”
五、常见误区与最佳实践
真题 6:Handler 使用陷阱
题目描述:
以下代码是否存在内存泄漏风险?说明理由。
public class MyActivity extends AppCompatActivity {// 创建Handler实例,关联到主线程的Looperprivate Handler mHandler = new Handler(Looper.getMainLooper()) {@Overridepublic void handleMessage(Message msg) {// 更新UI的逻辑}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 延迟10秒执行任务mHandler.postDelayed(() -> {// 延迟执行任务的逻辑}, 10000);}
}
风险分析:
- 匿名内部类持有 Activity 引用:
- 匿名 Runnable 隐式引用外部 Activity,
postDelayed
方法中的匿名 Runnable 会隐式持有外部 Activity 的引用。 - 若 Activity 销毁时任务未执行,会导致泄漏,当 Activity 销毁时,如果这个延迟任务还未执行,匿名 Runnable 持有 Activity 的引用会阻止 Activity 被回收,从而导致内存泄漏。
- 匿名 Runnable 隐式引用外部 Activity,
正确写法:
private static class SafeRunnable implements Runnable {// 持有对MyActivity的弱引用,防止内存泄漏private final WeakReference<MyActivity> activityRef;public SafeRunnable(MyActivity activity) {// 初始化弱引用this.activityRef = new WeakReference<>(activity);}@Overridepublic void run() {// 获取Activity实例MyActivity activity = activityRef.get();if (activity != null) {// 安全操作// 在这里添加具体的任务逻辑}}
}// 使用静态Runnable
mHandler.postDelayed(new SafeRunnable(this), 10000);
相关文章:
Android 中 Handler (创建时)内存泄漏问题及解决方案
一、Handler 内存泄漏核心原理 真题 1:分析 Handler 内存泄漏场景 题目描述: 在 Activity 中使用非静态内部类 Handler 发送延迟消息,旋转屏幕后 Activity 无法释放,分析原因并给出解决方案。 内存泄漏链路分析: 引…...
linux-驱动开发之设备树详解(RK平台为例)
前言 Linux3.x以后的版本才引入了设备树,设备树用于描述一个硬件平台的板级细节。 在早些的linux内核,这些“硬件平台的板级细节”保存在linux内核目录“/arch”, 以ARM为例“硬件平台的板级细节”保存在“/arch/arm/plat-xxx”和“/arch/ar…...
【现代深度学习技术】注意力机制05:多头注意力
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重…...
RDD的五大特征
1. 由多个分区(Partitions)组成 特性:RDD 是分区的集合,每个分区在集群的不同节点上存储。分区是数据并行处理的基本单位。作用:分区使 RDD 能够在集群中并行计算,提高处理效率。 2. 有一个计算每个分区的…...
键盘RGB矩阵与LED指示灯(理论部分)
键盘RGB矩阵与LED指示灯(理论部分) 一、LED指示灯基础 在键盘世界里,LED指示灯不仅仅是装饰,它们还能提供丰富的状态信息。QMK固件提供了读取HID规范中定义的5种LED状态的方法: Num Lock(数字锁定)Caps Lock(大写锁定)Scroll Lock(滚动锁定)Compose(组合键)Desp…...
HTTP方法和状态码(Status Code)
HTTP方法 HTTP方法(也称HTTP动词)主要用于定义对资源的操作类型。根据HTTP/1.1规范(RFC 7231)以及后续扩展,常用的HTTP方法有以下几种: GET:请求获取指定资源的表示形式。POST:向指…...
【sqlmap需要掌握的参数】
sqlmap需要掌握的参数 目标-u 指定URL 用于get请求-l 用于post请求- r 用于post请求指定数据库/表/字段 -D/-T/-C 脱库获得数据库获取用户获取表获取列获取字段获取字段类型获取值 其他 目标 -u 指定URL 用于get请求 -u URL, --urlURL 目标URL 只使用于get命令中 -l 用于pos…...
用 AltSnap 解锁 Windows 窗口管理的“魔法”
你有没有遇到过这样的场景:电脑屏幕上堆满了窗口,想快速调整它们的大小和位置,却只能拖来拖去,费时又费力?或者你是个多任务狂魔,喜欢一边写代码、一边看文档、一边刷视频,却发现 Windows 自带的…...
高并发内存池(三):TLS无锁访问以及Central Cache结构设计
目录 前言: 一,thread cache线程局部存储的实现 问题引入 概念说明 基本使用 thread cache TLS的实现 二,Central Cache整体的结构框架 大致结构 span结构 span结构的实现 三,Central Cache大致结构的实现 单例模式 thr…...
数据治理域——数据治理体系建设
摘要 本文主要介绍了数据治理系统的建设。数据治理对企业至关重要,其动因包括应对数据爆炸增长、提升内部管理效率、支撑复杂业务需求、加强风险防控与合规管理以及实现数字化转型战略。其核心目的是提升数据质量、统一数据标准、优化数据资产管理、支撑业务发展和…...
数据库实验报告 SQL SERVER 2008的基本操作 1
实验报告(第 1 次) 实验名称 SQL SERVER 2008的基本操作 实验时间 9月14日1-2节 一、实验内容 数据库的基本操作:包括创建、修改、附加、分离和删除数据库等。 二、源程序及主要算法说明 本次实验不涉及程序和算法。 三、测…...
基于STM32、HAL库的ICP-20100气压传感器 驱动程序设计
一、简介: ICP-20100 是 InvenSense(TDK 集团旗下公司)生产的一款高精度数字气压传感器,专为需要精确测量气压和海拔高度的应用场景设计。它具有低功耗、高精度、快速响应等特点,非常适合物联网、可穿戴设备和无人机等应用。 二、硬件接口: ICP-20100 引脚STM32L4XX 引脚…...
提示工程实战指南:Google白皮书关键内容一文讲清
You don’t need to be a data scientist or a machine learning engineer – everyone can writea prompt. 一、概述 Google于2025年2月发布的《Prompt Engineering》白皮书系统阐述了提示工程的核心技术、实践方法及挑战应对策略。该文档由Lee Boonstra主编,多位…...
国产大模型「五强争霸」:决战AGI,谁主沉浮?
引言 中国AI大模型市场正经历一场史无前例的洗牌!曾经“百模混战”的局面已落幕,字节、阿里、阶跃星辰、智谱和DeepSeek五大巨头强势崛起,形成“基模五强”新格局。这场竞争不仅是技术实力的较量,更是资源、人才与生态的全面博弈。…...
Linux进程10-有名管道概述、创建、读写操作、两个管道进程间通信、读写规律(只读、只写、读写区别)、设置阻塞/非阻塞
目录 1.有名管道 1.1概述 1.2与无名管道的差异 2.有名管道的创建 2.1 直接用shell命令创建有名管道 2.2使用mkfifo函数创建有名管道 3.有名管道读写操作 3.1单次读写 3.2多次读写 4.有名管道进程间通信 4.1回合制通信 4.2父子进程通信 5.有名管道读写规律ÿ…...
高吞吐与低延迟的博弈:Kafka与RabbitMQ数据管道实战指南
摘要 本文全面对比Apache Kafka与RabbitMQ在数据管道中的设计哲学、核心差异及协同方案。结合性能指标、应用场景和企业级实战案例,揭示Kafka在高吞吐流式处理中的优势与RabbitMQ在复杂路由和低延迟传输方面的独特特点;介绍了使用Java生态成熟第三方库&…...
C++23 views::slide (P2442R1) 深入解析
文章目录 引言C20 Ranges库回顾什么是Rangesstd::views的作用 views::slide 概述基本概念原型定义辅助概念工作原理代码示例输出结果 views::slide 的应用场景计算移动平均值查找连续的子序列 总结 引言 在C的发展历程中,每一个新版本都会带来一系列令人期待的新特…...
SpringDataRedis的入门案例,以及RedisTemplate序列化实现
目录 SpringDataRedis 简单介绍 入门案例 RedisTemplate序列化方案 方案一: 方案二: SpringDataRedis 简单介绍 提供了对不同Redis客户端的整合(Lettuce和Jedis) 提供了RedisTemplate统一API来操作Redis 支持Redis的发布订阅模型 支持Redis哨兵和Redis集群 支持基于…...
鸿蒙HarmonyOS list优化一: list 结合 lazyforeach用法
list列表是开发中不可获取的,非常常用的组件,使用过程中会需要不断的优化,接下来我会用几篇文章进行list在纯原生的纯血鸿蒙的不断优化。我想进大厂,希望某位大厂的看到后能给次机会。 首先了解一下lazyforeach: Laz…...
【Jenkins简单自动化部署案例:基于Docker和Harbor的自动化部署流程记录】
摘要 本文记录了作者使用Jenkins时搭建的一个简单自动化部署案例,涵盖Jenkins的Docker化安装、Harbor私有仓库配置、Ansible远程部署等核心步骤。通过一个SpringBoot项目 (RuoYi) 的完整流程演示,从代码提交到镜像构建、推送、滚动更新,逐步实…...
【愚公系列】《Manus极简入门》034-跨文化交流顾问:“文化桥梁使者”
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! …...
数字滤波器应用介绍
此示例说明如何设计、分析数字过滤器并将其应用于数据。它将帮助您回答以下问题: 如何补偿滤波器引入的延迟?如何避免使信号失真?如何从信号中删除不需要的内容?如何微分信号?以及积分信号文章目录 补偿筛选引入的延迟补偿恒定滤波器延迟 如FIR引起的消除方法,末尾添零补…...
木马查杀篇—Opcode提取
【前言】 介绍Opcode的提取方法,并探讨多种机器学习算法在Webshell检测中的应用,理解如何在实际项目中应用Opcode进行高效的Webshell检测。 Ⅰ 基本概念 Opcode:计算机指令的一部分,也叫字节码,一个php文件可以抽取出…...
栈和队列复习(C语言版)
目录 一.栈的概念 二.栈的实现 三.队列的概念 四.队列的实现 五.循环队列的实现 一.栈的概念 可以将栈抽象地理解成羽毛球桶,或者理解成坐直升电梯;最后一个进去的,出来时第一个出来,并且只有一个出入口。这边需要注意的是&am…...
SDK does not contain ‘libarclite‘ at the path
Xcode16以上版本更新SDK之后就报错了。是因为缺少libarclite_iphoneos.a文件。所以需要在网上找一下该文件根据路径添加进去,arc文件可能需要新建一下。 clang: error: SDK does not contain ‘libarclite’ at the path ‘/Applications/Xcode.app/Contents/Develo…...
Kotlin跨平台Compose Multiplatform实战指南
Kotlin Multiplatform(KMP)结合 Compose Multiplatform 正在成为跨平台开发的热门选择,它允许开发者用一套代码构建 Android、iOS、桌面(Windows/macOS/Linux)和 Web 应用。以下是一个实战指南,涵盖核心概念…...
Oracle数据库全局性HANG的处理过程
如果Oracle数据库全局性HANG,首先要做的就是收集数据库HANG时的状态,只有收集到了相应状态,抓住故障现场,才可以进一步分析故障产生的可能原因。 出现此故障,一般情况下可以如此处理: 如果数据库是单节点&a…...
MySQL 8.0 OCP(1Z0-908)英文题库(21-30)
目录 第21题题目分析正确答案 第22题题目分析正确答案 第23题题目分析正确答案 第24题题目分析正确答案 第25题题目分析正确答案 第26题题目分析正确答案 第27题题目分析正确答案 第28题题目分析正确答案 第29题题目分析正确答案 第30题题目解析正确答案 第21题 Choose three.…...
beyond compare 免密钥进入使用(删除注册表)
beyond compare 免密钥进入,免费使用(删除注册表) 温馨提醒:建议仅个人使用,公司使用小心律师函警告! 1.winr 输入regedit 打开注册表 2.删除计算机 \HKEY_CURRENT_USER\Software\Scooter Software\Beyo…...
前端项目2-01:个人简介页面
目录 一.代码显示 二.效果图 三.代码分析 1. 文档声明和 HTML 基本结构 2. CSS 样式部分 全局样式 body 样式 页面主要容器 box 样式 左侧区域 l 样式 右侧区域 r 样式 左侧区域中头像容器 to 样式 头像图片样式及悬停效果 左侧区域中个人信息容器 tit 样式 个人…...
.NET 8 API 实现websocket,并在前端angular实现调用
.NET 8 API 实现websocket,并在前端angular实现调用。 后端:.NET 8 WebSocket API 实现 在 .NET 8 中,可以通过 Microsoft.AspNetCore.WebSockets 提供的支持来实现 WebSocket 功能。以下是创建一个简单的 WebSocket 控制器的步骤。 安装必…...
P2P架构
P2P 是 Peer-to-Peer(点对点) 的缩写,是一种 去中心化 的网络架构,其中每个节点(称为 “对等节点”,Peer)既是 “客户端”,也是 “服务器”,可以直接与其他节点通信、共享…...
菊厂0510面试手撕题目解答
题目 输入一个整数数组,返回该数组中最小差出现的次数。 示例1:输入:[1,3,7,5,9,12],输出:4,最小差为2,共出现4次; 示例2:输入:[90,98,90,90,1,1]…...
【25软考网工】第六章(4)VPN虚拟专用网 L2TP、PPTP、PPP认证方式;IPSec、GRE
博客主页:christine-rr-CSDN博客 专栏主页:软考中级网络工程师笔记 大家好,我是christine-rr !目前《软考中级网络工程师》专栏已经更新二十多篇文章了,每篇笔记都包含详细的知识点,希望能帮助到你!…...
C语言:深入理解指针(3)
目录 一、数组名的理解 二、用指针访问数组 三、一维数组传参的本质 四、冒泡排序 五、二级指针 六、指针数组 七、指针数组模拟二维数组 八、结语 一、数组名的理解 数组名其实就是首元素的地址 int arr[3] {1,2,3}; printf("arr :%p\n" ,arr); printf(…...
R语言实战第5章(1)
第一部分:数学、统计和字符处理函数 数学和统计函数:R提供了丰富的数学和统计函数,用于执行各种计算和分析。这些函数可以帮助用户快速完成复杂的数学运算、统计分析等任务,例如计算均值、方差、相关系数、进行假设检验等。字符处…...
Lodash isEqual 方法源码实现分析
Lodash isEqual 方法源码实现分析 Lodash 的 isEqual 方法用于执行两个值的深度比较,以确定它们是否相等。这个方法能够处理各种 JavaScript 数据类型,包括基本类型、对象、数组、正则表达式、日期对象等,并且能够正确处理循环引用。 1. is…...
探索边缘计算:赋能物联网的未来
摘要 随着物联网(IoT)技术的飞速发展,越来越多的设备接入网络,产生了海量的数据。传统的云计算模式在处理这些数据时面临着延迟高、带宽不足等问题,而边缘计算的出现为解决这些问题提供了新的思路。本文将深入探讨边缘…...
Ubuntu中配置【Rust 镜像源】
本篇主要记录Ubuntu中配置Rust编程环境时,所需要做的镜像源相关的配置 无法下载 Rust 工具链 通过环境变量指定 Rust 的国内镜像源(如中科大或清华源)。 方法一:临时设置镜像 export RUSTUP_DIST_SERVERhttps://mirrors.ustc.e…...
netty 客户端发送消息服务端收到消息无法打印,springBoot配合 lombok使用@Slf4j
netty 客户端发送消息服务端收到消息无法打印,springBoot配合 lombok使用Slf4j 服务端代码 Slf4j public class EventLoopServer {public static void main(String[] args) throws InterruptedException {new ServerBootstrap().group(new NioEventLoopGroup()).c…...
学习笔记:黑马程序员JavaWeb开发教程(2025.4.3)
12.1 基础登录功能 EmpService中的login方法,是根据接收到的用户名和密码,查询时emp数据库中的员工信息,会返回一个员工对象。使用了三元运算符来写返回 Login是登录,是一个业务方法,mapper接口是持久层,是…...
Spark SQL 运行架构详解(专业解释+番茄炒蛋例子解读)
1. 整体架构概览 Spark SQL的运行过程可以想象成一个"SQL查询的加工流水线",从原始SQL语句开始,经过多个阶段的处理和优化,最终变成分布式计算任务执行。主要流程如下: SQL Query → 解析 → 逻辑计划 → 优化 → 物理…...
【时时三省】(C语言基础)字符数组的输入输出
山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 字符数组的输入输出可以有两种方法。 ( 1 )逐个字符输入输出。用格式符“% c”输入或输出一个字符. ( 2 )将整个字符串一次输入或输出。用“% s”格式符,意思是对字符串( strin…...
Hive HA配置高可用
Hive的高可用性(HA)通过消除关键组件的单点故障来实现,确保系统在部分故障时仍能正常运行。其基本原理涉及以下核心组件和策略: 1. Hive Metastore 的高可用 多实例部署:部署多个Metastore服务实例,每个实例连接到共享的后端数据库(如MySQL、PostgreSQ…...
Python爬虫第20节-使用 Selenium 爬取小米商城空调商品
目录 前言 一、 本文目标 二、环境准备 2.1 安装依赖 2.2 配置 ChromeDriver 三、小米商城页面结构分析 3.1 商品列表结构 3.2 分页结构 四、Selenium 自动化爬虫实现 4.1 脚本整体结构 4.2 代码实现 五、关键技术详解 5.1 Selenium 启动与配置 5.2 页面等待与异…...
重构金融数智化产业版图:中电金信“链主”之道
近日,《商学院》杂志独家专访了中电金信常务副总经理(主持经营工作)冯明刚,围绕“金融科技”“数字底座”“架构转型”“AI驱动”等议题,展开了一场关于未来架构、技术变革与系统创新的深入对话。 当下,数字…...
笔记本电脑升级实战手册【扩展篇1】:flash id查询硬盘颗粒
文章目录 前言:一、硬盘颗粒介绍1、MLC(Multi-Level Cell)2、TLC(Triple-Level Cell)3、QLC(Quad-Level Cell) 二、硬盘与主控1、主控介绍2、主流主控厂家 三 、硬盘颗粒查询使用flash id工具查…...
文档外发安全:企业数据防护的最后一道防线
在当今数字化时代,数据已成为企业最宝贵的资产之一。随着网络安全威胁日益增多,企业安装专业加密软件已从"可选"变为"必选"。本文将全面分析企业部署华途加密解决方案后获得的各项战略优势。 一、数据安全防护升级 核心数据全面保护…...
springboot集成langchain4j实现票务助手实战
前言 看此篇的前置知识为langchain4j整合springboot,以及springboot集成langchain4j记忆对话。 Function-Calls介绍 langchain4j 中的 Function Calls(函数调用)是一种让大语言模型(LLM)与外部工具(如 A…...
ZYNQ笔记(二十一): VDMA HDMI 彩条显示
版本:Vivado2020.2(Vitis) 任务:实现驱动 HDMI 显示彩条图像,同时支持输出给 HDMI 的图像分辨率可调。 目录 一、介绍 二、硬件设计 (1)DVI_Transmitter (2)Clockin…...