淘宝订单列表Fragment转场动画卡顿解决方案
如何应对产品形态与产品节奏相对确定情况下转变为『在业务需求与产品形态高度不确定性的情况下,如何实现业务交付时间与交付质量的确定性』。我们希望通过混合架构(Native 业务容器 + Weex 2.0)作为未来交易终端架构的重要演进方向,在 Native 容器侧充分发挥原生语言的性能优势、常驻 App 的调控与管控能力、手势识别与交互优势来解决体验问题。本专题《淘宝交易终端架构探索》是我们摸索出的部分实践总结,欢迎大家一起交流进步。
第一篇:《Weex购物车长列表横滑操作优化“编年史”》
第二篇:《淘宝页面首帧优化的经验和心得》
第三篇:《淘宝App交易链路终端混合场景体验探索》
第四篇:《淘宝订单列表Fragment转场动画卡顿解决方案》(本篇)
第五篇:《探索淘宝购物车SurfaceView闪黑的解决方案》(待发布)
背景
我们知道,在Android系统中Fragment的生命周期相对于Activity更加轻量级,Activity需要处理更多复杂的状态转换和资源管理,而Fragment只是在Activity之上叠加的一层视图组件。因此,Fragment的初始化和管理所耗费的系统资源和时间通常较少。直观来说,通过Fragment替换Activity,我们可以实现更短的点击响应耗时和更少的内存占用。
然而,使用Fragment同样也面临着一些问题,例如APM埋点错乱、复杂的状态管理、Fragment嵌套管理等问题。今天我们主要来看Fragment转场动画卡顿问题。
现状分析
在Activity场景下订单列表首屏渲染流程大致如下所示:
可以看到Activity的缓存渲染被我们延后到动画开始之后,这样可以大大缩短点击响应耗时。然而当我们保持渲染流程不变仅仅将页面容器从Activity切换为Fragment之后就会发现原本丝滑流畅的转场动画变得非常卡顿:
我们再来看看在低端机Y50上Fragment冷启动画的Trace情况:
从Trace中我们可以看出,整个动画过程中UI线程渲染首帧就占据了大半的时间,这正是因为我们将首屏的渲染放在了动画开始之后,阻塞了Fragment动画帧的绘制,导致第一帧动画就已经出现卡顿。此时动画剩余时间已经不多,后续动画则不可避免地出现丢帧现象。
Fragment转场动画卡顿之谜
我们先来了解下为什么Fragment动画会卡顿而Activity则不会。简单来说就是:Activity转场动画不会被主线程阻塞,而Fragment动画则会被主线程任务阻塞。
1. 系统级管理 vs 应用级管理:
Activity转场动画:由Android系统的WindowManager组件进行管理。WindowManager在系统级别提供了优化的动画管理。因此,无论主线程在此期间进行何种UI绘制,系统层面的动画渲染都不受影响。
Fragment转场动画:通常由应用程序自行管理,并且动画是在主线程上执行的。当主线程被其他UI操作阻塞时(例如绘制复杂UI视图),会直接影响到Fragment的动画流畅性。
2. 硬件加速的不同深度:
Activity动画:由于Activity的转场是由系统窗口管理器处理,它们可以在更深层次上利用硬件加速,确保动画的流畅性即使在高负荷情况下也能维持。
Fragment动画:虽然也可以利用硬件加速,但由于其动画逻辑和生命周期管理在应用层实现,容易受到主应用线程任务的影响,特别是当没有充分利用异步处理和硬件加速时。
3. 动画与绘制同步机制:
Choreographer和VSync(VerticalSynchronization)的作用:系统级动画(如Activity切换)与屏幕的垂直同步(VSync)高度同步,使用Choreographer来安排绘制和动画,确保高效的刷新率。在Activity动画期间,绘图和动画事件能更加自然地与设备刷新率保持同步。
Fragment同步机制不强:Fragment管理器缺少像Choreographer这样的系统级优化机制来协调动画和绘图更新,这使得Fragment动画更容易在UI线程繁重时出现问题。
丝滑转场探索
▐ 1. 动画延后
方案简介
顾名思义,动画延后就是在主线程的耗时任务即首屏渲染完成后再进行转场动画,此时主线程空闲,动画则不会卡顿。
具体实现
取消缓存渲染延后,在Activity里我们将缓存渲染延后到了动画开始之后,在Fragment中我们在onCreate阶段就执行缓存渲染
转场动画延迟。在低端机冷启时,给动画设置一个offset值。
然而在实践过程当中我们发现简单的动画延后并不能完全解决问题,往往在动画后段仍然会出现卡顿,这是因为真实请求回来后会进行页面二刷,而此时动画如果没有结束则依然会出现卡顿。
为此,我们可以将二刷也延后:
在Fragment自定义动画中设置动画结束监听
请求回来后循环校验当前动画是否完成
动画延后方案渲染流程:
效果展示
动画延后方案的Trace如下图所示:
从Trace中我们可以看出,动画帧基本没有出现卡顿,因为动画期间主线程并没有耗时任务。
结论
通过以上方法我们虽然可以解决动画卡顿的问题,但是很显然这并不是一个优雅的方案:
代码实现逻辑较为恶心,需要获取精确的一刷渲染结束时间点,同时二刷需要循环等待动画结束,后期很难维护
动画延后拉长了点击响应耗时,二刷延后又拉长了可交互耗时,得不偿失
一开始我们选择Fragment方案最主要的原因就是为了减少点击响应耗时,在中高端机上采用这种方案无可厚非,然而在低端机上首屏渲染本就耗时,如果再将动画延后至首屏渲染完成后那么点击响应耗时势必增加,这样就和我们的目标背道而驰了。
▐ 2. 分帧渲染
方案简介
既然我们已经知道动画卡顿的直接原因是首帧绘制耗时太长挤占了整个动画时长,从而导致后续动画时间不足出现大量丢帧、卡顿的现象。那么如果我们将UI线程首帧的渲染任务拆分成很多小块的任务,控制每一小段任务的执行耗时都能够在16ms的帧间隔内完成,那么UI线程渲染就能够和动画实现帧同步。
具体实现
在订单列表场景下,列表页通常由顶部的header区域和下方的滚动列表body区域组成。body区域是一整个RecycleView,而RecycleView适配器中的数据是一个List<T>。在正常的渲染流程中我们会将请求返回的一页数据解析、整理好一次性交给RV,然后RV会在当前页面完全渲染完成后一次性上屏,这一点从前面的Trace中也能看出
根据分帧渲染的思路,我们考虑将List中的数据均匀分成适当的等份,在每一个帧间隔期间设置一段数据。
首先在转场动画开始前先完成header渲染,然后分帧渲染单段数据。
这里的分帧渲染设置依赖于Android的Choreographer.FrameCallback帧回调,伪代码如下所示:
Choreographer.FrameCallback frameCallback = new Choreographer.FrameCallback() {@Overridepublic void doFrame(long frameTimeNanos) {// 当所有分段数据都设置后移除帧回调if (...) {Choreographer.getInstance().removeFrameCallback(this);return;}// 分段设置数据getAdapter().setData(bodyList.subList(a, b));getAdapter().notifyItemRangeChanged(itemCount, range);// 注册下一帧回调Choreographer.getInstance().postFrameCallback(this);}
};
// 注册当前帧回调
Choreographer.getInstance().postFrameCallback(frameCallback);
通过监听帧回调,将List数据分段设置我们可以实现按照帧维度进行精细化的渲染。
效果展示
从视屏中我们可以看出,分帧渲染后RecycleView的内容确实从上到下分段上屏,卡顿也会明显好很多。
Trace对比
分帧渲染Trace
正常渲染Trace
从Trace中我们可以看出,分帧渲染将首屏首帧这样一个完整的耗时任务分成了多个子任务,再结合Android的帧回调机制,在动画帧间隔期间完成每个UI线程子任务。相较于正常的渲染流程,分帧渲染明显减少了丢帧数从而达到减少卡顿的目的。
结论
实际上,分帧渲染相对于原始的动画起到了补帧的效果,但丢帧问题仍然存在。这是因为即便将RV的数据分成最小单位(即每份数据只有一个dx模板)也会出现渲染耗时超过16ms的情况,尤其是在低端机冷启首进的情况下。一旦最小渲染单位的渲染耗时超过了动画的帧间隔就无法实现完美的帧同步,从而再导致动画丢帧、卡顿。
▐ 3. 异步转场动画框架
分帧方案实现较为复杂且效果不达预期,在这之后架构组的成兆老师提供了一套新的思路:异步动画。既然Fragment动画卡顿是因为主线程阻塞导致的,那么我们是否可以在异步线程进行独立绘制呢?顺着这个思路我们很容易联想到了Android的SurfaceView。
SurfaceView简介
SurfaceView 是 Android 提供的一种视图类,允许在一个独立的绘图表面上进行绘制操作。相对于普通的View,SurfaceView 提供一个独立的 Surface,用于在自己的线程中进行绘图操作。这意味着可以在后台线程上绘制,避免占用主线程资源,从而减轻主线程的负载,提升整体渲染性能。
SurfaceView 的核心组件
Surface: 一个用于绘制的渲染目标,本质上是内存中的一段绘图缓冲区,底层通过 SurfaceFlinger进行管理。
SurfaceHolder: Surface的持有者,提供对 Surface 的访问和控制,并且可以注册回调来监听 Surface 的生命周期变化。SurfaceHolder的所有回调都在主线程
SurfaceView: 拥有独立绘图层的特殊View,由于继承自 View,它负责管理 Surface 和 SurfaceHolder,并分发生命周期事件。
SurfaceView 异部渲染原理分析
SurfaceView继承自View,本质上它也是个View。我们知道,普通的View对WMS并不可见,而是通过顶层的DecorView这个桥梁来与WMS完成交互,WMS会为这个根视图分配一个WindowState对象用来管理视图的显示属性。同时,在SF(Surface Flinger)中DecorView会拥有一个Layer,用来在屏幕上合成并最终展示视图。
而SurfaceView的特殊之处就在于,它拥有自己的Surface,这是用于直接绘图的缓冲区,而这个Surface在WMS中也注册了一个自己的WindowState,并且在SF中也会有对应的Layer。也就是说,虽然SurfaceView仍属于宿主窗口View hierachy中的一个视图节点,但在Server端(WMS和SF),它与宿主窗口却是分离的。得益于这种特殊的设计,SurfaceView能够独立参与窗口管理,享有与DecorView类似的管理机制,并且它被允许在不干扰UI线程的情况下,由专有线程高效地进行图形渲染。
方案简介
既然SurfaceView具备独立渲染的能力,不会被主线程阻塞,那么考虑用SurfaceView来完成动画,这样即使在动画期间主线程任务繁忙也不会影响SurfaceView的动画效果。
SurfaceView + 快照
在打开Fragment并且需要开始动画之前,创建一个SurfaceView,并将事先准备好的占位图即 placeholder添加到SurfaceView上,当动画开始后让这个SurfaceView来展示动画,等Fragment渲染完成后再隐藏这个SurfaceView。
具体实现
快照获取:即placeholder资源获取,在订单列表场景下,可以在请求回来二刷的时机通过注册ViewTreeObserver.OnGlobalLayoutListener 监听,在布局完成后通过系统方法截取当前首屏,并将其持久化存储到本地。这里获取快照推荐使用Android 8.0(API 26)后提供的 PixelCopy.request() 方法,如果使用View.draw() 方法可能导致图片圆角缺失、Weex组件无法获取快照等问题。
Nav阶段异步获取placeholder,并将其读取到内存中,避免后续在主线程进行耗时的IO操作
在下一次进入订单列表fragment.onCreate阶段,创建SurfaceView并将内存中的placeholder资源设置给SurfaceView
开始执行SurfaceView的动画,此时主线程正在渲染Fragment的真实首屏
Fragment首屏渲染完成,隐藏SurfaceView
效果展示
从Trace中我们可以看到即使在主线程处于繁忙状态下,SurfaceView的动画帧却不受影响。
在订单列表场景下,页面元素相对稳定,采用这套方案可以在最大程度缩减点击响应耗时的同时保证转场动画丝滑流畅,并且在动画期间不存在loading状态,这对于用户体验来说是巨大的提升。当然在使用这套方案的同时也需要注意一些隐藏的风险。
风险
▐ ANR
快照资源从本地存取的IO操作存在ANR风险,需要在异步异步线程完成。
▐ 获取快照阻塞主线程
对于快照资源获取的时机需要根据具体业务场景来判断,太早可能导致页面元素不全,太晚则可能影响可交互时长。
▐ 存储资源
快照存在本地,对于本地存储资源的占用需要额外注意。
团队介绍
我们是淘天集团-基础交易终端团队,一支专注于手淘APP交易域(购物车、下单、订单、物流等)业务研发和体验优化的技术团队。在丰富的业务场景下,我们通过持续的技术探索、不断的创新突破,给数亿用户提供极致可靠的交易保障、极致流畅的操作交互以及极致顺滑的购物体验。
¤ 拓展阅读 ¤
3DXR技术 | 终端技术 | 音视频技术
服务端技术 | 技术质量 | 数据算法
相关文章:
淘宝订单列表Fragment转场动画卡顿解决方案
如何应对产品形态与产品节奏相对确定情况下转变为『在业务需求与产品形态高度不确定性的情况下,如何实现业务交付时间与交付质量的确定性』。我们希望通过混合架构(Native 业务容器 Weex 2.0)作为未来交易终端架构的重要演进方向,…...
【状态空间方程】对于状态空间方程矩阵D≠0时的状态反馈与滑模控制
又到新的一年啦,2025新年快乐~。前几个月都没更新,主要还是因为不能把项目上的私密工作写进去,所以暂时没啥可写的。最近在山里实习,突然想起年前遗留了个问题一直没解决,没想到这两天在deepseek的加持下很快解决了&am…...
优雅的git log输出内容更加醒目
执行命令 git config --global alias.lg "log --graph --prettyformat:%C(red)%h%C(reset) - %C(yellow)%d%C(reset) %C(magenta)<%an>%C(reset) %C(cyan)(%ad)%C(reset) %C(green)%s%C(reset) (%cr) --abbrev-commit --dateformat:%Y-%m-%d %H:%M:%S"...
PySide(PyQT)使用场景(QGraphicsScene)进行动态标注的一个demo
用以标注图像的一个基本框架demo import sys from PySide6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QMainWindow, QLabel, QGraphicsPixmapItem from PySide6.QtGui import QPixmap, QPainter, QTransform from PySide6.QtCore import Qt, QPointF, S…...
LeetCode每日精进:876.链表的中间结点
题目链接:876.链表的中间结点 题目描述: 给你单链表的头结点 head ,请你找出并返回链表的中间结点。 如果有两个中间结点,则返回第二个中间结点。 示例 1: 输入:head [1,2,3,4,5] 输出:[3,4,5…...
ollama实践笔记
目录 一、linux安装文件命令: 二、启动ollama 三、linux 如何把ollama serve做为服务方式启动 四、安装deepseek-r1 五、如何在网页中使用ollama? 5.1 安装Open WebUI【不推荐】 5.2 安装ollama-webui-lite 六、Ubuntu安装docker、只需要一句话…...
联想电脑如何进入BIOS?
打开设置 下滑找到更新与安全 点击恢复和立即重新启动 选择疑难解答 选择UEFI固件设置 然后如果有重启点击重启 重启开机时一直点击FNF10进入BIOS界面...
CentOS本机配置为时间源
CentOS本机配置为时间源 安装chrony,默认已安装修改配置文件 /etc/chrony.conf客户端配置 安装chrony,默认已安装 yum -y install chrony修改配置文件 /etc/chrony.conf # cat /etc/chrony.conf | grep -Ev "^$|#" server ceph00 iburst dri…...
使用 EDOT 监测由 OpenAI 提供支持的 Python、Node.js 和 Java 应用程序
作者:来自 Elastic Adrian Cole Elastic 很自豪地在我们的 Python、Node.js 和 Java EDOT SDK 中引入了 OpenAI 支持。它们为使用 OpenAI 兼容服务的应用程序添加日志、指标和跟踪,而无需任何代码更改。 介绍 去年,我们宣布了 OpenTelemetry…...
微信小程序网络请求封装
微信小程序的网络请求为什么要封装?封装使用有什么好处? 封装的目的是为了偷懒,试想一下每次都要wx.request,巴拉巴拉传一堆参数,是不是很麻烦,有些公共的参数例如header,baseUrl是不是可以封装…...
【自学笔记】人工智能基础知识点总览-持续更新
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 人工智能重点知识点总览一、基础概念与原理1.1 人工智能定义与发展1.2 算法与数据结构1.3 数学基础 二、机器学习2.1 监督学习2.2 无监督学习2.3 强化学习 三、深度…...
Docker 常用命令基础详解(二)
四、容器操作命令 4.1 运行容器 使用docker run命令可以创建并运行一个容器,它就像是一个神奇的 “启动器”,让镜像中的应用程序在容器中运行起来。其基本语法为: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 其中,OPTIONS…...
初学java 数据库相关学习
创建数据库: 主键: unsigned primary key auto_increment 外键: foreign key(xx) references table_name(xx) 字段: 类型: int ; tinyint ;char(20);varchar(255); date; datetime; text; float(5,2); double(10,2); long; decimal(15,10) 约束:primary key; foreig…...
ARM64 Trust Firmware [一]
ARMv8 启动流程: 在《RK3568上电启动流程 [十五]》中,简单介绍了 RK3568 的上电启动过程,本篇再详细分解其启动流程。 在 ARMv8 架构中,启动流程包含多个阶段,这些阶段被称为 BL (bootloader) …...
K8S容器启动提示:0/2 nodes are available: 2 Insufficient cpu.
问题:K8S的容器启动报错0/2 nodes are available: 2 Insufficient cpu. 原因:Pod的资源请求(requests)设置不当:在Kubernetes中,调度器根据Pod的requests字段来决定哪个节点可以运行该Pod。如果一个Pod声明…...
数据结构:图论入门
图论起源于欧拉对哥尼斯堡七桥问题的解决. 他构建的图模型将陆地用点来表示, 桥梁则用线表示, 如此一来, 该问题便转化为在图中能否不重复地遍历每条边的问题. 图论的应用 地图着色 在地图着色问题中, 我们用顶点代表国家, 将相邻国家之间用边相连. 这样, 问题就转化为用最少…...
DataBase【MySQL基础夯实使用说明(下)】
MySQL数据库 🏆当领导表示关心时,您怎么回复? ⚠️不要傻傻的说应该的,这样不仅会抹杀掉你的辛苦,也让领导没办法接话! 🔔文章末尾彩蛋! 文章目录 MySQL数据库前言一、约束1.1.外键…...
Golang的多团队协作编程模式与实践经验
Golang的多团队协作编程模式与实践经验 一、多团队协作编程模式概述 在软件开发领域,多团队协作编程是一种常见的工作模式。特别是对于大型项目来说,不同团队间需要协同合作,共同完成复杂的任务。Golang作为一种高效、并发性强的编程语言&…...
详解spotbugs -textui常用命令(包括生成html测试报告)
用命令运行spotbugs 本文默认大家了解spotbugs的基础使用,如果不了解可以参考文章 使用神器Spotbugs,轻松入门静态代码分析-CSDN博客 我们在使用spotbugs 对Java代码进行静态分析,查找相关的漏洞时通常在使用Maven和Gradle进行构建的过程中…...
C++:Map和Set
目录 一、关联式容器 二、键值对 三、树形结构的关联式容器 A.set的模板参数列表 B.set的构造 C.set的迭代器 D.set的容量 E.set的修改操作 F.set的使用举例 A.map的模板参数列表 B.map的构造 C.map的迭代器 D.map的容量 E.map中元素的修改 operator[ ] insert()…...
【Unity Shader编程】之顶点着色器
来一张AI提供的资料 在shader编程中,定义的结构体,有些是会被自动赋值,有些是必须要手动赋值的,这就涉及到了语义, 例如 struct appdata{float4 vertex : POSITION;float vertex2;float2 uv : TEXCOORD0;};结构体里面定…...
Hive之[Hive]详细安装步骤
hive 是依赖hadoop中的hdfs作为存储,依赖mysql管理元数据 master节点 集群环境 master 192.168.204.130 slave1 192.168.204.131 slave2 192.168.204.132组件下载地址 https://archive.apache.org/dist/hive/hive-1.2.2/ 或 链接: https://pan.baidu.com/s/1…...
3.【线性代数】——矩阵乘法和逆矩阵
三 矩阵乘法和逆矩阵 1. 矩阵乘法1.1 常规方法1.2 列向量组合1.3 行向量组合1.4 单行和单列的乘积和1.5 块乘法 2. 逆矩阵2.1 逆矩阵的定义2.2 奇异矩阵2.3 Gauss-Jordan 求逆矩阵2.3.1 求逆矩阵 ⟺ \Longleftrightarrow ⟺解方程组2.3.2 Gauss-Jordan求逆矩阵 1. 矩阵乘法 1.…...
手动配置IP
手动配置IP,需要考虑四个配置项: 四个配置项 IP地址、子网掩码、默认网关、DNS服务器 IP地址:格式表现为点分十进制,如192.168.254.1 子网掩码:用于区分网络位和主机位 【子网掩码的二进制表达式一定是连续的&#…...
unity is running as administrator 管理员权限问题
每次打开工程弹出unity is running as administrator的窗口 unity版本2022.3.34f1,电脑系统是win 11系统解决方法一:解决方法二: unity版本2022.3.34f1,电脑系统是win 11系统 每次打开工程都会出现unity is running as administr…...
AI在电竞比分网中的主要应用场景
AI在电竞体育比分网的数据应用非常广泛,能够显著提升数据分析、预测、用户体验和商业价值。以下是AI在电竞比分网中的主要应用场景: 1. 实时数据采集与分析 比赛数据实时更新:AI通过自动化系统实时采集比赛数据(如击杀数、经济差、…...
消息中间件:RabbitMQ镜像集群部署配置全流程
目录 1、特点 2、RabbitMQ的消息传递模式 2.1、简单模式(Simple Mode) 2.2、工作队列模式(Work Queue Mode) 2.3、发布/订阅模式(Publish/Subscribe Mode) 2.4、路由模式(Routing Mode&am…...
TCP的拥塞控制
什么是TCP的拥塞控制?它的工作原理是什么?为什么需要拥塞控制? TCP拥塞控制简介 想象一下,你和一群朋友在一条狭窄的小路上跑步。如果每个人都拼命跑,小路很快就会变得拥挤不堪,大家互相碰撞,…...
Jenkins 配置 Git Repository 五
Jenkins 配置 Git Repository 五 这里包含了 Freestyle project 任务类型 和 Pipeline 任务类型 关于 Git 仓库的配置,如下 不同的任务类型,只是在不同的模块找到 配置 Git 仓库 找到 Git 仓库配置位置之后,所有的任务类型配置都是一样的 …...
父组件中循环子组件调用
父组件中循环子组件调用 父组件 //father.vue <template><view><view v-for"(item,index) in list"><son ref"son"></son></view><buton click"submit">123</buton></view> </templ…...
【网络安全.渗透测试】Cobalt strike(CS)工具使用说明
目录 前言 一、工具显著优势 二、安装 Java 运行环境 三、实验环境搭建要点 四、核心操作流程详解 (一)环境准备与连接步骤 (二)主机上线与深度渗透流程 五、其他实用功能应用指南 (一)office 宏 payload 应用 (二)Https Payload 应用 (三)信息收集策略 …...
C++ 设计模式-建造者模式
以下是一个完整的C建造者模式示例,包含产品类、建造者接口、具体建造者、指挥者以及测试代码: #include <iostream> #include <string> #include <memory>// 产品类:汽车 class Car { public:void setBody(const std::str…...
【Unity3D】Unable to detect SDK in the selected directory
某天突然发现SDK选中自己的目录 或 打安卓包时 提示SDK Tools相关的报错 打开Android Studio的SDK Manager更新Android SDK Tools...
QML使用ChartView绘制饼状图
一、工程配置 首先修改CMakeLists.txt,按下图修改: find_package(Qt6 6.4 REQUIRED COMPONENTS Quick Widgets) PRIVATEtarget_link_libraries(appuntitledPRIVATE Qt6::QuickPRIVATE Qt6::Widgets )其次修改main.cpp,按下图修改ÿ…...
ollama本地部署 deepseek离线模型安装 一套从安装到UI运行
一、安装本地ollama 1、下载ollama (1)百度网盘windows版本 通过网盘分享的文件:OllamaSetup.exe 链接: https://pan.baidu.com/s/15ca6WAzrc4wWph5H9BEOzw 提取码: 283u (2)进入官网:Ollama 2、选择你的系统 等待下载完成就可以了。 注:这…...
【linux】ubunbu切换到root
在 Ubuntu 中切换到 root 用户有几种方法,具体取决于你的需求和权限配置。以下是常见的几种方式: 1. 使用 sudo 临时切换到 root 如果你当前用户有 sudo 权限,可以使用以下命令临时切换到 root 用户: bash sudo -i 或者࿱…...
推理框架对比:ReAct、思维链(COT)和思维树(TOT)谁更胜一筹
推理框架作为 AI 解决复杂问题的核心机制,正逐渐成为研究和应用的焦点。ReAct、思维链(Chain-of-Thought,CoT)(Chain-of-Thought (CoT):引导大型语言模型解决问题的有效策略)和思维树࿰…...
electron.vite 项目创建以及better-sqlite3数据库使用
1.安装electron.vite npm create quick-start/electronlatest中文官网:https://cn.electron-vite.org/ 2. 安装项目依赖 npm i3.修改 electron-builder 配置文件 appId: com.electron.app productName: text33 directories:buildResources: build files:- !**/.v…...
Dockerfiles 的 Top 10 常见 DevOps/SRE 面试问题及答案
1. RUN 和 CMD 之间有什么区别? RUN : 在镜像构建过程中执行命令,创建一个新的层。通常用于安装软件包。 示例: RUN apt-get update && apt-get install -y curlCMD : 指定容器启动时默认运行的命令。它在运行时执行,而不是在构建过程…...
Sentinel——Spring Boot 应用接入 Sentinel 后内存开销增长计算方式
接入 Sentinel 对 Spring Boot 应用的内存消耗影响主要取决于 规则数量、资源数量、监控粒度、并发量 等因素。 1. 核心内存消耗来源 (1) Sentinel 核心库 默认依赖:Sentinel Core 本身占用较小,通常在 10~50MB(取决于资源数量和规则复杂度…...
domain 网络安全 网络安全域
文章目录 1、域的概述 1.1、工作组与域1.2、域的特点1.3、域的组成1.4、域的部署概述1.5、活动目录1.6、组策略GPO 2、域的部署实验 2.1、建立局域网,配置IP2.2、安装活动目录2.3、添加用户到指定域2.4、将PC加入域2.5、实验常见问题 3、OU(组织单位…...
OpenCV机器学习(2)提升算法类cv::ml::Boost
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::ml::Boost 是 OpenCV 机器学习模块中的一部分,用于实现提升算法(Boosting Algorithms)。Boosting 是一种…...
【Java 面试 八股文】框架篇
框架篇 1. Spring框架中的单例bean是线程安全的吗?2. 什么是AOP?3. 你们项目中有没有使用到AOP?4. Spring中的事务是如何实现的?5. Spring中事务失效的场景有哪些?6. Spring的bean的生命周期?7. Spring中的…...
基于HAL库的按钮实验
实验目的 掌握STM32 HAL库的GPIO输入配置方法。 实现通过按钮控制LED亮灭(支持轮询和中断两种模式)。 熟悉STM32CubeMX的外部中断(EXTI)配置流程。 实验硬件 开发板:STM32系列开发板(如STM32F103C8T6、N…...
TCP 端口号为何位于首部前四个字节?协议设计的智慧与启示
知乎的一个问题很有意思:“为什么在TCP首部中要把TCP的端口号放入最开始的四个字节?” 这种问题很适合我这种搞历史的人,大年初一我给出了一个简短的解释,但仔细探究这个问题,我们将会获得 TCP/IP 被定义的过程。 文…...
前端实现在PDF上添加标注(1)
前段时间接到一个需求,用户希望网页上预览PDF,同时能在PDF上添加文字,划线,箭头和用矩形框选的标注,另外还需要对已有的标注进行修改,删除。 期初在互联网上一通搜索,对这个需求来讲发现了两个问…...
Springboot 中如何使用Sentinel
在 Spring Boot 中使用 Sentinel 非常方便,Spring Cloud Alibaba 提供了 spring-cloud-starter-alibaba-sentinel 组件,可以快速将 Sentinel 集成到你的 Spring Boot 应用中,并利用其强大的流量控制和容错能力。 下面是一个详细的步骤指南 …...
如何优化React应用的性能?
文章目录 1. 引言2. 渲染优化2.1 使用 React.memo 避免不必要的重新渲染2.2 使用 shouldComponentUpdate 或 PureComponent2.3 使用 useMemo 和 useCallback 3. 异步渲染与懒加载3.1 使用 React.lazy 和 Suspense 实现懒加载3.2 分割代码(Code-Splitting)…...
ES的java操作
ES的java操作 一、添加依赖 在pom文件中添加依赖包 <dependencies><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</version></dependency><!-- elastic…...
八大排序——简单选择排序
目录 1.1基本操作: 1.2动态图: 1.3代码: 代码解释 1. main 方法 2. selectSort 方法 示例运行过程 初始数组 每轮排序后的数组 最终排序结果 代码总结 1.1基本操作: 选择排序(select sorting)也…...