JVM加强
目录
JVM运行时的数据区(内存结构):
线程独享:
线程共享:
什么时候会内存溢出
JVM有哪些垃圾回收算法
GC如何判断对象可以被回收
典型的垃圾回收器
CMS:
G1:
类加载器和双亲委派机制:
类加载器
双亲委派机制
JVM中有哪些引用
虚引用
类加载的过程
JVM类初始化的顺序
对象的创建过程
对象头中有哪些信息
JVM的内存参数
GC的回收机制与原理
JVM运行时的数据区(内存结构):
线程独享:
- 虚拟机栈:每次调用方法时都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法对应的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧。
- 本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一。
- 程序计数器:保存指令执行的地址,方便线程切回后能够继续执行代码
线程共享:
- 堆内存:jvm进行垃圾回收的主要区域,存放对象相关信息,分为了新生代和老年代,内存比例一般为1:2,新生代的Eden区域内存不够的时候发生Minor GC,老年代内存不够的时候发生Full GC
- 方法区:存放有关类的信息。存放类信息、静态变量、常量、运行时常量池等信息。JDK1.8之前用永久代实现,JDK1.8之后采用元空间实现,元空间使用的是本地内存,而非存放在JVM结构当中
什么时候会内存溢出
堆内存溢出:
- 对象一直创建而不被回收的时候
- 加载的类越来越多的时候
- 虚拟机栈的线程越来越多的时候(如果应用程序创建了过多的线程,并且每个线程都创建了大量的对象,堆内存的使用量就会增加。)
栈溢出:
- 方法调用次数太多,一般为递归调用不当造成
JVM有哪些垃圾回收算法
标记清除算法:标记不需要回收的对象(首先会进行标记阶段。从根对象(如全局变量、栈中的引用等)开始,通过可达性分析或其他方式,遍历对象图谱,将所有与根对象可达的对象标记为存活对象),然后清除没有标记的对象,这种方式会造成许多内存碎片。
复制算法:将内存将内存分为两块,只使用一块,进行垃圾回收的时候,先将存活的对象复杂到另一块区域,然后在清空之前的区域。(新生代中的from区和to区用的就是类似这种算法)
标记整理算法:与标记清除算法类似,但是在标记之后,将存活的对象向一方移动,然后清除边界外的垃圾对象。应用于老年代的垃圾回收
GC如何判断对象可以被回收
引用计数法:为每个对象添加引用计数器,当引用个数为0的时候判定为可以被回收,但存在有两个对象相互引用导致无法回收的问题
可达性分析算法:从GCRoots开始向下搜索,搜索过的路径称为引用链,对于GCRoots没有任何引用的对象,则判定可以被回收
什么是GCRoots:
在Java中,以下几种情况可以被定义为GCRoots:
- 栈中的引用:包括局部变量、方法参数和操作数栈中的引用。
- 静态变量:属于类的静态字段,因为它们始终存在于内存中。
- JNI(Java Native Interface)引用:JNI是Java与本地代码交互的机制,JNI引用指向在本地代码中创建的Java对象。
- 虚拟机内部的引用:包括虚拟机常量引用和系统类加载器等特殊类的引用。
- 线程相关引用:例如当前活动线程的引用或线程的任务队列中的引用。
典型的垃圾回收器
CMS:
以最小的停顿时间为目标,只运行在老年代的垃圾回收器,使用标记清除算法,可以并发收集(标记和清除阶段)。
CMS回收器采用了一种并发标记清除算法,具有以下几个主要特点:
- 并发:CMS回收器的标记和清除阶段是与应用程序线程并发执行的。它尽量减少垃圾收集期间的停顿时间,以提供更好的响应性能。在标记阶段,由于与应用程序线程同时运行,可以减少暂停时间。
- 低停顿:CMS回收器的主要目标是减少应用程序的停顿时间。通过在标记和清除阶段的并发执行,可以避免全局停顿。但为了达到低停顿的效果,CMS回收器会牺牲一部分吞吐量。
- 分代收集:CMS回收器主要关注老年代的回收,因为老年代通常包含更多的存活对象。对于新生代,CMS回收器通常与其他回收器(如Serial或ParNew)结合使用。
- 标记-清除算法:CMS回收器采用标记-清除算法,首先进行并发标记,然后进行并发清除。标记过程中使用“标记”位来标记存活对象,而清除阶段会清除所有未被标记的对象,释放内存空间。
- 空间碎片:CMS回收器在并发清除阶段不会移动对象,这可能导致内存碎片的产生。为了解决内存碎片问题,CMS回收器提供了“空闲列表”来尽量利用连续的内存空间。
需要注意的是,CMS回收器适用于具有大内存、长时间运行的应用程序,并且强调减少停顿时间。但由于并发执行和空间碎片的特点,它可能会导致一些额外的CPU开销,并且在极端情况下可能会触发Full GC。
G1:
JDK1.9之后的默认的垃圾回收器,注重响应速度,支持并发,采用标记整理+复制算法回收内存,使用可达性分析判断对象是否应该被回收。
G1回收器具有以下几个主要特点:
- 区域化的堆布局:与传统的分代堆模型不同,G1将堆划分为多个大小相等的区域。每个区域可以是Eden、Survivor、Old或Huge Region之一。这种区域化的布局有助于对垃圾回收的控制和优化。
- 并发标记:G1回收器使用并发标记算法来标记存活对象。在标记阶段,应用程序线程与垃圾收集线程并发执行,从而减少了停顿时间。
- 多线程并行处理:G1回收器在标记和清除阶段使用多个线程来并行处理垃圾回收任务,以提高回收效率。
- 基于回收价值的优先级:G1回收器根据每个区域内的回收价值来选择优先回收的区域,这样可以优先回收那些包含大量垃圾的区域,从而提高回收效率。
- 整理空闲:G1回收器在执行垃圾回收时会进行部分或完全的内存整理,以减少内存碎片,提高内存使用效率。
- 可预测的停顿时间:G1回收器通过将回收任务划分为多个短暂的回收周期来控制停顿时间。用户可以通过配置参数来指定期望的最大停顿时间,G1回收器会尽量在这个时间范围内完成垃圾回收。
G1回收器适用于具有大内存、需要低延迟和可预测停顿时间的应用程序。相对于CMS回收器,G1回收器提供了更好的吞吐量和停顿时间控制。但与此同时,它也引入了一些额外的开销,如内存开销、CPU开销和GC负载。
类加载器和双亲委派机制:
类加载器
类加载器负责从文件系统、网络或其他来源加载类的字节码,并将其转换为JVM可以理解的格式。JVM支持多个类加载器,每个加载器都负责加载特定类型的类。
从父加载器到子类加载器分别为:
BootStrapClassLoader(启动类加载器) 加载路径——JAVA_HOME/jre/lib
ExtensionClassLoader(扩展类加载器) 加载路径——JAVA_HOME/jre/lib/ext
ApplicationClassLoader (应用程序类加载器) 加载路径——classPath
双亲委派机制
双亲委派机制是类加载器的一种工作方式,它通过层级关系进行加载类的过程。当一个类加载器需要加载一个类时,它首先将这个任务委派给它的父类加载器,父类加载器再将任务委派给它的父类加载器,直至最终委派给顶层的启动类加载器。只有当父类加载器无法加载这个类时,子加载器才会尝试自己加载。
优势
-
安全性: 假设有一个恶意代码想要替换Java核心API类中的某个类,比如
java.lang.String
。由于双亲委派机制的存在,该加载请求会首先被委派给启动类加载器进行处理。启动类加载器负责加载核心Java API,并将其保护起来,以防止被篡改或替换。因此,即使存在恶意代码尝试加载java.lang.String
类,由于该类已由启动类加载器加载,恶意代码的加载请求将被拒绝。 -
避免重复加载: 假设我们有两个不同的类加载器,分别是
ClassloaderA
和ClassloaderB
,它们都可以加载同一个类com.example.MyClass
。如果没有双亲委派机制,当需要加载com.example.MyClass
时,ClassloaderA
和ClassloaderB
可能会分别加载自己的版本,导致在JVM中存在多个com.example.MyClass
类的副本,可能会引发类冲突和不一致的问题。而通过双亲委派机制,当ClassloaderA
和ClassloaderB
都遵循委派机制,它们都会将加载请求委派给父类加载器,最终由启动类加载器加载该类。这样,只有一个版本的com.example.MyClass
类会被加载,避免了重复加载和冲突。 -
存在性检查: 当一个类加载器需要加载某个类时,它会先询问父类加载器是否已经加载过该类。如果父类加载器已经加载了该类,那么子类加载器就无需再次加载,直接使用父类加载器加载的类。这样做可以提高加载效率,避免不必要的重复加载操作。例如,当一个应用程序使用
Class.forName("com.example.MyClass")
动态加载某个类时,首先会询问应用程序类加载器(Application Class Loader)是否已经加载了该类。如果已经加载,则可以直接使用,而不需要再次加载。
JVM中有哪些引用
在JVM(Java虚拟机)中,引用是指对对象的间接访问。引用允许我们操作和处理对象,而无需直接访问对象本身。引用是一种对内存中对象的标识,通过引用可以定位和操作存储在堆中的对象。
引用在Java中有不同的类型,包括强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。它们的主要区别在于对垃圾回收的影响和生命周期的长短。
- 强引用:new的对象。哪怕内存溢出也不会回收
- 软引用:只有内存不足时才会回收
- 弱引用:每次垃圾回收都会回收
- 虚引用:必须配合引用队列使用,一般用于追踪垃圾回收动作、
虚引用
当一个对象只有虚引用指向它时,无论何时垃圾回收器决定回收该对象,它都可以立即进行回收。在回收对象之前,垃圾回收器会将这个对象放入一个特殊的引用队列中。
使用虚引用的好处是,我们可以通过检查引用队列来确定哪些对象已经被回收。这样,我们可以在对象被回收时采取一些额外的操作或记录。例如,我们可以在对象被回收时进行资源清理或日志记录。
要注意的是,虚引用本身并不能保持对象的存活,也不能通过虚引用来访问对象。它仅仅是在对象被回收前提供了一个通知的机制,以便我们可以观察和处理对象的回收过程。
所以,虚引用的主要作用是帮助开发者了解对象的回收情况,并在需要时执行一些附加的操作。
类加载的过程
(1)加载:将字节码通过二进制的形式转化到方法区中的运行数据区当中。
(2)连接:
- 验证:验证字节码文件的正确性
- 准备:正式为类变量在方法区中分配内存,并设置默认的初始值,final类型的变量是在编译时就赋值
- 解析:将常量池中的符号引用(如类的全限定名)解析为直接引用(类再实际内存中的地址)
(3)初始化:执行类构造器(不是常规的那种类的构造方法),为静态变量赋初值并初始化静态代码块。
JVM类初始化的顺序
父类静态代码块和静态成员变量-》
子类静态代码块和静态成员变量-》
父类代码块和普通成员变量-》
子类代码块和普通成员变量-》
子类构造方法
对象的创建过程
(1)检查类是否被加载,如果没加载就先加载类
(2)为对象在堆中分配内存,使用CAS方式分配,防止在为A进行内存分配的时候,执行当前地址的指针还没有来得及修改,对象B就拿来分配内存(让A分配完了再让B分配)
(3)初始化,将对象中的属性都分配为0值或者为null
(4)设置对象头
(5)为属性赋值和执行构造方法
对象头中有哪些信息
1.Markword
- 锁信息
- hashcode
- GC标记
2.类指针KlassPointer
JVM的内存参数
-Xmx[]:堆空间最大内存
-Xms[]:堆空间最小内存,一般设置成跟堆空间最大内存一样的
-Xmn[]:新生代的最大内存
-xx:[survivorRatio=3]:Eden区与from+to区的比例为3:1,默认为4:1
-xx[use 垃圾回收器名称]:指定垃圾回收器
-xss:设置单个线程栈大小
一般设堆空间为最大可用物理地址的百分之80
GC的回收机制与原理
GC的目的实现内存的自动释放,使用可达性分析算法判断对象是否可被回收,采用了分代回收的思想,将堆分为了新生代、老年代;新生代中采取了复制算法,老年代中采用了标记整理算法,当新生代内存不够的时候发生Minor GC,老年代内存不够的时候发生Full GC
相关文章:
JVM加强
目录 JVM运行时的数据区(内存结构): 线程独享: 线程共享: 什么时候会内存溢出 JVM有哪些垃圾回收算法 GC如何判断对象可以被回收 典型的垃圾回收器 CMS: G1: 类加载器和双亲委派机制&a…...
解决Oracle中XML插入数据时的空格问题
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
微服务中间件--分布式事务
分布式事务 a.理论基础1) CAP定理2) BASE理论 b.Seata1) XA模式1.a) 实现XA模式 2) AT模式3) TCC模式3.a) 代码实现 4) Saga模式5) 四种模式对比6) TC的异地多机房容灾架构 a.理论基础 1) CAP定理 分布式系统有三个指标: Consistency(一致性ÿ…...
计算机网络(9) --- 数据链路层与MAC帧
计算机网络(8) --- IP与IP协议_哈里沃克的博客-CSDN博客IP与IP协议https://blog.csdn.net/m0_63488627/article/details/132155460?spm1001.2014.3001.5502 目录 1.MAC帧 1.MAC地址 2.MAC帧报头 3.资源碰撞 4.MTU 1.对IP协议的影响 2.对UDP协议…...
【学会动态规划】环绕字符串中唯一的子字符串(25)
目录 动态规划怎么学? 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后: 动态规划怎么学? 学习一个算法没有捷径,更何况是学习动态规划, 跟我…...
CNN卷积详解(三)
一、卷积层的计算 4 ∗ * ∗ 4的输入矩阵 I I I 和 3 ∗ * ∗ 3 的卷积核 K K K: 在步长(stride)为 1 时,输出的大小为 ( 4 − 3 1 ) ( 4 − 3 1) 计算公式: ● 输入图片矩阵 I I I 大小: w w w w ww ●…...
使用 Amazon Redshift Serverless 和 Toucan 构建数据故事应用程序
这是由 Toucan 的解决方案工程师 Django Bouchez与亚马逊云科技共同撰写的特约文章。 带有控制面板、报告和分析的商业智能(BI,Business Intelligence)仍是最受欢迎的数据和分析使用场景之一。它为业务分析师和经理提供企业的过去状态和当前状…...
CentOS 上快速安装包管理工具Conda
要在 CentOS 上安装 Conda,您可以按照以下步骤进行操作: 1. 下载 Miniconda 或 Anaconda 安装脚本: Miniconda:适用于轻量级安装的 Miniconda 版本。 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.…...
opencv-手势识别
# HandTrackingModule.py import cv2 import mediapipe as mpclass HandDetector:"""使用mediapipe库查找手。导出地标像素格式。添加了额外的功能。如查找方式,许多手指向上或两个手指之间的距离。而且提供找到的手的边界框信息。"""…...
【SA8295P 源码分析】10 - HQX Display(OpenWFD)qcdisplaycfg_ADP_STAR_LA.xml 配置文件解析
【SA8295P 源码分析】10 - HQX Display(OpenWFD)qcdisplaycfg_ADP_STAR_LA.xml 配置文件解析 一、HQX Display 介绍1.1 OpenWF Display Driver二、HQX Display 配置文件参数解析2.1 qcdisplaycfg.xml 配置文件2.1 配置两个 DPUs in QNX2.1.1 配置 graphics_ADP_STAR.conf : …...
达梦数据库权限和预定角色介绍
概述 本文对达梦数据库数据库和对象权限及DM预定义角色及角色创建进行介绍。 1.权限管理 用户权限有两类:数据库权限和对象权限。 数据库权限主要是指针对数据库对象的创建、删除、修改的权限,对数据库备份等权限。 数据库权限一般由 SYSDBA、SYSAU…...
Python编程从入门到实践_8-8 用户的专辑_答案
Python编程从入门到实践_8-8 用户的专辑_答案 我也看了一些其他人的答案,很多的答案存在问题,每次调用函数 make_album() 后生成一个专辑字典会覆盖上次调用函数 make_album() 生成的字典,不符合题意。 我采取的解决方案是添加一个空列表 …...
HummingBird 基于 Go 开源超轻量级 IoT 物联网平台
蜂鸟(HummingBird) 是 Go 语言实现的超轻量级物联网开发平台,包含设备接入、产品管理、物模型、告警中心、规则引擎等丰富功能模块。系统采用GoLang编写,占用内存极低, 单物理机可实现百设备的连接。 在数据存储上&…...
10.小程序样式
样式 css部分样式不支持,并且添加了rpx属性,小程序开发的时候应该使用rpx,而不是px,因为rpx是将移动端的屏幕大小分为750份,会自动按设备的大小去适配;我们在开发时应该以iphone6为基准的设备进行开发&…...
Flink 流式读写文件、文件夹
文章目录 一、flink 流式读取文件夹、文件二、flink 写入文件系统——StreamFileSink三、查看完整代码 一、flink 流式读取文件夹、文件 Apache Flink针对文件系统实现了一个可重置的source连接器,将文件看作流来读取数据。如下面的例子所示: StreamExe…...
【SA8295P 源码分析】64 - QNX 与 Android GVM 显示 Dump 图片方法汇总
【SA8295P 源码分析】64 - QNX 与 Android GVM 显示 Dump 图片方法汇总 一、QNX侧1.1 surfacedump 功能1.2 screenshot 功能二、Android GVM 侧2.1 screencap -p 导出 PNG 图片2.2 screencap 不加 -p 参数,导出 RGB32 图片2.3 dumpsys SurfaceFlinger --display-id 方法系列文…...
字符串旋转(1)
目录 编辑 题目要求😍: 题目内容❤: 题目分析📚: 主函数部分📕:编辑 方法一🐒: 方法二🐒🐒: 方法三🐒…...
【SA8295P 源码分析】13 - Android GVM 虚拟机 QUPv3 UART / SPI / I2C功能配置及透传配置
【SA8295P 源码分析】13 - Android GVM 虚拟机 QUPv3 UART / SPI / I2C功能配置及透传配置 一、QUP v3 介绍二、QUP v3 UART 功能配置2.1 TrustZone 域 Uart 资源权限配置:以 QUPV3_0_SE2 为例2.2 QNX Host 域关闭 Uart 资源:以 QUPV3_0_SE2 为例2.3 Android Kernel 域使能 U…...
STM32 F103C8T6学习笔记10:OLED显示屏GIF动图取模—简易时钟—动图手表的制作~
今日尝试做一款有动图的OLED实时时钟,本文需要现学一个OLED的GIF动图取模 其余需要的知识点有不会的可以去我 STM32 F103C8T6学习笔记 系列专栏自己查阅把,闲话不多,直接开肝~~~ 文章提供源码,测试工程下载,测试效…...
大数据课程K3——Spark的常用案例
文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Spark的常用案例——WordCount; ⚪ 掌握Spark的常用案例——求平均值; ⚪ 掌握Spark的常用案例——求最大值和最小值; ⚪ 掌握Spark的常用案例——TopK; ⚪ 掌握Spark的常用案例…...
85-最大矩阵
题目 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。 示例 1: 输入:matrix [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,…...
8.3 【C语言】通过指针引用数组
8.3.1 数组元素的指针 所谓数组元素的指针就是数组元素的地址。 可以用一个指针变量指向一个数组元素。例如: int a[10]{1,3,5,7,9,11,13,15,17,19}; int *p; p&a[0]; 引用数组元素可以用下标法,也可以用指针法…...
基于Flink CDC实时同步PostgreSQL与Tidb【Flink SQL Client模式下亲测可行,详细教程】
文章目录 一、PostgreSQL作为数据来源(source),由flink读取1.postgre安装与配置2.flink安装与配置3.flink cdc postgre配置3.1 postgre配置(for flink cdc)3.2 flink cdc postgres的jar包下载 4.flink cdc postgre测试…...
Vue-5.编译器Idea
Vue专栏(帮助你搭建一个优秀的Vue架子) Vue-1.零基础学习Vue Vue-2.Nodejs的介绍和安装 Vue-3.Vue简介 Vue-4.编译器VsCode Vue-5.编译器Idea Vue-6.编译器webstorm Vue-7.命令创建Vue项目 Vue-8.Vue项目配置详解 Vue-9.集成(.editorconfig、…...
qiuzhiji3
本篇想介绍一下慧与,这里的工作氛围和企业文化令人难忘,希望更多人了解它 也想探讨一下不同的文化铸就的不同企业,究竟有哪些差别。 本篇将从我个人角度出发描述慧与。 2022/3/16至2023/7/31 本篇初次写于2023年8月20日 说起来在毕业之前那段…...
JVM——垃圾回收(垃圾回收算法+分代垃圾回收+垃圾回收器)
1.如何判断对象可以回收 1.1引用计数法 只要一个对象被其他对象所引用,就要让该对象的技术加1,某个对象不再引用其,则让它计数减1。当计数变为0时就可以作为垃圾被回收。 有一个弊端叫做循环引用,两个的引用计数都是1ÿ…...
QT TLS initialization failed问题(已解决) QT基础入门【网络编程】openssl
问题: qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed 这个问题的出现主要是使用了https请求:HTTPS ≈ HTTP + SSL,即有了加密层的HTTP 所以Qt 组件库需要OpenSSL dll 文件支持HTTPS 解决: 1.加入以下两行代码获取QT是否支持opensll以…...
SpringMVC之获取请求参数
文章目录 前言一、通过ServletAPI获取二、通过控制器方法的形参获取请求参数三、注解1.RequestParam2.RequestHeader3.CookieValue前面的代码总和:4.通过POJO获取请求参数 三、解决获取请求参数的乱码问题总结 前言 下面用到了thymeleaf,不知道的可以看…...
【无标题】QT应用编程: QtCreator配置Git版本控制(码云)
QT应用编程: QtCreator配置Git版本控制(码云) 感谢:DS小龙哥的文章,这篇主要参考小龙哥的内容。 https://cloud.tencent.com/developer/article/1930531?areaSource102001.15&traceIdW2mKALltGu5f8-HOI8fsN Qt Creater 自带了git支持。但是一直没…...
JVM面试题-2
1、有哪几种垃圾回收器,各自的优缺点是什么? 垃圾回收器主要分为以下几种:Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1; Serial:单线程的收集器,收集垃圾时,必须stop the worl…...
wordpress什么是分页/网络营销渠道名词解释
apt-get remove wineapt-get remove wine-binrm -rf /root/.wine/ 转载于:https://www.cnblogs.com/dzxs/p/dzxsly.html...
做网站 分工/全网推广平台推荐
1.基于贫血模型的传统开发模式 // BO,不包含业务逻辑 // 虚拟钱包 public class VirtualWalletBo {// 省略 getter/setter/constructor 方法 private Long id; private Long createTime; private BigDecimal balance; }// Service public class VirtualWalletSer…...
专做程序员招聘的网站/软文平台发布
1.第一个Bug的故事 有人把软件产品和药品并称为世界上两种无法根除自身的缺陷却被允许公开合法销售的产品! 随着软件各种Bug的增多,严重的质量事故也随之增多,人们对抗Bug的态度日益强硬。 1945年9月某天,Hopper 正在埋头工作在一…...
崂山区城乡建设局网站/网站查询器
Resharper是一款很优秀的重构工具,已经习惯了Resharper快捷键,利用Resharper做重构,TDD开发,很爽。唯一缺点就是低配置机器上速度很慢,容易拖死VS, 为此我我专门把我的本本换成6G内存,现在感觉顺…...
陕西省人民政府采购网/曲靖seo
本文同步发布于 个人博客 前言 上周周赛因为忘记起床导致没打TAT 本次周赛战绩: rk5,总完成时间20min,还有奖品,好耶! A 2129.将标题首字母大写 题意 给出一个包含若干个单词的句子,把所有字母变为小写字母&#…...
王野天 演员/北京seo优化排名推广
1.应用场景 主要用于了解App架构的演进过程,以及对比端上架构与后端架构的区别,联系。 2.学习/操作 1.文档阅读 49 | 谈谈App架构的演进-极客时间 [转]Web 研发模式演变——玉伯 - 知乎 2.整理输出 49 | 谈谈App架构的演进-极客时间 专栏截止到上一期&a…...