【Java校招面试】基础知识(五)——GC
目录
- 前言
- 一、基础概念
- 二、垃圾回收算法
- 三、垃圾收集器
- 四、引用
- 后记
前言
本篇主要介绍Java垃圾回收机制——GC的相关内容。
“基础知识”是本专栏的第一个部分,本篇博文是第五篇博文,如有需要,可:
- 点击这里,返回本专栏的索引文章
- 点击这里,返回上一篇《【Java校招面试】基础知识(四)——JVM》
- 点击这里,前往下一篇《【Java校招面试】基础知识(六)——计算机网络》
一、基础概念
01. 垃圾回收(GC)发生的位置
垃圾回收发生在JVM内存模型的堆内存
中
02. 对象被判定为垃圾的标准
没有被其他对象引用。
03. 判定对象是否为垃圾的算法
1) 引用计数算法: 通过判断对象的引用数量来决定对象是否可以被回收。每个对象实例都有一个引用计数器,被引用则+1,完成引用则-1。任何引用计数为0的对象实例可以被当作垃圾收集。
- 优点: 执行效率高,程序执行受影响小。
- 缺点: 无法检测出循环引用的情况,会导致内存泄漏。
2) 可达性分析算法: 通过判断对象的引用链是否可达来决定对象是否可以被回收;
04. 可作为GC Root的对象
1) 虚拟机栈中引用的对象(栈帧中的本地变量表);
2) 方法区中的常量引用对象;
3) 方法区中的类静态属性引用的对象;
4) 本地方法栈中JNI(Native方法)的引用对象;
5) 活跃线程的引用对象。
二、垃圾回收算法
01. 标记清除算法(Mark and Sweep)
- 标记: 从根集合进行扫描,对存活的对象进行标记
- 清除: 对堆内存从头到尾进行线性遍历,回收不可达对象内存
- 存在的问题: 产生大量不连续的碎片,造成堆内存碎片化
02. 复制算法(Copying)
将堆内存按照一定的比例分成两块或多块,分为对象面和空闲面。选择其中的一块或两块作为对象面,其他的作为空闲面。对象主要在对象面上创建。当对象面的内存用完时,将存活的对象从对象面复制到空闲面。然后将对象面多有对象内存清除。适用于对象存活率低的场景。
- 优点:
1) 解决了碎片化的问题;
2) 顺序分配内存,简单高效;
3) 适用于对象存活率较低的场景; - 缺点: 在对象存活率较高的场景中,需要进行较多的复制
03. 标记整理算法(Compacting)
- 标记: 从根集合进行扫描,对存活的对象进行标记
- 清除: 移动所有存活的对象,且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收。
优点:
1) 避免内存的不连续性;
2) 不用设置两块内存互换;
3) 适用于对象存活率较高的场景;
04. 分代收集算法(Generational Collector)——目前的主流垃圾回收算法
- 特点:
1) 垃圾回收算法的组合;
2) 按照对象生命周期的不同划分区域以采取不同的垃圾回收算法; - 目的: 提高JVM的回收效率
05. JDK 8中对堆内存所作的调整
1) JDK 8以前及JDK 8的JVM内存模型区别
从图中可见,JDK 8中,从堆内存中去除了Permanent Generation(永久代)
,取而代之的是在本地内存中新设的Meta Space(元空间)
2) 永久代中存放的数据
① 类的元数据(如类的名称、访问修饰符、父类、实现的接口等)
② 常量池
③ 静态变量
④ 即时编译器编译后的代码
⑤ 一些需要在类加载时完成的初始化操作
3) 永久代存在的问题(被元空间替代的原因)
① 内存限制问题: 永久代的大小是通过-XX:MaxPermSize参数来指定的,而该参数的默认值较小,容易导致OutOfMemoryError异常。
② 类加载器泄漏问题: 在永久代中,存在着一些类加载器无法被回收的情况,导致永久代的内存无法释放,最终也会导致OutOfMemoryError异常。
③ 字符串常量池溢出问题: 由于字符串常量池被存储在永久代中,如果不合理地使用字符串常量,就会导致永久代的内存快速耗尽,最终也会导致OutOfMemoryError异常。
④ 性能问题: 永久代的垃圾回收效率很低,会导致应用程序的性能下降。
⑤ 维护成本问题: 永久代需要手动调整大小,而且需要进行垃圾回收,增加了应用程序的维护成本。
4) 永久代和元空间的区别
① 存储位置: 永久代位于JVM堆内存中,而元空间则是位于本地内存中。
② 大小限制: 永久代的大小是固定的,而且它很容易被填满,导致OutOfMemoryError。而元空间的大小是动态的,它可以根据需要来自动调整大小,因此更加灵活。
③ 垃圾回收: 永久代是由JVM的垃圾回收机制来进行管理和清除的。而元空间不再使用垃圾回收机制进行管理,而是使用本地内存的机制,例如使用操作系统的虚拟内存来管理。
④ 移植性: 由于永久代是Java虚拟机的一部分,因此它只能在Java虚拟机中使用。而元空间是本地内存的一部分,因此它可以在不同的虚拟机和操作系统中使用。
06. 垃圾回收器的分类
- Minor GC: 针对年轻代的垃圾回收,通常情况下只会回收年轻代中的Eden区和一个Survivor区。
- Major GC: 针对老年代的垃圾回收,通常情况下会回收整个老年代。
- Full GC: 针对整个堆空间的垃圾回收,包括年轻代和老年代。
他们的区别主要有以下几点:
1) 发生频率不同: Minor GC频率很高,可能会发生多次,Major GC和Full GC发生频率较低。
2) 对应用程序的影响不同: Minor GC对应用程序的影响较小,Major GC和Full GC会导致较长的停顿时间,对应用程序的影响较大。
3) 回收效率不同: Minor GC的回收效率较高,Major GC和Full GC的回收效率较低。
07. 触发Full GC的条件(答出3点即可)
1) 老年代空间不足
2) 永久代空间不足(针对JDK 7及以下版本)
3) CMS GC时出现promotion failed
、concurrent mode failure
4) Minor GC晋升到老年代的平均大小大于老年代的剩余空间
5) 程序中手动调用System.gc()
6) 使用RMI(远程方式)来进行RPC或管理的JDK应用,每小时执行1次Full GC
08. 年轻代
用于存放并尽可能快速地收集掉那些生命周期短的对象
1) 包含一个Eden(伊甸园)区和两个Suivivor(一个From区,一个To区),比例为8:1:1
2) 每次将Eden和From中的存活对象复制到To区中,最后清理掉Eden和From区;
3) 每次复制,存活对象的年龄+1,当对象的年龄达到一定值(默认是15,可以通过-XX:MaxTenuringThreshold修改)时,对象将会被移动到老年代。
09. 老年代
存放生命周期较长的对象,占整个堆内存的2/3
10. 常见的GC调优参数
- -XX:SurvivorRatio, Eden和Suivivor的比值,默认8:1;
- -XX:NewRatio, 老年代和年轻代内存大小的比例;
- -XX:MaxTenuringThreshold, 对象聪年轻代晋升到老年代经过GC次数的最大阈值;
11. Stop-The-World
1) JVM由于要执行GC而停止了应用程序的执行;
2) 任何一种GC算法中都会发生;
3) 多数GC优化通过减少Stop-The-World发生的时间来提高程序性能。
12. SafePoint
1) 分析过程中对象引用关系不会发生变化的点;
2) 产生SafePoint的地方: 方法调用、循环跳转、异常跳转等。GC发生时,让所有的线程都跑到最新的安全点,如果发现线程不在安全点,则恢复线程,等其跑到安全点。
3) 安全点数量需要适中,太少会让GC等待太长的时间;太多会增加程序运行的负荷。
三、垃圾收集器
01. 新生代常见的垃圾收集器
1) Serial收集器(-XX:+UseSerialGC,复制算法)
- 单线程收集,进行垃圾收集时,必须暂停所有工作线程;
- 简单高效,Client模式下默认的年轻代收集器。
2) ParNew收集器(-XX:+UseParNewGC,复制算法)
- 多线程收集,其余的行为、特点和Serial收集器一样;
- 单核执行效率不如Serial,在多核下执行才有优势,默认开启的线程数与CPU核数相同;
- 在Server模式下重要的收集器,除Serial外,只有ParNew可以和CMS收集器配合工作。
3) Parallel Scavenge收集器(-XX:+UseParallelGC,复制算法)
吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间)
- 比起关注用户线程停顿时间,更关注系统吞吐量;
- 在多核下执行才有优势,Server模式下默认的年轻代收集器;
- 如果对于垃圾收集器运作原理不是很了解,在优化过程中遇到困难时,可以使用-XX:+UseAdaptiveSizePolicy把调优任务交给虚拟机。
02. 老年代常见的垃圾收集器
1) Serial Old收集器(-XX:+UseSerialOldGC,标记整理算法)
- 单线程收集,进行垃圾收集时,必须暂停所有工作线程;
- 简单高效,Client模式下默认的老年代收集器。
2) Parallel Old收集器(-XX:+UseParallelOldGC,标记整理算法)
多线程,吞吐量优先
3) CMS收集器(-XX:+UseConcMarkSweepGC,标记清除算法)
- 初始标记:Stop-The-World
- 并发标记:并发追溯标记,程序不会停顿
- 并发预清理:查找执行并发标记阶段从年轻代晋升到老年代的对象
- 重新标记:暂停虚拟机,扫描CMS堆中的剩余对象
- 并发清理:清理垃圾对象,程序不会停顿
- 并发重置:重置CMS收集器的数据结构
存在的问题: 采用标记清除算法,不对内存进行压缩,会造成空间碎片化的问题
03. 既可用于老年代也可用于年轻代的GC
G1(Garbage First)收集器(-XX:+UseG1GC,复制+标记整理算法)
1) 特点:
- 并行和并发
- 分代收集
- 空间整合
- 可预测的停顿
2) 设计:
- 将整个Java堆内存划分成多个大小相等的Region
- 年轻代和老年代不再物理隔离
04. 所有垃圾收集器的关系
05. 两个在新的垃圾收集器
这两个垃圾收集器在JDK 11中作为实验特性引入,在JDK 15中已成为正式的垃圾收集器。
- Epsilon GC
- ZGC
06. Object类的finalize()方法的作用和C++的析构函数有什么不同?
1) C++中的析构函数是在对象生命周期结束时自动调用的,而不是在垃圾回收时调用的。
2) C++中的析构函数可以手动调用,而Java中的finalize()方法只能由垃圾回收器调用。
3) C++中的析构函数可以被重载,而Java中的finalize()方法是Object类的一个标准方法,不能被重载。
四、引用
01. Java中的强引用,软引用,弱引用,虚引用都是什么?
强引用(Strong Reference):
1) 最普遍的引用: Object obj = new Object();
2) 抛出OutOfMemoryError终止程序也不会回收具有强引用的对象;
3) 通过将对象的引用设置为null来弱化引用,使其被回收。
软引用(Soft Reference):
1) 对象处在有用但非必须的状态;
2) 只有当内存空间不足时,GC才会回收该引用的对象的内存;
3) 可以用来实现高速缓存;
4) 用法
String str = new String("abc");SoftReference<String> softReference = new SoftReference<>(str);
弱引用(Weak Reference):
1) 非必需的对象,比软引用更弱一些;
2) GC时会被回收;
3) 由于GC线程优先级很低,被回收的概率也不大;
4) 适用于引用偶尔被使用且不影响垃圾收集的对象;
5) 用法:
String str = new String("abc");WeakReference<String> weakReference = new weakReference<>(str);
虚引用(Phantom Reference):
1) 不会决定对象的生命周期;
2) 任何时候都可能被垃圾收集器回收;
3) 跟踪对象被垃圾收集器回收的活动,起哨兵的作用;
4) 必须和引用队列ReferenceQueue联合使用,因为它的get函数返回值永远为null,因此无法用get函数判断它是否已被回收;
5) 用法:
String str = new String("abc");ReferenceQueue refQueue = new ReferenceQueue();PhantomReference ref = new PhantomReference(str, refQueue);
02. 四种引用的比较
强引用 > 软引用 > 弱引用 > 虚引用
引用类型 | 被回收的时间 | 用途 | 生存时间 |
---|---|---|---|
强引用 | 从来不会 | 对象的一般状态 | JVM停止运行时终止 |
软引用 | 内存不足时 | 对象缓存 | 内存不足时终止 |
弱引用 | 垃圾回收时 | 对象缓存 | GC运行后终止 |
虚引用 | 未知/瞬间 | 标记、哨兵 | 未知/瞬间 |
03. 引用队列(ReferenceQueue)
- 无实际存储结构,存储逻辑依赖于内部节点之间的关系来表达;
- 存储关联的且被GC的软引用、弱引用和虚引用。
04. 引用队列的代码示例
1) 目标对象MyObject
public class MyObject {public String name;public MyObject(String name){this.name = name;}@Overrideprotected void finalize() throws Throwable {System.out.printf("Finalizing Object %s", name);super.finalize();}}
2) 目标对象弱引用MyObjectWeakReference
public class MyObjectWeakReference extends WeakReference<MyObject>{public String name;public MyObjectWeakReference(MyObject referent, ReferenceQueue<MyObject> q) {super(referent, q);this.name = referent.name;}}
3) 调用类
public class ReferenceQueueTest {private static ReferenceQueue<MyObject> q = new ReferenceQueue<>();private static void checkQueue() {Reference ref;while ((ref = (Reference<MyObject>) q.poll()) != null) {System.out.println("In Queue: Weak Reference of " + ((MyObjectWeakReference) ref).name);System.out.println("Reference Object " + ref.get());}}public static void main(String[] args) {List<WeakReference<MyObject>> refList = new ArrayList<>();for (int i = 0; i < 3; i++) {refList.add(new MyObjectWeakReference(new MyObject("MyObject" + i), q));System.out.println("Created Weak Reference " + refList.get(i));}System.out.println("First Time Check.");checkQueue();System.gc();try {Thread.sleep(1000);} catch (InterruptedException ie) {}System.out.println("Second Time Check.");checkQueue();}}
4) 代码流程分析
i) 创建3个弱引用对象;
ii) 输出引用队列中的所有引用对象;
iii) 手动gc并等待其结束(这里是让线程睡眠1秒);
iv) 再次输出引用队列中的所有引用对象。
5) 代码输出
Created Weak Reference referencequeuetest.MyObjectWeakReference@15db9742
Created Weak Reference referencequeuetest.MyObjectWeakReference@6d06d69c
Created Weak Reference referencequeuetest.MyObjectWeakReference@7852e922
First Time Check.
Finalizing Object MyObject2
Finalizing Object MyObject1
Finalizing Object MyObject0
Second Time Check.
In Queue: Weak Reference of MyObject2
Reference Object null
In Queue: Weak Reference of MyObject1
Reference Object null
In Queue: Weak Reference of MyObject0
Reference Object null
6) 代码输出解析
i) 创建3个弱引用对象;
ii) 首次检查时,因为还没有发生GC,所以引用队列里什么都没有,没有任何输出;
iii) GC发生,MyObject的finalize方法被调用;
iv) 第二次检查时,因为已经发生GC,所以3个MyObjectWeakReference都在RefernceQueue里;
v) 因为已经发生GC,所以通过ref.get()得到的对象为null;
后记
GC(垃圾收集)部分内容也不少,我将这些知识点分为基础概念
、垃圾回收算法
、垃圾收集器
和引用
4个部分,便于阅读和查找。
相关文章:
【Java校招面试】基础知识(五)——GC
目录 前言一、基础概念二、垃圾回收算法三、垃圾收集器四、引用后记 前言 本篇主要介绍Java垃圾回收机制——GC的相关内容。 “基础知识”是本专栏的第一个部分,本篇博文是第五篇博文,如有需要,可: 点击这里,返回本专…...
使用CMake调用Makefile 项目
目录标题 基本示例Cmake传递lib给MakefileCmake传递参数给Makefile,比如make cleanWindows下使用Cmake调用Makefile 基本示例 如果项目是使用传统的Makefile构建的,并且您希望使用CMake调用这些Makefile,您可以使用CMake的add_custom_target…...
快速傅里叶变换FFT学习笔记
点值表示法 我们正常表示一个多项式的方式,形如 A ( x ) a 0 a 1 x a 2 x 2 . . . a n x n A(x)a_0a_1xa_2x^2...a_nx^n A(x)a0a1xa2x2...anxn,这是正常人容易看懂的,但是,我们还有一种表示法。 我们知道…...
如何下载安装驱动
1 打开浏览器 这里以Edge浏览器举例 第一步打开桌面上的Edge浏览器 如果您的桌面上没有 那么找到搜索栏 搜索Edge 然后打开 打开之后一般是这样 然后把我发送您的地址 驱动下载地址 https://t.lenovo.com.cn/yfeyfYyD (这个网址只是一个例子) 删除掉前…...
鸿蒙Hi3861学习四-Huawei LiteOS介绍
一、什么是LitesOS Huawei LiteOS是华为针对物联网领域推出的轻量级物联网操作系统,是华为物联网战略的重要组成部分,具备轻量级、低功耗、互联互通、组件丰富、快速开发等关键能力。基于物联网领域业务特征打造领域性技术栈,为开发者提供“一…...
Vue核心 收集表单数据 过滤器
1.14. 收集表单数据 收集表单数据: 若: ,则v-model收集的是value值,用户输入的就是value值。若: ,则v-model收集的是value值,且要给标签配置value值。若: 没有配置input的value属性,那么收集的就是checked(勾选 or 未…...
华为EC6108V9E/EC6108V9I_rk3228_安卓4.4.4_通刷_卡刷固件包
华为EC6108V9E/EC6108V9I_rk3228_安卓4.4.4_通刷_卡刷固件包-内有教程 特点: 1、适用于对应型号的电视盒子刷机; 2、开放原厂固件屏蔽的市场安装和u盘安装apk; 3、修改dns,三网通用; 4、大量精简内置的…...
数字化转型导师坚鹏:面向数字化转型的大数据顶层设计实践
面向数字化转型的大数据顶层设计实践 课程背景: 数字化背景下,很多企业存在以下问题: 不清楚大数据思维如何建立? 不清楚企业大数据分析方法? 不了解大数据应用成功案例? 课程特色: …...
day27_mysql
今日内容 零、 复习昨日 一、单表查询 二、多表联查 零、 复习昨日 1 DDL,DML,DQL是啥 DDL 数据定义语言(库,表,列)DML 数据操作语言(表内数据的操作增删改)DQL 数据查询语言(表内数据的查询&am…...
QwtPlotCurve使用说明
QwtPlotCurve是Qwt库中用于绘制曲线的类,可以在QwtPlot上绘制各种类型的曲线,如折线、样条线、散点等。以下是QwtPlotCurve的一些常用函数和使用说明: setSamples(const QPolygonF &samples):设置曲线的数据点,参数…...
JS逆向 -- 某平台登录加密分析
一、打开网站,使用账号密码登录 账号:aiyou123.com 密码:123456 二、通过F12抓包,抓到如下数据,发现密码加密了 三、加密结果是32位,首先考虑是md5加密。 四、全局搜索pwd,点击右上角…...
一分钟快速实现Flask框架的蓝图和视图
一分钟快速实现Flask框架的蓝图和视图 Flask是一个轻量级的Web应用框架,非常适合快速开发小型的Web应用。Flask框架使用蓝图(Blueprint)和视图(View)的概念来组织应用程序的代码。在本文中,我们将介绍如何…...
Mysql 约束练习【第13章_约束】
#第13章_约束 /* 基础知识 1.1 为什么需要约束? 为了保证数据的完整性! 1.2 什么叫约束?对表中字段的限制。 1.3 约束的分类: 角度1:约束的字段的个数 单列约束 vs 多列约束 角度2:约束的作用范围 列…...
java调用cmd命令
1.首先,我们需要了解一下 java是如何调用 cmd的: 6.在实际的开发中,我们有可能会遇到 java调用 cmd命令的情况: 7.对于一些特定的环境下,例如在嵌入式系统中,那么我们可以使用下面这种方式来调用 cmd命令&a…...
Qt音视频开发36-超时检测和自动重连的设计
一、前言 如果网络环境正常设备正常,视频监控系统一般都是按照正常运行下去,不会出现什么问题,但是实际情况会很不同,奇奇怪怪七七八八的问题都会出现,就比如网络出了问题都有很多情况(交换机故障、网线故障、带宽故障等),所以监控系统在运行过程中,还得做超时检测,…...
Reactor 第九篇 WebFlux重构个人中心,效果显著
1 重构背景 原有的开发人员早已离职,代码细节没人知道,经过了一段时间的维护,发现有以下问题: 个人中心系统的特征就是组装各个业务的接口,输出个人中心业务需要的数据,整个系统调用了几十个第三方业务线的…...
Vben Admin 自学记录 —— Drawer组件的基本使用及练习(持续更新中...)
Drawer 抽屉组件 对 antv 的 drawer 组件进行封装,扩展拖拽,全屏,自适应高度等功能。 Drawer相关使用及概念 练习 —— 在之前table基础上,添加查看功能,点击查看按钮,弹出抽屉显示单条表格数据…...
Android 9.0 根据包名默认授予app悬浮窗权限
1.概述 在9.0的设备开发中,对于在app中授予悬浮窗权限,也是通常用的功能,但在设备产品中预制app,需求要求默认授予悬浮窗权限, 就不需要在app中动态申请悬浮窗权限了,所以就来分析下这个实现这个功能 2.根据包名默认授予app悬浮窗权限的核心类 packages\apps\Settings\s…...
Swift中Data,String,[UInt8]的相互转换(6种互相转换)
var dataData() var array[UInt8]() var str"" //Data[UInt8] data.append(10) array[UInt8](data) print(array)//[10] //[UInt8]转Data array[1,2,3,4,5] dataData(array) print(data.count)//5 //Data转String data.removeAll() data.append(contentsOf:[0x31,…...
【微软Bing王炸更新】无需等待,人人可用,答案图文并茂,太牛了
🚀 AI破局先行者 🚀 🌲 AI工具、AI绘图、AI专栏 🍀 🌲 如果你想学到最前沿、最火爆的技术,赶快加入吧✨ 🌲 作者简介:硕风和炜,CSDN-Java领域优质创作者🏆&am…...
腾讯云的cdn怎么配置|腾讯云CDN配置教程
众所周知,WordPress系统不挂加速或者是服务器不好速度贼慢,所以要想办法解决访问速度的问题,经过我不断的研究腾讯云的CDN,因为我用的是zibll子比主题,不懂的就挂会导致无法使用第三方登录,因为有缓存导致一直不回调一直卡在那个登录界面和支付没反应要么出现二维码,要么…...
数据结构入门-顺序表链表
线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种实际中广泛使用多个数据结构,常见的线性表:顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构,也就说是连续的一条直线。…...
【AWS入门】AWS Lamda
目录 创建一个Lamda函数用Lamda函数控制启停EC2实例创建一台EC2实例创建角色创建lamda函数 使用Amazon EventBridge计划启停实例创建EventBridge 用户往S3存储桶上传图片文件,触发Lambda函数,将图片压缩并上传至另一个存储桶创建两个存储桶通过Cloudform…...
牛客刷SQL题Day5
SQL69 返回产品并且按照价格排序 select prod_name , prod_price from Products where prod_price between 3 and 6 select prod_name , prod_price from Products where 6>prod_price and prod_price >3 踩坑1: between......and.......包括边界。 踩坑2&am…...
【Errors】【计算机图形学】A-SDF复现的一点纠正记录
ICCV 2021的工作A-SDF,在跑的过程中可能是一些版我Run了这篇工作代码的Reconstruction,然后出现了一点小小的错误,记录如下。 问题一:对数据做直接修改导致出错(可能是不同的pytorch版本导致的?) 错误描述…...
Dockerfile创建镜像文件
Dockerfile Docker镜像原理 Linux文件系统有bootfs和rootfs两部分组成 Docker镜像由特殊文件系统叠加 最底端bootfs,使用宿主机bootfs 第二次时rootfs,被称为基础镜像 向上可以叠加其他镜像文件 同一文件系统能将多层整合成一层,隐藏了多层存在 镜像可以放置…...
javascript中的严格模式
认识严格模式: 在ECMAScript5标准中,JavaScript提出了严格模式的概念(Strict Mode): 严格模式很好理解,是一种具有限制性的JavaScript模式,从而是代码隐式的脱离了“懒散(sloppy)模…...
(二)【平衡小车制作】电机驱动(超详解)
一、硬件设计 1.直流减速电机 直流减速电机,即齿轮减速电机,是在普通直流电机的基础上,加上配套齿轮减速箱。齿轮减速箱的作用是,提供较低的转速,较大的力矩。 简单的来说,STM32分配两个IO口给一个…...
快速了解车联网V2X通信
自动驾驶拥有极其巨大的潜力,有可能改变我们的出行方式。它不仅有望永远改变车辆的设计和制造,还会永远改变汽车的所有权乃至整个交通运输业务。要实现全自动驾驶的目标,开发人员需要开发极为复杂的软件,软件中融入的人工智能(AI)…...
「Codeforces」D. Infinite Set
D. Infinite Set https://codeforces.com/contest/1635/problem/D 题目描述 你有一个由不同正整数组成的数组和一个无限集 S,现在你需要往集合 S 中塞入所有符合 x x x 条件的数。 x x x 的条件(满足其中任意一个即可): x a i …...
网站设计数据库怎么做/刷赞网站推广免费链接
命令1 & 命令2 & 命令3 ... (无论前面命令是否故障,照样执行后面) 命令1 && 命令2 && 命令3.... (仅当前面命令成功时,才执行后面) 命令1 || 命令2 || 命令3.... (仅当前面命令失败时.才执行后面)1、start 用来启动一…...
上海做设计公司网站/微信推广平台
Nginx的简介 Nginx(发音同 engine x)是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。由俄罗斯的程序设计师Igor Sysoev所开发࿰…...
郑州区块链数字钱包网站开发过程/一键制作免费网站的app
面向对象的特征 封装、继承、多态(、抽象) 封装 将某些逻辑或者是代码提取成某种对应的形式,这个提取的过程就是封装 封装包括:方法的封装、类的封装以及访问权限的封装。 访问权限设置主要体现为---将属性设置为私有的࿰…...
web网站漏洞扫描/网页设计模板网站免费
坑边闲话:如何在 Word 里添加代码片段呢?这个可以通过 VBA 编程实现,加上某些可以导出 HTML 格式的源码编辑器,基本无缝操作。但是 Word 插入代码并自动更新,真的是让人非常恼火,写完这篇文章,我…...
中小企业网站建设价格/全网营销整合推广
近日,微软的EF团队发布了一个针对SQL Server的Sample Database Provider Entity Framework 5,支持EF的一些新特性。 这个新的Sample Provider支持如下EF 5的新特性: Spatial typesTable Valued Functions带有多个结果集的存储过程然而&#x…...
自建网站的流程/网站域名查询工具
因为讨论下来,最终的DataProvider格式需要是一个json格式,所以我们还必须提供方法吧xml格式转为json格式,现在很多框架比如json-lib框架能很轻易的完成这个任务了。 1234567891011121314151617181920/*** This class will read the xml file …...