Android面试总结之GC算法篇
一、GC 机制核心原理与算法
面试题 1:Android 中为什么采用分代回收?分代策略如何优化 GC 效率?
标准答案:
分代回收基于对象生命周期的差异,将堆分为年轻代(Young Gen)和老年代(Old Gen):
- 年轻代:对象存活率低,采用复制算法(如 ART 的 Generational Copying),将存活对象复制到 To 区,快速回收垃圾。例如,新创建的对象首先分配在 Eden 区,Minor GC 时存活对象晋升到 Survivor 区,多次 GC 后进入老年代29。
- 老年代:对象存活率高,采用标记 - 整理算法(如 ART 的并发标记清除),减少内存碎片。老年代 GC(Major GC)触发频率较低,但耗时较长28。
ART 优化:
- 动态分代策略:根据应用内存使用模式自动调整年轻代 / 老年代比例,例如频繁创建短期对象的应用会扩大年轻代。
- 并发标记:在老年代 GC 时,允许应用线程与 GC 线程并行执行,减少 UI 卡顿。例如,标记阶段 GC 线程扫描对象图,应用线程继续分配内存89。
面试题 2:GC Roots 包含哪些对象?如何通过 GC Roots 判断对象存活?
标准答案:
GC Roots 是垃圾回收的起点,包括以下对象34:
- 虚拟机栈(栈帧中的本地变量表):方法执行时的局部变量引用。
- 本地方法栈中的 JNI 引用:Native 代码通过
NewGlobalRef
创建的强引用。 - 方法区中的静态变量和常量:如类的静态字段、字符串常量池中的引用。
- 活动线程:当前运行线程及其调用栈中的对象。
- 被同步锁(synchronized)持有的对象:确保锁对象在同步块执行期间不被回收。
存活判断:从 GC Roots 出发,通过可达性分析(Reachability Analysis)遍历对象图,所有可到达的对象为存活对象,不可到达的对象将被回收。例如,若 Activity 被单例强引用,即使 Activity 销毁,仍会被视为存活对象,导致内存泄漏35。
二、内存泄漏深度解析与实战
面试题 3:列举三种 Android 典型内存泄漏场景,并说明解决方案。
标准答案:
- 静态变量持有 Activity 引用
- 场景:单例或静态集合类直接持有 Activity 上下文。
- 示例:
public class Singleton {private static Singleton instance;private Context context;private Singleton(Context context) { this.context = context; } // 若传入Activity上下文,Activity无法回收 }
- 解决方案:改用 Application 上下文(生命周期与 App 一致):
private Singleton(Context context) { this.context = context.getApplicationContext(); } ```{insert\_element\_5\_}。
- 非静态内部类 / 匿名类持有外部 Activity 引用
- 场景:Handler、AsyncTask 等非静态内部类隐式持有 Activity 引用,若任务未取消,Activity 无法回收。
- 示例:
public class MainActivity extends AppCompatActivity {private Handler handler = new Handler() { // 非静态Handler,持有Activity强引用@Override public void handleMessage(Message msg) { /* ... */ }}; }
- 解决方案:
- 使用静态内部类 + 弱引用包裹 Activity:
private static class MyHandler extends Handler {private final WeakReference<MainActivity> activityRef;public MyHandler(MainActivity activity) { activityRef = new WeakReference<>(activity); }@Override public void handleMessage(Message msg) {MainActivity activity = activityRef.get();if (activity != null) { /* 安全操作 */ }} }
- 在
onDestroy()
中移除所有未处理消息:@Override protected void onDestroy() {super.onDestroy();handler.removeCallbacksAndMessages(null); } ```{insert\_element\_6\_}。
- 使用静态内部类 + 弱引用包裹 Activity:
- 未关闭的资源(文件流、数据库连接等)
- 场景:未显式关闭
InputStream
、Cursor
等系统资源,导致句柄泄漏。 - 解决方案:
- 使用
try-with-resources
自动关闭:try (InputStream is = new FileInputStream("file.txt")) { /* 读取文件 */ } // 自动调用is.close()
- 在
finally
块中手动关闭:Cursor cursor = null; try {cursor = db.query(...);// 处理cursor } finally {if (cursor != null && !cursor.isClosed()) cursor.close(); } ```{insert\_element\_7\_}。
- 使用
- 场景:未显式关闭
面试题 4:弱引用能否解决所有内存泄漏?为什么?
标准答案:
弱引用(WeakReference
)只能解决特定场景的泄漏,无法覆盖所有情况:
- 适用场景:当泄漏根源是 “强引用可被弱引用替代” 时有效。例如:
- 非静态内部类持有 Activity 引用(改为静态内部类 + 弱引用)。
- 回调中持有上下文(如 Listener 用弱引用避免 Activity 泄漏)56。
- 不适用场景:
- 单例持有强上下文:若单例直接持有 Activity 上下文,改用 Application 上下文更合理,弱引用会导致空指针。
- 未关闭的资源:资源句柄泄漏与引用类型无关,需显式释放。
- 未停止的线程 / Handler:线程或 Handler 未停止时,即使使用弱引用,线程仍可能持有强引用。
- 集合类未清理元素:全局集合未移除元素,弱引用无法解决(集合本身仍持有强引用)56。
三、ART 与 Dalvik 的 GC 差异
面试题 5:对比 ART 与 Dalvik 的 GC 策略,说明 ART 的优化点。
标准答案:
特性 | Dalvik | ART |
---|---|---|
编译方式 | JIT(运行时编译) | AOT(安装时编译)+ 部分 JIT |
GC 算法 | 标记 - 清除为主,碎片化严重 | 分代回收(年轻代复制,老年代并发标记清除) |
内存占用 | 较高,碎片化导致内存利用率低 | 较低,动态压缩堆内存减少碎片 |
GC 暂停时间 | 单次 Full GC 耗时较长,易导致卡顿 | 并发标记减少暂停时间,增量 GC 分散任务 |
大对象处理 | 直接分配在堆中,易触发 Full GC | 大对象空间(LOS)独立管理,减少碎片 |
- 并发标记(Concurrent Marking):GC 线程与应用线程并行执行,减少 UI 卡顿。例如,标记阶段允许应用继续分配内存89。
- 增量 GC(Incremental GC):将 GC 工作拆分为多个小任务,分散在多个帧中执行,避免长时间阻塞主线程9。
- 内存压缩:动态压缩堆内存,释放连续内存块,提升大对象分配成功率89。
四、性能优化工具与实战
面试题 6:如何使用 Android Profiler 检测内存泄漏?
标准答案:
- 启动 Profiler:在 Android Studio 中通过
View > Tool Windows > Profiler
打开。 - 录制内存轨迹:运行应用,点击 Profiler 中的 “Memory” 标签,开始录制内存分配过程。
- 分析内存泄漏:
- 触发泄漏场景:例如多次打开 / 关闭 Activity。
- 生成 Heap Dump:点击 “Dump Java Heap” 生成内存快照。
- 查找泄漏路径:在 Heap 分析视图中,使用 “Path to GC Roots” 功能追踪对象引用链,定位泄漏根源(如未释放的 Handler 引用)56。
面试题 7:如何避免大对象引发的性能问题?
标准答案:
- 拆分大对象:将巨型数组或字符串拆分为多个小对象,减少单次内存分配压力。
- 使用 ByteBuffer:通过
ByteBuffer
管理内存布局,避免内存碎片。例如:java
ByteBuffer buffer = ByteBuffer.allocateDirect(1024 * 1024); // 直接内存,减少GC压力
- 复用对象池:对频繁创建的大对象(如网络请求缓冲区)使用对象池复用,减少 GC 触发频率。
- 避免在主线程分配大对象:将大对象分配移至后台线程,避免 UI 卡顿611。
五、高频问题扩展
面试题 8:解释 Zygote 机制如何优化内存共享。
标准答案:
Zygote 是 Android 系统的核心进程,通过以下方式实现内存共享:
- 共享只读内存:Zygote 在启动时加载 Framework 类和资源,其他应用进程通过
fork
复制 Zygote 内存,减少重复加载。例如,多个应用共享同一套 Android 系统类12。 - 写时复制(Copy-On-Write):子进程修改共享内存时,才会分配独立物理内存,避免内存浪费。例如,应用进程修改字符串常量时,仅复制该字符串所在的内存页12。
- 大对象独立管理:Zygote 堆中的大对象存储在独立空间,避免影响其他进程的内存分配12。
面试题 9:ART 的并发 GC 如何减少暂停时间?
标准答案:
ART 的并发 GC(如粘性 CMS)通过以下机制减少暂停时间:
- 并发标记阶段:GC 线程与应用线程并行扫描对象图,标记存活对象。此时可能产生 “浮动垃圾”(标记后新创建的对象),需在最终标记阶段处理89。
- 增量更新(Incremental Update):当应用线程修改引用关系时,通过写屏障(Write Barrier)记录变化,确保 GC 线程能正确追踪新引用,避免重复扫描9。
- 并行回收:多核设备上允许多个线程同时执行标记和清除操作,缩短 Full GC 时间89。
六、面试陷阱与避坑指南
-
GC Roots 的动态变化:
- 陷阱:面试官可能提问 “静态变量是否永远是 GC Root?”
- 避坑:静态变量在类卸载前始终是 GC Root,但类卸载仅在特定条件下发生(如自定义类加载器)。实际开发中,静态变量引用需谨慎管理,避免长生命周期对象泄漏。
-
内存泄漏的隐蔽场景:
- 陷阱:“使用 WeakReference 包裹 Activity 就能避免泄漏吗?”
- 避坑:弱引用仅在对象未被强引用时生效。若内部类 / 线程仍持有强引用(如未取消的 AsyncTask),弱引用无法解决泄漏。需结合生命周期管理(如在
onDestroy()
中取消任务)56。
-
GC 日志分析:
- 陷阱:面试官可能给出 GC 日志片段,要求分析问题。
- 避坑:重点关注
paused
时间(如单次 GC 暂停超过 16ms 可能导致卡顿)、freed
对象数量(频繁 Minor GC 提示内存分配压力大)、LOS
对象回收情况(大对象是否合理使用)912。
GC日志分析扩展:
-
典型 GC 日志解读
以下是一条 ART 的 GC 日志示例:07-01 16:00:44.690: I/art(801): Explicit concurrent mark sweep GC freed 65595(3MB) AllocSpace objects, 9(4MB) LOS objects, 34% free, 38MB/58MB, paused 1.195ms total 87.219ms
- GC 类型:
concurrent mark sweep
表示并发标记清除,主要回收老年代4。 - 回收量:释放了 3MB 非大对象和 4MB 大对象,堆内存使用率降至 34%。
- 暂停时间:应用线程暂停 1.195ms,总耗时 87.219ms。高暂停时间可能导致 UI 卡顿,需排查内存抖动问题4。
- GC 类型:
-
关键指标与优化方向
- 暂停时间(Pause Time):若单次 GC 暂停超过 16ms,可能导致帧率下降。需检查是否有大量临时对象或长生命周期引用。
- GC 频率:频繁的 Minor GC(如每秒多次)表明内存分配压力大,可通过对象池或复用策略优化。
- 大对象回收:若 LOS 频繁触发 GC,需避免创建不必要的大对象(如巨型数组),或使用
ByteBuffer
优化内存布局4。
相关文章:
Android面试总结之GC算法篇
一、GC 机制核心原理与算法 面试题 1:Android 中为什么采用分代回收?分代策略如何优化 GC 效率? 标准答案: 分代回收基于对象生命周期的差异,将堆分为年轻代(Young Gen)和老年代(Ol…...
驱动开发系列55 - Linux Graphics QXL显卡驱动代码分析(二)显存管理
一:概述 前面介绍了当内核检测到匹配的PCI设备后,会调用 qxl_pci_probe 初始化设备,其中会调用qxl_device_init 来初始化设备,为QXL设备进行内存映射,资源分配,环形缓冲区初始化,IRQ注册等操作,本文展开说说这些细节,以及介绍下QXL的显存管理。 二:QXL设备初始化细节…...
javaScript——DOM续(六)
滚轮事件 在 Web 开发中监听鼠标滚轮事件时,不同浏览器存在差异。下面是对 onmousewheel、DOMMouseScroll 和标准 wheel 事件的完整说明和兼容写法。 🌀 onmousewheel 事件概览 onmousewheel 是早期浏览器(如 IE 和 Chrome)支持…...
MySQL 服务搭建
💢欢迎来到张翊尘的开源技术站 💥开源如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 在线安装Ubuntu/Debian更新系统包索引安装 MySQL …...
Eigen的使用
https://github.com/PX4/eigen Eigen在Qt中的配置(博主亲测) 1、Qt中调用 //.pro中-------- INCLUDEPATH \$$PWD/eigen-master//.cpp中------- #include <Eigen/Dense> using namespace Eigen;Matrix2d a; MatrixXd b(2,2); Vector3d v(1,2,3);…...
【云原生】基于Centos7 搭建Redis 6.2 操作实战详解
目录 一、前言 二、Redis 6.2 安装过程 2.1 下载安装包 2.2 安装包解压 2.3 安装包编译 2.3 安装 2.4 启动redis 2.4.1 前台启动(不推荐) 2.4.2 后启动(推荐) 2.4.3 关闭redis服务 2.4.4 设置客户端连接 三、写在最后 …...
《TCP/IP详解 卷1:协议》之第九章:IP选路
目录 一、IP选路之IP层工作流程 二、选路原理 三、路由表中的五种不同的标志(flag) 四、路由表的初始化 1、静态路由表初始化 ①、手动配置 ②、默认网关配置 2、动态路由表初始化 ①、路由协议的作用 ②、直接连接网络的自动发现 五、没有到达…...
HTTP知识速通
一.HTTP的基础概念 首先了解HTTP协议,他是目前主要使用在应用层的一种协议 http被称为超文本传输协议 而https则是安全的超文本传输协议 本章节的内容首先就是对http做一个简单的了解。 HTTP是一种应用层协议,是基于TCP/IP协议来传递信息的。 其中…...
npm命令介绍(Node Package Manager)
文章目录 npm命令全解析简介基础命令安装npm(npm -v检插版本)初始化项目(npm init)安装依赖包(npm install xxx、npm i xxx) 依赖管理精解依赖类型区分(生产环境依赖dependencies、开发环境依赖…...
在 Windows 上启用 Telnet 命令
在 Windows 上启用打开 Telnet 命令 Telnet 是一种用于远程访问和管理计算机的协议。尽管存在安全漏洞,Telnet 仍然被广泛用于初始网络硬件配置、远程访问、端口测试等任务。在 Windows 10 和 11 上,可以通过多种方法启用 Telnet 客户端。 使用控制面板…...
网络安全零基础培训 L1-9 PHP连接MySQL数据库
使用MySQLi扩展 MySQLi 是 “MySQL Improved Extension” 的缩写,它是 PHP 用于与 MySQL 数据库进行交互的扩展。 step1:连接数据库 <?php// 定义数据库服务器的地址,通常 localhost 表示本地服务器$servername "服务器地址&quo…...
Python生活手册-文件二进制:从快递柜到生鲜冷链的数据保鲜术
一、快递柜与冷链运输:两种存取哲学 1. 普通快递柜(文本模式) 日常存取包裹的智能快递柜就像文本模式,系统会自动处理包裹的包装: with open(快递单.txt, r, encodingutf-8) as 快递柜:包裹内容 快递柜.read() # …...
CUDA从入门到放弃
1 CUDA简介 GPU为图形处理器, 也是显卡的“大脑”显卡集成了GPU, 显存和其他电路的硬件GPU: 计算密集型CPU: 逻辑流控制GPU性能指标: 核心数GPU显存容量GPU计算峰值显存带宽 GPU不能单独计算, CPUGPU组成异构计算架构CPU起到控制作用, 一般成为主机(Host), GPU可以看作CPU的协…...
Golang多人在线坦克对战游戏(帧同步)
以下是一个简化但完整的同步帧游戏示例——实现一个多人在线坦克对战游戏。代码分为服务器和客户端两部分,使用UDP协议通信。我们将重点讲解核心同步机制。 项目结构 sync-frame-game/ ├── server/ │ ├── main.go # 游戏服务器主逻辑 │ └── game_stat…...
MySQL | DQL语句-连接查询
MySQL | DQL语句-连接查询 🪄个人博客:https://vite.xingji.fun 什么是连接查询 从一张表中查询数据称为单表查询。从两张或更多张表中联合查询数据称为多表查询,又叫做连接查询。什么时候需要使用连接查询? 比如这样的需求&…...
JVM——Java 虚拟机是如何加载 Java 类的?
引入 在 Java 世界的底层运作中,类加载机制扮演着一个既神秘又关键的角色。它就像是一个精心设计的舞台幕后 machinery,确保了 Java 程序能够顺利运行。今天,我们就深入探索 Java 虚拟机(JVM)是如何加载 Java 类的。 …...
Sigmoid函数导数推导详解
Sigmoid函数导数推导详解 在逻辑回归中,Sigmoid函数的导数推导是一个关键步骤,它使得梯度下降算法能够高效地计算。 1. Sigmoid函数定义 首先回顾Sigmoid函数的定义: g ( z ) 1 1 e − z g(z) \frac{1}{1 e^{-z}} g(z)1e−z1 2. 导…...
运维工作中,Ansible常用模块有哪些?
Ansible是一个强大的自动化运维工具,他通过模块来执行各种任务。Ansible的模块库非常丰富,涵盖了系统管理、文件操作、软件包管理、网络配置、云服务等多个领域。以下是Ansible中常见的模块分类及具体模块详细介绍: 系统管理模块 主要用于管…...
内存安全的攻防战:工具链与语言特性的协同突围
一、内存安全:C 开发者永恒的达摩克利斯之剑 在操作系统内核、游戏引擎、金融交易系统等对稳定性要求苛刻的领域,内存安全问题始终是 C 开发者的核心挑战。缓冲区溢出、悬空指针、双重释放等经典漏洞,每年在全球范围内造成数千亿美元的损失。…...
Linux-04-搜索查找类命令
一、find查找文件或目录: 1.基本语法: find指令将从指定目录向下递归地遍历其各个子目录1,将满足条件的文件显示在终端 find[搜索范围] [选项] 2.选项说明: 选项功能-name <查询方式>按照指定的文件名查找模式查找文件-user <用户名>查找属于指定用…...
移动光猫 UNG853H 获取超级管理员账号密码
注:电脑连接光猫,网线不要接2口(2口一般是IPTV网口) 首先浏览器打开 192.168.1.1,使用光猫背面的用户名密码登录。(user用户名) 然后在浏览器中另开一个窗口打开以下地址: http://…...
健康生活新主张:全方位养生指南
在追求高品质生活的今天,健康养生早已不是老年人的专属话题,而是每个人都该掌握的生活技能。科学养生不需要复杂的程序,而是通过日常习惯的优化,为身体注入源源不断的活力。 饮食管理是健康的根基。选择天然、少加工的食材&#x…...
py使用uniad原生sdk 3, 放弃Buildozer,使用BeeWare
目前,Buildozer 支持打包: Android:通过 Python for Android。您必须有 Linux 或 OSX computer 才能为 Android 进行编译。 iOS:通过 Kivy iOS。您必须拥有 OSX computer 才能为 iOS 进行编译。 支持其他平台在路线图中…...
【数据分享】2020年中国高精度森林覆盖数据集(免费获取)
森林作为全球陆地生态系统的主体,分布面积广、结构复杂,承担着调节气候、维护生态安全、改善环境等方面的重要作用。我国的森林资源丰富,据《中国森林资源报告:2014—2018》统计,我国森林覆盖率已经达到23.04%。森林覆…...
(007)Excel 公式的使用
文章目录 逻辑运算公式的参数常用函数引用方式引用工作表和工作簿表格的引用修改公式的计算时机区域交叉引用 逻辑运算 公式的参数 单元格引用:SUM(A1:A24)。字面值:SQRT(121)。字面文本字符串:PROPER(“john.f.smith”)。表达式:…...
Vue之脚手架与组件化开发
一、基础知识 1、准备工作 node版本在12以上(看情况而变) 全局安装vue/cli脚手架(不理解的可以去看一下node安装环境配置教程) npm i vue/cli -g 2、项目初始化 在终端输入 vue create my-vue-project(这里是名字࿰…...
第四章 Maven
01 01. maven-课程介绍 02 02. maven-概述-maven介绍 私服:提高下载效率,让中央仓库不必被反复访问。我们一般用阿里云的私服。 03 03. maven-概述-maven安装 04 04. maven-idea集成-配置及创建maven项目 05 05. maven-idea集成-导入maven项目 06 06. …...
哈希表笔记(四)Redis对比Java总结
文章目录 一、基础结构对比数据结构定义Java HashMapRedis字典 主要区别与设计思路 二、关键操作API对比初始化Java HashMapRedis字典 添加元素Java HashMapRedis字典 查找元素Java HashMapRedis字典 删除元素Java HashMapRedis字典 扩容/重哈希操作Java HashMapRedis字典 三、…...
【精选】基于数据挖掘的广州招聘可视化分析系统(大数据组件+Spark+Hive+MySQL+AI智能云+DeepSeek人工智能+深度学习之LSTM算法)
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...
WPF使用依赖注入框架AutoMapper
WPF应用中使用AutoMapper和依赖注入框架实现对象映射与依赖管理 1. 准备工作 首先,通过NuGet安装必要的包: Install-Package AutoMapper Install-Package Autofac Install-Package Autofac.Extensions.DependencyInjection Install-Package Microsoft.Extensions.Dependen…...
WPF封装常用的TCP、串口、Modbus、MQTT、Webapi、PLC通讯工具类
WPF封装常用通讯工具类 下面我将为您封装常用的TCP、串口、Modbus、MQTT、WebAPI和PLC通讯工具类,适用于WPF应用程序开发。 一、TCP通讯工具类 using System; using System.Net.Sockets; using System.Text; using System.Threading.Tasks;public class TcpClientHelper : …...
游戏引擎学习第253天:重新启用更多调试界面
运行游戏,尝试调试系统,并为今天的工作设定方向。 今天我们将继续完成调试编辑代码的收尾工作。虽然昨天已经让它运行起来了,但目前还在使用旧的GUID系统,以及调试系统里早期用于探索阶段的一些旧式实现。因此,我们需…...
C# | 基于C#实现的BDS NMEA-0183数据解析上位机
以下是一个基于C#实现的BDS NMEA-0183数据解析上位机的示例代码,包含基础功能和界面: using System; using System.Collections.Generic; using System.IO.Ports; using System.Windows.Forms; using System.Drawing; using System.Globalization;namespace BDS_NMEA_Viewer…...
【AI提示词】成本效益分析师
提示说明 专注于通过数据驱动的方式提供成本效益分析,帮助客户优化资源投入与预期回报。 提示词 # Role: 成本效益分析师## Profile - language: 中文 - description: 专注于通过数据驱动的方式提供成本效益分析,帮助客户优化资源投入与预期回报 - ba…...
Kotlin革新数据分析
摘要 在数据分析领域,Python长期占据主导地位。然而,随着技术的不断发展,Kotlin凭借其独特优势逐渐崭露头角。本文深入探讨Kotlin在数据分析中的应用,详细阐述其与Python在数据分析生态系统中的差异,通过具体案例展示…...
今日行情明日机会——20250430
指数目前仍然在震荡区间,等后续的方向选择以及放量后的主线~ 2025年4月30日涨停主要行业方向分析 一、核心主线方向 机器人概念(政策催化技术突破) • 涨停家数:18家。 • 代表标的: ◦ 全筑股份(工业机器…...
【Docker】Dockerfile 使用
文章目录 1. 什么是 Dockerfile?2. Dockerfile 核心指令详解2.1 基础指令2.2 构建过程指令2.3 运行时指令2.4 容器启动指令3. Dockerfile 最佳实践3.1 优化镜像构建3.2 安全性增强3.3 多阶段构建4. 完整 Dockerfile 示例5. 构建与验证6. 总结Docker 作为容器化技术的代表,已经…...
【Hive入门】Hive性能调优之资源配置:深入解析执行引擎参数调优
目录 前言 1 Hive执行引擎概述 2 MapReduce引擎调优 2.1 Map阶段资源配置 2.2 Reduce阶段资源配置 2.3 并发控制参数 3 Tez引擎调优 3.1 Tez架构概述 3.2 内存配置 3.3 并发与并行度 4 Spark引擎调优 4.1 Spark执行模型 4.2 内存管理 4.3 并行度配置 5 资源隔离…...
初学python的我开始Leetcode题8-3
提示:100道LeetCode热题-8-3主要是二叉树相关,包括三题:将有序数组转换为二叉搜索树、验证二叉搜索树、二叉搜索树中第K小的元素。由于初学,所以我的代码部分仅供参考。 目录 前言 题目1:将有序数组转换为二叉搜索树…...
【音频】Qt6实现MP3播放器
1、简介 解码MP3有很多种方法,比如:FFmpeg、GStreamer、Qt、libmpg123 库等,下面介绍使用,只使用Qt的接口方法解码、播放MP3。 开发配置: 1)操作系统:Windows11 2)Qt版本:Qt6.5.1 3)编译器:MinGW_64 2、获取音频输出设备 QMediaDevices 用于获取媒体设备,包括音…...
【Linux】VSCode用法
描述 部分图片和经验来源于网络,若有侵权麻烦联系我删除,主要是做笔记的时候忘记写来源了,做完笔记很久才写博客。 专栏目录:记录自己的嵌入式学习之路-CSDN博客 1 安装环境及运行C/C 1.1 安装及配置步骤 请参考这位大佬的…...
普通 html 项目也可以支持 scss_sass
项目结构示例 下载vscode的插件Live Sass Compiler 自动监听编译scss 下载插件Live Server 用于 web 服务器,打开 html 文件到浏览器,也可以不用这个,自己用 nginx 或者宝塔其他 web 工具 新建一个 index.scss打开,点击 vscode 底…...
C#实现主流PLC读写工具类封装
以下是针对三菱、欧姆龙、西门子S7系列、汇川、台达PLC的完整封装工具类实现,基于Modbus TCP/RTU、MC协议、QJ71等主流通信协议: 基础接口定义 /// <summary> /// PLC操作基础接口 /// </summary> public interface IPLC {/// <summary>/// 连接PLC/// &…...
C++之特殊类设计及类型转换
目录 一、设计一个不能被拷贝的类 二、设计一个只能在堆上创建对象的类 三、设计一个只能在栈上创建对象的类 四、设计一个不能被继承的类 五、设计一个只能创建一个对象的类(单例模式) 六、C语言中的类型转换 七、C中的三类类型转换 八、C强制类型转换 8.1、为什么C需…...
【Linux】C语言补充知识
有一些Linux常见的C语言用法需要哈好复习一下。 部分图片和经验来源于网络,若有侵权麻烦联系我删除,主要是做笔记的时候忘记写来源了,做完笔记很久才写博客。 专栏目录:记录自己的嵌入式学习之路-CSDN博客 1 结构体 1.1 结…...
怎么查看数据库容量
要查看数据库容量,你需要登录数据库管理系统,然后执行相应的 SQL 查询语句。不同的数据库管理系统有不同的语法,以下是一些常见的数据库管理系统中查看数据库容量的 SQL 查询语句示例: MySQL/MariaDB: SELECT table_schema &quo…...
深度学习中卷积的计算复杂度与内存访问复杂度
深度学习中卷积的计算复杂度与内存访问复杂度 在深度学习中,普通卷积(Standard Convolution)、深度可分离卷积(Depthwise Separable Convolution, DWConv)和部分卷积(Partial Convolution, PConvÿ…...
神经网络—损失函数
文章目录 前言一、损失函数概念二、损失函数原理1、分类问题中常见的损失函数(1)0-1损失函数原理优缺点 (2)交叉熵损失(Cross-Entropy Loss)原理优缺点 (3) 合页损失(Hin…...
Rust中避免过度使用锁导致性能问题的策略
一、引言 在 Rust 多线程编程中,锁是实现线程同步的重要工具,它可以防止多个线程同时访问和修改共享数据,从而避免数据竞争和不一致的问题。然而,过度使用锁会带来严重的性能问题,如锁竞争导致的线程阻塞、上下文切换…...
Qt connect第五个参数
在 Qt 中,QObject::connect 函数的第五个参数用于指定 连接类型(Qt::ConnectionType),它决定了信号与槽之间的通信方式。以下是各枚举值的详解及使用场景: 1. Qt::AutoConnection(默认值) 行为…...