《JVM如何判断一个对象可以被回收?图文详解GC Root算法》
大家好呀!我是你们的老朋友Java技术博主👋 今天咱们来聊聊Java虚拟机(JVM)中一个超级重要的话题——垃圾回收机制(Garbage Collection)和GC Root可达性分析!这可是Java程序员必须掌握的核心知识点哦!😎
🌟 前言:为什么需要垃圾回收?
想象一下你家的房间 🏠,如果从来不打扫卫生,垃圾越堆越多,最后会怎么样?没错,房间会变得又脏又乱,甚至没法住人了!😱
Java程序运行时也是这样,会不断创建对象(就像产生垃圾),如果不及时清理,内存就会被占满,程序就会"卡死"!💀
所以Java设计了"自动垃圾回收"机制,就像请了个智能保洁阿姨 🤖,会自动帮我们打扫内存,清理不再使用的对象。这就是GC(Garbage Collection)的由来!
📚 一、垃圾回收基本概念
1.1 什么是垃圾?
在Java中,"垃圾"就是指那些已经不再被使用的对象。比如:
public class Test {public static void main(String[] args) {String s1 = new String("hello"); // 创建对象1s1 = new String("world"); // 对象1变成垃圾了!}
}
上面的代码中,第一个"hello"字符串对象后来没人引用了,就变成了垃圾🗑️。
1.2 为什么要回收垃圾?
因为内存是有限的!如果不回收垃圾:
- 内存会被慢慢耗尽 💧
- 程序运行会越来越慢 🐢
- 最终导致OutOfMemoryError崩溃 💥
1.3 垃圾回收是谁来做的?
JVM中有专门的垃圾收集器(Garbage Collector) 来做这件事,不同的JDK版本有不同的实现,比如:
- Serial GC 🚂
- Parallel GC ✈️
- CMS GC �
- G1 GC 🚀
- ZGC 🛸
(具体收集器我们后面再细讲)
🔍 二、如何判断对象是垃圾?
这是垃圾回收的核心问题!JVM主要使用可达性分析算法来判断对象是否存活。
2.1 引用计数法(简单但有问题)
先来看一个简单的思路:给每个对象加个计数器,记录有多少引用指向它。
Object a = new Object(); // 对象A的引用计数=1
Object b = a; // 对象A的引用计数=2
a = null; // 对象A的引用计数=1
b = null; // 对象A的引用计数=0 → 可以回收
看起来不错?但是有个致命问题——循环引用!
class Node {Node next;
}Node a = new Node(); // 对象A计数=1
Node b = new Node(); // 对象B计数=1
a.next = b; // 对象B计数=2
b.next = a; // 对象A计数=2a = null; // 对象A计数=1
b = null; // 对象B计数=1
// 但实际上A和B已经无法被访问了,却因为计数不为0无法回收!😱
所以Java没有用这种方法!
2.2 可达性分析算法(Java实际使用的)
这个算法就像在对象间玩"谁是我的朋友"的游戏 🎮:
- 首先定义一些GC Roots(相当于"顶级大佬")
- 从这些GC Roots出发,看看能"抱大腿"(被引用)的对象
- 所有能通过引用链到达的对象都是存活对象
- 其他对象就是垃圾,可以回收
[外链图片转存中…(img-u7WZTOeT-1746801753658)] (想象这是一张很生动的可达性分析图)
🌳 三、GC Roots有哪些?
GC Roots就像是对象世界的"顶级大佬",主要有以下几类:
3.1 虚拟机栈中的局部变量
public void method() {Object obj = new Object(); // obj就是GC Root// ...
} // 方法结束后obj不再为GC Root
3.2 方法区中的静态变量
class Test {static Object staticObj = new Object(); // staticObj是GC Root
}
3.3 方法区中常量引用的对象
class Test {static final String CONSTANT = "constant"; // CONSTANT是GC Root
}
3.4 本地方法栈中JNI引用的对象
public native void nativeMethod(Object obj); // native方法引用的对象
3.5 同步锁持有的对象
synchronized(lockObject) { // lockObject是GC Root// ...
}
3.6 虚拟机内部引用
比如基本类型对应的Class对象、常驻的异常对象等。
🧐 四、可达性分析详细过程
让我们用一个超详细的例子来看看可达性分析是怎么工作的!
class Person {String name;Person friend;Person(String name) {this.name = name;}
}public class GCDemo {static Person p1 = new Person("张三"); // GC Rootpublic static void main(String[] args) {Person p2 = new Person("李四"); // GC Root (栈局部变量)Person p3 = new Person("王五"); // GC Root (栈局部变量)p1.friend = p2;p2.friend = p3;p3.friend = new Person("赵六");p2 = null; // 断开李四的引用}
}
现在内存中的对象关系是这样的:
GC Roots:- 静态变量 p1 → 张三- 局部变量 p3 → 王五对象引用链:张三 → 李四 → 王五 → 赵六王五 (直接由p3引用)
可达性分析步骤:
-
从GC Roots出发:
- p1(张三)可达
- p3(王五)可达
-
扫描张三的引用:
- 张三 → 李四 (可达)
- 李四 → 王五 (但王五已经被标记)
- 王五 → 赵六 (可达)
-
最终存活对象:
- 张三、李四、王五、赵六
-
其他对象:无(这个例子中所有对象都可达)
如果把代码改成:
p3 = null; // 断开王五的引用
那么对象链就变成:
张三 → 李四 → 王五 → 赵六
但没有任何GC Roots能到达王五和赵六了,所以:
- 存活对象:张三、李四
- 可回收对象:王五、赵六
⏳ 五、对象的生死历程
一个对象在垃圾回收中的"一生"是这样的:
- 可达的:从GC Roots能到达
- 可复活:重写了finalize()方法且未被调用过
- 不可达的:从GC Roots无法到达
- 真正死亡:finalize()后仍然不可达
特别要注意finalize()
方法:
protected void finalize() throws Throwable {// 对象被回收前的最后挣扎// 可以在这里让对象重新被引用"复活"
}
但是!⚠️ 强烈建议不要依赖finalize()!因为:
- 调用时机不确定
- 性能差
- 可能根本不被调用
🧹 六、垃圾回收算法
知道了哪些是垃圾后,JVM会用以下几种方式清理:
6.1 标记-清除 (Mark-Sweep)
- 标记所有存活对象
- 清除所有未标记对象
✅ 优点:简单直接
❌ 缺点:产生内存碎片
6.2 标记-整理 (Mark-Compact)
- 标记存活对象
- 移动存活对象到内存一端
- 清理边界外内存
[外链图片转存中…(img-hQAmW4wT-1746801753659)]
✅ 优点:没有碎片
❌ 缺点:移动对象成本高
6.3 复制算法 (Copying)
把内存分成两块,只用其中一块:
- 将存活对象复制到另一块
- 清空当前块
✅ 优点:没有碎片、简单高效
❌ 缺点:浪费一半内存
6.4 分代收集 (Generational)
这是现代JVM最常用的方法!根据对象存活时间把堆分成:
-
新生代 (Young Generation) - 新创建的对象
- 使用复制算法
- 分为Eden、Survivor0、Survivor1区
-
老年代 (Tenured Generation) - 长期存活的对象
- 使用标记-清除或标记-整理
-
永久代/元空间 (PermGen/Metaspace) - 类信息等
- JDK8后用元空间替代永久代
对象晋升过程:
新生对象 → Eden区 → 第一次GC后 → Survivor区 → 多次GC后 → 老年代
🚗 七、常见垃圾收集器
JVM提供了多种垃圾收集器,就像不同的清洁车:
7.1 Serial收集器 🚜
- 单线程工作
- 适合客户端小应用
- 会"Stop The World"(暂停所有应用线程)
7.2 Parallel收集器 ✈️
- Serial的多线程版本
- JDK8默认收集器
- 注重吞吐量
7.3 CMS收集器 🚒
- 并发标记清除
- 减少停顿时间
- JDK9开始被废弃
7.4 G1收集器 🚀
- JDK9后默认收集器
- 把堆分成多个Region
- 可预测停顿时间
7.5 ZGC收集器 🛸
- JDK11引入
- 超低延迟(<10ms)
- 处理超大堆
🛠️ 八、GC调优基础
虽然GC是自动的,但我们也可以适当调优:
8.1 常用JVM参数
-Xms
/-Xmx
:初始/最大堆大小-Xmn
:新生代大小-XX:+UseG1GC
:使用G1收集器-XX:MaxGCPauseMillis=200
:目标最大GC停顿
8.2 调优原则
- 优先让JVM自动调整
- 先满足性能要求,再考虑减少内存
- 监控GC日志是关键!
8.3 查看GC日志
添加JVM参数:
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log
💡 九、内存泄漏排查技巧
即使有GC,也可能发生内存泄漏!常见原因:
- 静态集合持有对象
- 未关闭的资源(连接、流等)
- 监听器未注销
- 不合理的缓存
排查工具:
jmap
:生成堆转储jvisualvm
:可视化分析Eclipse MAT
:强大的内存分析工具
📝 十、总结
- 垃圾回收是JVM自动内存管理机制 🧹
- 可达性分析通过GC Roots判断对象存活 🌳
- GC Roots包括:栈局部变量、静态变量等 🔍
- 主要回收算法:标记-清除、复制、分代 ♻️
- 不同收集器适用于不同场景 🚀
- 适当调优可以提升性能 ⚡
记住,理解GC原理对于写出高性能Java程序非常重要!
推荐阅读文章
-
由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)
-
如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系
-
HTTP、HTTPS、Cookie 和 Session 之间的关系
-
什么是 Cookie?简单介绍与使用方法
-
什么是 Session?如何应用?
-
使用 Spring 框架构建 MVC 应用程序:初学者教程
-
有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误
-
如何理解应用 Java 多线程与并发编程?
-
把握Java泛型的艺术:协变、逆变与不可变性一网打尽
-
Java Spring 中常用的 @PostConstruct 注解使用总结
-
如何理解线程安全这个概念?
-
理解 Java 桥接方法
-
Spring 整合嵌入式 Tomcat 容器
-
Tomcat 如何加载 SpringMVC 组件
-
“在什么情况下类需要实现 Serializable,什么情况下又不需要(一)?”
-
“避免序列化灾难:掌握实现 Serializable 的真相!(二)”
-
如何自定义一个自己的 Spring Boot Starter 组件(从入门到实践)
-
解密 Redis:如何通过 IO 多路复用征服高并发挑战!
-
线程 vs 虚拟线程:深入理解及区别
-
深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别
-
10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!
-
“打破重复代码的魔咒:使用 Function 接口在 Java 8 中实现优雅重构!”
-
Java 中消除 If-else 技巧总结
-
线程池的核心参数配置(仅供参考)
-
【人工智能】聊聊Transformer,深度学习的一股清流(13)
-
Java 枚举的几个常用技巧,你可以试着用用
-
由 Spring 静态注入引发的一个线上T0级别事故(真的以后得避坑)
-
如何理解 HTTP 是无状态的,以及它与 Cookie 和 Session 之间的联系
-
HTTP、HTTPS、Cookie 和 Session 之间的关系
-
使用 Spring 框架构建 MVC 应用程序:初学者教程
-
有缺陷的 Java 代码:Java 开发人员最常犯的 10 大错误
-
Java Spring 中常用的 @PostConstruct 注解使用总结
-
线程 vs 虚拟线程:深入理解及区别
-
深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别
-
10大程序员提升代码优雅度的必杀技,瞬间让你成为团队宠儿!
-
探索 Lombok 的 @Builder 和 @SuperBuilder:避坑指南(一)
-
为什么用了 @Builder 反而报错?深入理解 Lombok 的“暗坑”与解决方案(二)
相关文章:
《JVM如何判断一个对象可以被回收?图文详解GC Root算法》
大家好呀!我是你们的老朋友Java技术博主👋 今天咱们来聊聊Java虚拟机(JVM)中一个超级重要的话题——垃圾回收机制(Garbage Collection)和GC Root可达性分析!这可是Java程序员必须掌握的核心知识点哦!😎 🌟…...
常用算法/机理模型演示平台搭建(一)
算法/机理模型演示平台搭建 一、算法列表(app/algorithms)二、行业机理模型 (app/models)三、如何使用本项目旨在为初学者提供 35种 常用算法和 9种 行业机理模型的简单Python实现或概念说明。每个算法都有其独特的应用场景,从数据预测、质量检测、过程控制到结构分析和优化问…...
一文详解红黑树
一文详解红黑树 前言一、基本概念与特性1.1 红黑树的定义1.2 红黑树的特性 二、红黑树的节点结构与表示三、红黑树的基本操作3.1 插入操作3.2 删除操作 四、红黑树的应用场景4.1 编程语言的集合类4.2 数据库索引4.3 Linux 内核进程调度 总结 前言 在数据结构的领域中ÿ…...
Windows 安装显卡驱动
1.第一步:打开Nvidia 官网驱动下载页面 2.第二步:选择相关信息, 玩游戏选择,GeForce Game Ready ,创意设计、摄影直播 选择 NVIDIA Studio 驱动程序 (NVIDIA Studio Driver - WHQL.) 2.第三步࿱…...
【C语言】易错题 经典题型
出错原因:之前运行起来的可执行程序没有关闭 关闭即可 平均数(average) 输入3个整数,输出它们的平均值,保留3位小数。 #include <stdio.h> int main() {int a, b, c;scanf("%d %d %d", &a, &…...
C++类与对象--5 运算符重载
对已有的运算符进行重新定义,赋予不同的功能,以适应不同的数据类型 5.1 加号运算符 实现两个自定义数据类型的加运算 (1)通过成员函数实现“”重载 class Number { public:Number(int a, int b):m_A(a),m_B(b){}Number(){}Number operator(Number &a…...
接口排查不能靠猜:实战中如何用抓包工具精准定位问题(含 Charles 使用示例)
几乎每个写代码的开发者都经历过这样的时刻:接口突然返回空、请求超时、前端数据没更新……你试过重启服务、翻查日志、改代码打印,最后还是无解。 我想说,其实很多问题的答案都藏在“网络请求”里,只是你没有去看。 这篇文章&a…...
【占融数科-注册/登录安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...
4.7 时间模块
时间模块: * 1. time:操作时间本身 2.datetime:主要用于设置某一时间 3.calendar:主要用于时间份量计算 import time # 1. actimr:把一个表示时间的元组转换为字符串。要是不给出参数则返回当前本地时间。 print(time.asctime())…...
SHIMADZU岛津 R300RC300 Operation Manual
SHIMADZU岛津 R300RC300 Operation Manual...
(C语言篇)处理字符串的四个基础函数
strlen、strcpy、strcat、strcmp使用以及注意事项 在C语言中,strlen、strcpy、strcat、strcmp是处理字符串的四个基础函数,都在<string.h>头文件中声明。下面为你详细介绍它们的功能、用法和注意事项。 1. strlen - 计算字符串长度 函数原型&am…...
mysql的安装方式
1.yum/apt安装 yum安装: 先搭建yum仓库,可以在清华源内找:mysql | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror vim /etc/yum.repos.d/mysql.repo[mysql-connectors-community] nameMySQL Connectors Communit…...
嵌入式(C语言篇)Day11
嵌入式Day11 一、动态内存分配核心函数 (一)函数列表 函数名功能头文件返回值malloc分配连续的size字节堆内存stdlib.h成功返回首地址(void*),失败返回NULLcalloc分配num个元素size字节/元素的堆内存,自…...
Java集合框架解析:从基础到底层源码
Java集合框架解析:从基础到底层源码 一、集合体系 1.1 两大核心接口深度解析 Collection 单列集合 List 系列 ArrayList:动态数组实现,初始容量10,扩容策略为 原容量的1.5倍// JDK17 扩容源码片段 int newCapacity oldCapacity…...
C语言实现android/linux按键模拟
C语言实现 input事件模拟 #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <linux/input.h>int main() {int fd open("/dev/input/event0", O_RDWR);if (fd < 0) {perror("Failed to open device");ret…...
VisionPro:轴承错位标识
找出轴承缺陷并标记:效果 1.打开导入图片 2.添加CogToolblock:方便后续写代码 3.对零件进行模板匹配 4.对图片进行预处理(重点) 5.添加找圆工具和展开工具 根据下图将线链接 6.添加模板匹配工具并运行 7.训练模板 好的全找出来 8.代码编写 红色框为添加的代码(下面有完整代码) …...
专题五:floodfill算法(扫雷游戏精讲)
以leetcode529题 题目解析: M表示:未挖出的地雷 E表示:未挖出的空白方块 什么叫未挖出,就是你没玩的时候,棋盘是什么样的,就是你站在上帝视角看待棋盘 B:表示挖出来是空白的,如…...
MySQL企业版免费开启,强先体验
近期Oracle突然宣布,MySQL企业版面向开发者免费开放下载,这一消息瞬间引爆DBA圈。作为数据库领域的“顶配车型”,企业版长期因高昂授权费让中小团队望而却步,如今免费开放无异于“劳斯莱斯开进菜市场”。 本文将深度拆解企业版的…...
React Contxt详解
React Contxt详解 React 的 Context API 是用于跨组件层级传递数据的解决方案,尤其适合解决「prop drilling」(多层组件手动传递 props)的问题。以下是关于 Context 的详细解析: 文章目录 React Contxt详解一、Context 核心概念二…...
前端工程的相关管理 git、branch、build
环境配置 标准环境打包 测试版:npm run build-test 预生产:npm run build-preview 正式版:npm run build 建议本地建里一个 .env.development.local 方便和后端联调时修改配置相关信息。 和 src 同级有一下区分环境的文件: .env.d…...
鸿蒙 Location Kit(位置服务)
移动终端设备已经深入人们日常生活的方方面面,如查看所在城市的天气、新闻轶事、出行打车、旅行导航、运动记录。这些习以为常的活动,都离不开定位用户终端设备的位置。 Location Kit 使用多种定位技术提供服务,可以准确地确定设备在室外/室…...
人工智能、机器学习与深度学习:概念解析与内在联系
人工智能、机器学习与深度学习:概念解析与内在联系 一、人工智能(Artificial Intelligence, AI) (一)人工智能的定义 人工智能的定义随着技术发展不断演变。从广义上讲,人工智能是指通过计算机技术实现的…...
【Linux学习】Ubuntu对用户进行管理
目录 写在前面 【Linux学习】Ubuntu对用户进行管理一、为什么需要用户管理?二、用户管理基础操作(一)用户管理1. 用户管理命令表格2. 关键操作场景说明场景一:创建用户并配置权限场景二:修改用户属性场景三:…...
JVM 垃圾回收器
以下是对主流 JVM 垃圾回收器的详细解析,涵盖 一、Serial GC(单线程串行回收器) 二、Parallel GC(吞吐量优先回收器) 三、CMS(Concurrent Mark Sweep,低延迟回收器) 四、G1&…...
JUC入门(三)
7、Callable 1、可以有返回值 2、可以抛出异常 3、方法不同 run()/call() 代码测试 老版本的应用 package com.yw.callable;public class Old {public static void main(String[] args) {new Thread(new MyThread()).start();} }class MyThread implements Runnable{Overri…...
RV1126多线程获取SMARTP的GOP模式数据和普通GOP模式数据
通过代码的方式同时获取SMARTP模式的VENC码流数据和普通GOP模式的VENC码流数据,并进行对比画质。 一.RV1126 VI采集摄像头数据并同时编码SMARTP模式和普通GOP模式的编码码流流程 RV1126利用多线程同时获取普通GOP的VENC码流数据和SMARTP的码流数据一般如上图&#…...
MySQL事务、视图、索引、备份和恢复
1. 事务 如果不使用事务,那么如果出现了张三账户汇款成功-500元,但是李四那边的服务器出现了故障没有接收到500元,那么就会出现张三账户里有500元但是李四那边的账户还是1元的情况,转账的500元被吞了。 创建事务 2. 视图 创建视图…...
yolov8训练模型优化模型【误检】
针对 YOLOv8 模型在电动车人脸检测中出现误检行人人脸的问题,结合最新研究与实践经验,以下提供多维度优化方案及具体实施步骤: 一、数据集优化 数据清洗与标注增强 剔除干扰样本:确保训练集中所有标注仅包含骑行状态的人脸&#x…...
初识MySQL · 索引
目录 前言: 重温磁盘 认识索引 为什么这么做,怎么做 重谈page 聚簇索引VS非聚簇索引 回表查询 索引分类 前言: 前文我们主要是介绍了MySQL的一些基本操作,增删查改一类的操作都介绍了,并且因为大多数情况下&am…...
Kubernetes in action-配置和应用升级
Kubernetes的配置和应用升级 1、配置1.1 configMap1.2 secret1.3 Downward API1.4 Kubernetes API 2、服务升级2.1 升级方式2.1.1 先删除所有的旧版pod,使用新版本pod替换2.1.2 先创建新版pod,再删除旧版本pod2.1.3 滚动优化 2.2 使用deployment声明式升…...
十三、面向对象底层逻辑-Dubbo序列化Serialization接口
一、引言:分布式通信的数据桥梁 在分布式服务调用中,参数的跨网络传输需要将对象转化为二进制流,这一过程直接影响系统的性能、兼容性与安全性。Dubbo通过Serialization接口构建了可扩展的序列化体系,支持多种序列化协议的无缝切…...
5.19 打卡
DAY 30 模块和库的导入 知识点回顾: 导入官方库的三种手段导入自定义库/模块的方式导入库/模块的核心逻辑:找到根目录(python解释器的目录和终端的目录不一致) 作业:自己新建几个不同路径文件尝试下如何导入...
MathType公式如何按照(1)(2)…编号
在word中使用mathtype插入公式,发现插入的公式编号默认为(1.1),(1.2)…,但论文中常用的公式编号是(1)(2)…,分享一下如何实现(1.1)→(1)。 ①word菜单找到“MathType”,点击“插入编号”-“格式化”。 ②取消勾选“章编号”和“节…...
解决即使安装了pageoffice网页还是无法跳转、点击按钮没有反应等问题
出现的现象: 安装了pageoffice网页还是无法跳转、点击按钮没有反应 网页提示的错误: 点击按钮之前右键检查网页发现的错误: 点击无效按钮之后右键检查出现的错误: 原因: 鉴于安全性的考虑,新版浏览器不支…...
正点原子STM32新建工程
MDK 源自德国的 KEIL 公司,是 RealView MDK 的简称。 MDK5 由两个部分组成: MDK Core 和 Software Packs。 MDK Core 又分成四个部分: uVision IDE with Editor(编辑器), ARMC/C Compiler(编译…...
计算机网络 第三章:运输层(一)
运输层位于应用层和网络层之间,是分层的网络体系结构的重要部分。该层为运行在不同主机上的应用进程提供直接的通信服务。通常特别关注因特网协议,即 TCP 和 UDP 运输层协议。 讨论运输层和网络层的关析,为研究运输层第一个关键功能ÿ…...
机器学习(14)——模型调参
文章目录 一、动态调参方法论1. 调参策略选择2. 千万数据优化原则 二、模型调参策略对比1. LightGBM调参路线2. XGBoost调参路线3. 随机森林调参策略 三、代码实现示例通用数据准备(适用于所有模型)1. LightGBM调参示例2. XGBoost调参示例3. 随机森林调参…...
基于PetaLinux的Zynq PS应用自启动全攻略
一、嵌入式Linux启动管理的艺术 在工业机器人、智能摄像头、边缘计算网关等场景中,开机自启动管理是系统可靠性的第一道关卡。本文将深入讲解Zynq PS端在PetaLinux环境下实现: Systemd服务深度定制启动时序精准控制启动速度优化技巧动态服务管理创新方案二、环境搭建与工程配…...
贪心算法:多处最优服务次序、删数问题
多处最优服务次序问题 问题描述:设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti(1≤i≤n),共有s处可以提供此项服务。应如何安排n个顾客的服务次序,才能使平均等待时间达到最小?平均等待时间是n个顾客等待服务时间的总和除以n。 算法设计:对于给定的n个顾…...
使用 Flask 框架实现FTP,允许用户通过 Web 界面浏览和下载文件夹中的所有文件
Flask 文件和文件夹下载服务实现 以下是一个基于 Flask 框架的简单 Web 服务,用于开放指定文件夹(./shared_files),允许用户通过浏览器浏览和下载文件夹中的所有文件和子文件夹。ZIP 和 TAR 文件将直接下载,而文件夹将…...
【Go】从0开始学习Go
文章目录 从0开始学习Go0 与C对比1 代码框架1.1 helloworld式代码示例1.2 主体代码元素(核心三部分)1.3 其他 2 与C/C区别3 有用的小工具4 注意事项 从0开始学习Go 0 与C对比 特性CGo编译型语言需要编译为机器码直接编译为二进制可执行文件静态类型类型…...
软件设计师SQL考点分析——求三连
一、考点分值占比与趋势分析 综合知识分值统计表(75分制) 年份考题数量分值分值占比考察重点2018334%关系代数、权限控制2019222.67%SQL注入、授权语句2020445.33%投影操作、权限回收2021334%视图操作、权限传递2022222.67%数据库安全、WITH GRANT OPT…...
使用tcs34725传感器和51单片机识别颜色
使用TCS34725颜色传感器和51单片机来识别颜色是一个非常有趣的项目。TCS34725是一种常用的RGB颜色传感器,能够测量红、绿、蓝光的强度,从而实现颜色识别。 1. 硬件连接 TCS34725传感器通过IC接口与51单片机连接。以下是连接方式: SDA&…...
数据库-oracle-包-视图传参
并发下可能不准确 -- 修改包规范 CREATE OR REPLACE PACKAGE sczz.p_view_param IS function set_n(n varchar2) return varchar2; function get_n return varchar2; function set_ny(ny varchar2) return varchar2; function get_ny return varchar2; …...
深入探讨Java中的上下文传递与ThreadLocal的局限性及Scoped Values的兴起
在Java开发中,特别是在依赖框架的应用程序中,上下文数据的管理是一个常见但具有挑战性的问题。上下文数据可能包括元数据、配置信息或其他需要在代码不同部分之间共享的信息。传统的做法是通过方法参数显式传递这些上下文,但这种方法会导致代码复杂、难以维护,尤其是在大型…...
Spring boot 学习笔记2
Maven 项目管理工具:Maven 通过 pom.xml(Project Object Model)文件描述项目配置,包括依赖、构建流程、插件等,实现项目标准化管理 依赖管理:自动下载并管理项目所需的第三方库(如 Spring、MyB…...
“保证医疗器械信息来源合法 真实、安全的保障措施、情况说明及相关证明”模板
保证医疗器械信息来源合法真实、安全的保障措施、情况说明及相关证明 一、医疗器械信息来源合法、真实、安全的管理措施 目前我公司网站所展示的医疗器械是企业代理品种,是取得合法注册资格的产品,拥有合法证明文件的产品。本网站仅展示本公司行政许可…...
Feature Toggle 不再乱:如何设计一个干净、安全、可控的特性开关系统?
网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…...
不锈钢保温容器行业2025数据分析报告
不锈钢保温容器市场概况 2024年全球不锈钢保温容器市场规模约为453.3亿元,预计到2031年将增长至608.3亿元,年均复合增长率(CAGR)为4.3%。这一增长主要得益于全球范围内对保温容器需求的持续增加,尤其是在户外活动、餐…...
leetcode239 滑动窗口最大值deque方式
这段文字描述的是使用单调队列(Monotonic Queue) 解决滑动窗口最大值问题的优化算法。我来简单解释一下: 核心思路 问题分析:在滑动窗口中,若存在两个下标 i < j 且 nums[i] ≤ nums[j],则 nums[i] 永远…...