Systrace分析App性能学习笔记

学习Gracker Systrace系列文章,总结使用Systrace分析App性能的方法。推荐想通过Systrace学习Framework的同学,去看原文。

文章目录

  • 概述
  • Systrace使用流程
  • Systrace 文件生成
    • 图形方式(不推荐)
    • 命令行方式
  • Systrace分析
    • 快捷键使用
    • 帧状态
    • 线程状态查看
    • 线程唤醒信息分析
    • 信息区数据解析
  • 通过Systrace学习Android Framework
    • Input 解读
      • InputDown 事件在 SystemServer 的工作流
      • InputDown 事件在 App 的工作流
      • App 的 Pending 队列
      • 关键知识点和流程
    • Choreographer + SurfaceFlinger + Vsync + TripleBuffer
      • Vsync
      • Choreographer
      • SurfaceFlinger
      • TripleBuffer
  • 掉帧分析思路
  • Android Systrace 响应速度
    • App自身可能存在的问题
    • 分析应用耗时的点
  • 应用进程启动阶段
    • 应用进程启动到 SplashActivity 第一帧显示
    • SplashActivity 第一帧显示到主 Activity 第一帧显示
    • 主 Activity 第一帧显示到界面完全加载并显示
  • 特殊Api使用
    • 添加Tag
    • IdleHandler使用

概述

  • Systrace 利用了 Linux Kernel 中的 ftrace 功能
  • Android 定义了一个 Trace 类。应用程序可利用该类把统计信息输出给ftrace。
    # 同线程使用
     Trace.beginSection("onCreate");
     ... 
     Trace.endSection();
    
    # 异步线程使用
    Trace.beginAsyncSection()
    ...
    Trace.endAsyncSection()
    
    注意:如果时间太短不会捕捉到,在命令行捕捉时,必须添加-a $applicationId 大范围添加建议使用TraceFix。
  • Android 提供一个 systrace.py,将生成的文件转换为html,使用chrome进行分析。

Systrace使用流程

  1. 手机准备好你要进行抓取的界面
  2. 点击开始抓取(命令行的话就是开始执行命令)
  3. 手机上开始操作(不要太长时间)
  4. 设定好的时间到了之后,会将生成 Trace.html 文件,使用 Chrome 将这个文件打开进行分析(在浏览器输入chrome://tracing/,然后打开待分析文件)

一般抓到的 Systrace 文件如下

Systrace 文件生成

图形方式(不推荐)

打开Android_SDK\tools\monitor.bat

使用chrome打开报错

在网上也没有找到对应的解决办法

命令行方式

使用命令行方式非常简单

注意:这里需要安装python2并配置环境变量

推荐. windows10同时安装python2和python3,完美解决冲突

adb shell atrace -h # 查看支持的所有选项
D:\Android_SDK\platform-tools\systrace>adb shell atrace -h
atrace: invalid option -- h

usage: atrace [options] [categories...]
options include:
  -a appname      enable app-level tracing for a comma separated list of cmdlines; * is a wildcard matching any process
  -b N            use a trace buffer size of N KB
  -c              trace into a circular buffer
  -f filename     use the categories written in a file as space-separated
                    values in a line
  -k fname,...    trace the listed kernel functions
  -n              ignore signals
  -s N            sleep for N seconds before tracing [default 0]
  -t N            trace for N seconds [default 5]
  -z              compress the trace dump
  --async_start   start circular trace and return immediately
  --async_dump    dump the current contents of circular trace buffer
  --async_stop    stop tracing and dump the current contents of circular
                    trace buffer
  --stream        stream trace to stdout as it enters the trace buffer
                    Note: this can take significant CPU time, and is best
                    used for measuring things that are not affected by
                    CPU performance, like pagecache usage.
  --list_categories
                  list the available tracing categories
 -o filename      write the trace to the specified file instead
                    of stdout.

D:\Android_SDK\platform-tools\systrace>

一般来说比较常用的是

  1. -o : 指示输出文件的路径和名字
  2. -t : 抓取时间(最新版本可以不用指定, 按 Enter 即可结束)
  3. -b : 指定 buffer 大小 (一般情况下,默认的 Buffer 是够用的,如果你要抓很长的 Trae , 那么建议调大 Buffer )
  4. -a : 指定 app 包名 (如果要 Debug 自定义的 Trace 点, 记得要加这个)

Systrace分析

快捷键使用

快捷键的使用可以加快查看 Systrace 的速度,下面是一些常用的快捷键

鼠标模式快捷切换 : 主要是针对鼠标的工作模式进行切换 , 默认是 1 ,也就是选择模式,查看 Systrace 的时候,需要经常在各个模式之间切换 , 所以点击切换模式效率比较低,直接用快捷键切换效率要高很多

  • 数字键1 : 切换到 Selection 模式 , 这个模式下鼠标可以点击某一个段查看其详细信息, 一般打开 Systrace 默认就是这个模式 , 也是最常用的一个模式 , 配合 M 和 ASDW 可以做基本的操作

  • W : 放大 Systrace , 放大可以更好地看清局部细节

  • S : 缩小 Systrace, 缩小以查看整体

  • A : 左移

  • D : 右移

  • M : 高亮选中当前鼠标点击的段(这个比较常用,可以快速标识出这个方法的左右边界和执行时间,方便上下查看)

  • 数字键2 : 切换到 Pan 模式 , 这个模式下长按鼠标可以左右拖动, 有时候会用到

  • 数字键3 : 切换到 Zoom 模式 , 这个模式下长按鼠标可以放大和缩小, 有时候会用到

  • 数字键4 : 切换到 Timing 模式 , 这个模式下主要是用来衡量时间的,比如选择一个起点, 选择一个终点, 查看起点和终点这中间的操作所花费的时间。

帧状态

这是分析App性能的最明显的特征

  • 绿帧

    绿帧是最常见的帧,表示这一帧在一个 Vsync 周期里面完成
    在这里插入图片描述
    下这种一片皆绿,肯定没有问题
    在这里插入图片描述

  • 黄帧

    黄帧表示这一帧耗时超过1个 Vsync 周期,但是小于 2 个 Vsync 周期。黄帧的出现表示这一帧可能存在性能问题,可能会导致卡顿情况出现
    在这里插入图片描述

  • 红帧

    红帧表示这一帧耗时超过 2 个 Vsync 周期,红帧的出现表示这一帧可能存在性能问题,大概率会导致卡顿情况出现
    在这里插入图片描述

线程状态查看

  • 绿色 : 运行中(Running)

    在这里插入图片描述

  • 蓝色 : 可运行(Runnable)

    在这里插入图片描述

  • 白色 : 休眠中(Sleep)

    线程没有工作要做,可能是因为线程在互斥锁上被阻塞。

    在这里插入图片描述

  • 橘色 : 不可中断的睡眠态 (Uninterruptible Sleep - IO Block)

    线程在I / O上被阻塞或等待磁盘操作完成

    在这里插入图片描述

  • 紫色 : 不可中断的睡眠态(Uninterruptible Sleep)

    线程在另一个内核操作(通常是内存管理)上被阻塞。

    在这里插入图片描述

注意:Uninterruptible指的是当前不能响应外部中断

线程唤醒信息分析

一个线程被唤醒的信息往往比较重要,知道他被谁唤醒,那么我们也就知道了他们之间的调用等待关系,如果一个线程出现一段比较长的 sleep 情况,然后被唤醒,那么我们就可以去看是谁唤醒了这个线程,对应的就可以查看唤醒者的信息,看看为什么唤醒者这么晚才唤醒。

另外一个场景的情况是:应用主线程在等待此应用的其他线程执行的结果,这时候线程唤醒信息就可以用来分析主线程到底被哪个线程 Block 住了,比如下面这个场景,这一帧 doFrame 执行了 152ms,有明显的异常,但是大部分时间是在 sleep

在这里插入图片描述

发现在这个过程中,有间歇性的Runnable,对其进行放大,点击Runnable,查看说明信息

在这里插入图片描述

看看20424是哪一个线程,将分析面板滑动到Kernel部分,在同一个时间节点在所有的CPU上都点击一下,看看CPU Slice-》Args tid一致。

在这里插入图片描述

然后针对性分析RenderHeartbeat方法调用过程。

在这里插入图片描述

信息区数据解析

  • 线程状态信息解析
    在这里插入图片描述

  • 函数 Slice 信息解析
    在这里插入图片描述

  • Counter Sample 信息解析
    在这里插入图片描述

  • CPU Slice 信息解析
    在这里插入图片描述

  • User Expectation 信息解析
    位于整个 Systrace 最上面的部分,标识了 Rendering Response 和 Input Response
    在这里插入图片描述

  • Binder调用
    在这里插入图片描述

  • 显示的锁的信息
    在这里插入图片描述
    ActivityTaskManagerService 的 getFocusedStackInfo 方法在执行过程中被阻塞,原因是因为执行同步方法块的时候,没有拿到同步对象的锁的拥有权;需要等待拥有同步对象的锁拥有权的另外一个方法 ActivityTaskManagerService.activityPaused 执行完成后,才能拿到同步对象的锁的拥有权,然后继续执行

  • CPU Info 解读
    在这里插入图片描述 在kernel CPU可以查看特定CPU时钟频率甚至限频情况

  • CPU Usage
    在这里插入图片描述
    页面顶端可以查看整体CPU使用情况。

通过Systrace学习Android Framework

作为移动应用开发者这一块接触不多,Systrace作为整体分析安卓系统性能的工具,如果不了解一点,有些工作挺难开展,捡性能分析用到的简单说说。

Input 解读

在这里插入图片描述

InputReader 和 InputDispatcher 是跑在 SystemServer 里面的两个 Native 线程,负责读取和分发 Input 事件,我们分析 Systrace 的 Input 事件流,首先是找到这里。

下面针对上图中标号进行简单说明

  1. InputReader 负责从 EventHub 里面把 Input 事件读取出来,然后交给 InputDispatcher 进行事件分发
  2. InputDispatcher 在拿到 InputReader 获取的事件之后,对事件进行包装和分发 (也就是发给对应的App)
  3. OutboundQueue 里面放的是即将要被派发给对应 AppConnection 的事件
  4. WaitQueue 里面记录的是已经派发给 AppConnection 但是 App 还在处理没有返回处理成功的事件
  5. PendingInputEventQueue 里面记录的是 App 需要处理的 Input 事件,这里可以看到已经到了应用进程
  6. deliverInputEvent 标识 App UI Thread 被 Input 事件唤醒
  7. InputResponse 标识 Input 事件区域,这里可以看到一个 Input_Down 事件 + 若干个 Input_Move 事件 + 一个 Input_Up 事件的处理阶段都被算到了这里
  8. App 响应 Input 事件 : 这里是滑动然后松手,也就是我们熟悉的桌面滑动的操作,桌面随着手指的滑动更新画面,松手后触发 Fling 继续滑动,从 Systrace 就可以看到整个事件的流程。

下面以第一个 Input_Down 事件的处理流程来进行详细的工作流说明,其他的 Move 事件和 Up 事件的处理是一样的(部分不一样,不过影响不大)

InputDown 事件在 SystemServer 的工作流

在这里插入图片描述

InputDown 事件在 App 的工作流

在这里插入图片描述

App 的 Pending 队列

在这里插入图片描述

关键知识点和流程

从上面的 Systrace 来看,Input 事件的基本流向如下:

  1. InputReader 读取 Input 事件
  2. InputReader 将读取的 Input 事件放到 InboundQueue 中
  3. InputDispatcher 从 InboundQueue 中取出 Input 事件派发到各个 App(连接) 的 OutBoundQueue
  4. 同时将事件记录到各个 App(连接) 的 WaitQueue
  5. App 接收到 Input 事件,同时记录到 PendingInputEventQueue ,然后对事件进行分发处理
  6. App 处理完成后,回调 InputManagerService 将负责监听的 WaitQueue 中对应的 Input 移除

只要记住Input事件的流动方向即可,如果在App端出现多个事件堆积,就发生App卡顿。

Choreographer + SurfaceFlinger + Vsync + TripleBuffer

三者协调配合产生流畅的画面。其工作过程如图所示:
在这里插入图片描述
Systrace时序图
在这里插入图片描述

Vsync

在这里插入图片描述
Vsync 信号可以由硬件产生,也可以用软件模拟,不过现在基本上都是硬件产生,负责产生硬件 Vsync 的是 HWC,HWC 可生成 VSYNC 事件并通过回调将事件发送到 SurfaceFlinge , DispSync 将 Vsync 生成由 Choreographer 和 SurfaceFlinger 使用的 VSYNC_APP 和 VSYNC_SF 信号。
VSync灰色和白色都是一个完整的Vsync
在这里插入图片描述

Choreographer

Choreographer 的引入,主要是配合 Vsync,给上层 App 的渲染提供一个稳定的 Message 处理的时机,也就是 Vsync 到来的时候 ,系统通过对 Vsync 信号周期的调整,来控制每一帧绘制操作的时机。
在这里插入图片描述
如果强制关闭硬件加速器就没有RenderThread,都在UI thread进行。

SurfaceFlinger

SurfaceFlinger 也会在 Vsync 到来的时候,将所有已经准备好的 Surface 进行合成操作。

在这里插入图片描述

TripleBuffer

Choreographer(RenderThread)与SurfaceFlinger是生产者、消费者关系。总共三个Buffer,存在彼此制约的关系。任何一个缓慢都会造成另外一个“卡住”。

掉帧分析思路

通常我们通过 Systrace 判断应用是否掉帧的时候,一般是直接看 SurfaceFlinger 部分,主要是下面几个步骤

  1. SurfaceFlinger 的主线程在每个 Vsync-SF 的时候是否没有合成?
  2. 如果没有合成操作,那么需要看没有合成的原因:
  • 因为 SurfaceFlinger 检查发现没有可用的 Buffer 而没有合成操作?
  • 因为 SurfaceFlinger 被其他的工作占用(比如截图、HWC 等)?
  • 如果有合成操作,那么需要看对应的 App 的 可用 Buffer 个数是否正常:如果 App 此时可用 Buffer 为 0,那么看 App 端为何没有及时 queueBuffer(这就一般是应用自身的问题了),因为 SurfaceFlinger 合成操作触发可能是其他的进程有可用的 Buffer
    SurfaceFlinger没有进行合成,App也没有生成供SurfaceFlinger使用的Buffer
    在这里插入图片描述
    滑动发现Choreographer超时
    在这里插入图片描述
    然后判定可能问题,尝试处理。

Android Systrace 响应速度

App自身可能存在的问题

应用自身原因主要是应用启动时候的组件初始化、View 初始化、数据初始化耗时等,具体包括:

  1. Application.onCreate:应用自身的逻辑 + 三方 SDK 初始化耗时
  2. Activity 的生命周期函数:onStart、onCreate、onResume 耗时
  3. Services 的生命周期函数耗时
  4. Broadcast 的 onReceive 耗时
  5. ContentProvider 初始化耗时(注意已经被滥用)
  6. 界面布局初始化:measure、layout、draw 等耗时
  7. 渲染线程初始化:setSurface、queueBuffer、dequeueBuffer、Textureupload 等耗时
  8. Activity 跳转:从 SplashActivity 到 MainActivity 耗时
  9. 应用向主线程 post 的耗时 Message 耗时
  10. 主线程或者渲染线程等待子线程数据更新耗时
  11. 主线程或者渲染线程等待子进程程数据更新耗时
  12. 主线程或者渲染线程等待网络数据更新耗时
  13. 主线程或者渲染线程 binder 调用耗时
  14. WebView 初始化耗时
  15. 初次运行 JIT 耗时

分析应用耗时的点

  1. 是否某一段方法自身执行耗时比较久(Running 状态) –> 应用自身问题
  2. 主线程是否有大段 Running 状态,但是底下没有任何堆栈 –> 应用自身问题,加 TraceTag 或者使用 TraceView 来找到对应的代码逻辑
  3. 是否在等 Binder 耗时比较久(Sleep 状态) –> 检测 Binder 服务端,一般是 SystemServer
  4. 是否在等待子线程返回数据(Sleep 状态) –> 应用自身问题,通过查看 wakeup 信息,来找到依赖的子线程
  5. 是否在等待子进程返回数据(Sleep 状态) –> 应用自身问题,通过查看 wakeup 信息,来找到依赖的子进程或者其他进程(一般是 ContentProvider 所在的进程)
  6. 是否有大量的 Runnable –> 系统问题,查看 CPU 部分,看看是否已经跑满
  7. 是否有大量的 IO 等待(Uninterruptible Sleep | WakeKill - Block I/O) –> 检查系统是否已经低内存
  8. RenderThread 是否执行 dequeueBuffer 和 queueBuffer 耗时 –> 查看 SurfaceFlinger

如果是应用自身的原因,可以使用 TraceView(AS 自带的 CPU Profiler)、Simple Perf 等继续查看更加详细的函数调用信息,也可以使用 TraceFix 插件,插入更多的 TraceTag 之后,重新抓取 Systrace 来对比分析
应用启动后,SystemServer 会记录从 startActivity 被调用到应用第一帧显示的时长,在 Systrace 中的显示如下(注意结尾是应用第一帧,如果应用启动的时候是 SplashActivity -> MainActivity,那么这里的结尾只是 SplashActivity,MainActivity 的完全启动需要自己查看)

在这里插入图片描述

应用进程启动阶段

通常的大型应用,App 冷启动通常包括下面三个部分,每一个部分耗时都会导致应用的整体启动速度变慢,所以在优化启动速度的时候,需要明确知道应用启动结束的点(需要跟测试沟通清楚,一般是界面保持稳定的那个点)

  1. 应用进程启动到 SplashActivity 第一帧显示(部分 App 没有 SplashActivity,所以可以省略这一步,直接到进程启动到 主 Activit 第一帧显示 )
  2. SplashActivity 第一帧显示到主 Activity 第一帧显示
  3. 主 Activity 第一帧显示到界面完全显示
    下面针对这三个阶段来具体分析(当然你的 App 如果简单的话,可能没有 SplashActivity ,直接进的就是主 Activity,那么忽略第二步就可以了)

应用进程启动到 SplashActivity 第一帧显示

由于是冷启动,所以 App 进程在 Fork 之后,需要首先执行 bindApplication ,这个也是区分冷热启动的一个重要的点。Application 的环境创建好之后,就开始组件的启动(这里是 Activity 组件,通过 Service、Broadcast、ContentProvider 组件启动的进程则会在 bindApplication 之后先启动这些组件)
Activity 的生命周期函数会在 Activity 组件创建的时候执行,包括 onStart、onCreate、onResume 等,然后还要经过一次 Choreographer#doFrame 的执行(包括 measure、layout、draw)以及 RenderThread 的初始化和第一帧任务的绘制,再加上 SurfaceFlinger 一个 Vsync 周期的合成,应用第一帧才会真正显示(也就是下图中 finishDrawing 的位置)
在这里插入图片描述

SplashActivity 第一帧显示到主 Activity 第一帧显示

大部分的 App 都有 SplashActivity 来播放广告,播放完成之后才是真正的主 Activity 的启动,同样包括 Activity 组件的创建,包括 onStart、onCreate、onResume 、自有启动逻辑的执行、WebView 的初始化等等等等,直到主 Activity 的第一帧显示
在这里插入图片描述

主 Activity 第一帧显示到界面完全加载并显示

一般来说,主 Activity 需要多帧才能显示完全,因为有很多资源(最常见的是图片)是异步加载的,第一帧可能只加载了一个显示框架、而其中的内容在准备好之后才会显示出来。这里也可以看到,通过 Systrace 不是很方便来判断应用冷启动的终点(除非你跟测试约定好,在某个 View 显示之后就算启动完成,然后你在这个 View 里面打个 Systrace 的 Tag,通过跟踪这个 Tag 就可以粗略判断具体 Systrace 里面哪一帧是启动完成的点)
在这里插入图片描述

特殊Api使用

添加Tag

这个在前面有提到

 # 同线程使用
     Trace.beginSection("ccc");
     ... 
     Trace.endSection();

    # 异步线程使用
    Trace.beginAsyncSection()
    ...
    Trace.endAsyncSection()

注意:如果时间太短不会捕捉到,在命令行捕捉时,必须添加-a $applicationId 大范围添加建议使用TraceFix。
在这里插入图片描述

IdleHandler使用

在启动优化的过程中,idleHandler 可以在 MessageQueue 空闲的时候执行任务,配合activity.reportFullyDrawn获取页面完成时间。
在这里插入图片描述使用代码如下:

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onResume() {
        super.onResume();
        mHandler.getLooper().getQueue().addIdleHandler(() -> {
            reportFullyDrawn();
            return false;
        });
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/102759.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Dubbo 应用切换 ZooKeeper 注册中心实例,流量无损迁移

首先思考一个问题:如果 Dubbo 应用使用 ZooKeeper 作为注册中心,现在需要切换到新的 ZooKeeper 实例,如何做到流量无损? 本文提供解决这个问题的一种方案。 场景 有两个基于 Dubbo 的微服务应用,一个是服务提供者&…

RT-Thread 内核移植

内核移植 内核移植就是将RTT内核在不同的芯片架构、不同的板卡上运行起来,能够具备线程管理和调度,内存管理,线程间同步等功能。 移植可分为CPU架构移植和BSP(Board support package,板级支持包)移植两部…

四轴飞行器的电池研究(MatlabSimulink仿真)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

《TCP/IP网络编程》阅读笔记--基于Windows实现Hello Word服务器端和客户端

目录 1--Hello Word服务器端 2--客户端 3--编译运行 3-1--编译服务器端 3-2--编译客户端 3-3--运行 1--Hello Word服务器端 // gcc hello_server_win.c -o hello_server_win -lwsock32 // hello_server_win 9190 #include <stdio.h> #include <stdlib.h> #i…

一般不用buildroot来编译uboot和kernel

Buildroot 是一个流行的嵌入式 Linux 系统构建工具&#xff0c;它可以帮助开发者自动化地构建完整的嵌入式 Linux 系统&#xff0c;包括文件系统、内核以及各种用户空间应用程序。虽然 Buildroot 在构建嵌入式系统方面非常强大且易于使用&#xff0c;但一般情况下&#xff0c;它…

蓝牙发展现状

目录 一、产品分类1、Bluetooth经典2、Bluetooth低能耗(LE)3、二者差异 二、出货量三、未来需要加强的方向四、技术行业细分五、学习资料1、蓝牙官网2、大神博客——于忠军 一、产品分类 1、Bluetooth经典 Bluetooth Classic无线电&#xff0c;也被称为Bluetooth 基本速率/增强…

windows11 利用vmware17 安装ky10-server-x86操作系统

下载相关软件和镜像 vmware17 下载 下载页面 Download VMware Workstation Pro ky10server-x86镜像下载 官网 国产操作系统、银河麒麟、中标麒麟、开放麒麟、星光麒麟——麒麟软件官方网站 (kylinos.cn) 选择对应版本去下载 安装 选择镜像&#xff0c;点击下一步 磁盘设置要…

macOS上制作arm64的jdk17镜像

公司之前一直用的openjdk17的镜像&#xff0c;docker官网可以直接下载&#xff0c;但是最近对接的一个项目&#xff0c;对方用的是jdk17&#xff0c;在对接的时候有加解密异常的问题&#xff0c;为了排查是不是jdk版本的问题&#xff0c;需要制作jdk17的镜像。docker官网上的第…

Spark-Core核心算子

文章目录 一、数据源获取1、从集合中获取2、从外部存储系统创建3、从其它RDD中创建4、分区规则—load数据时 二、转换算子(Transformation)1、Value类型1.1 map()_1.2 mapPartitions()1.3 mapPartitionsWithIndex(不常用)1.4 filterMap()_扁平化&#xff08;合并流&#xff09;…

Docker部署RustDesk Server 设置开机自启

三、Docker安装 Docker官方和国内daocloud都提供了一键安装的脚本&#xff0c;使得Docker的安装更加便捷。 官方的一键安装方式&#xff1a; curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun 国内 daocloud一键安装命令&#xff1a; curl -sSL https://…

测试验证平台

测试验证平台 1.功能说明&#xff1a; 模拟智能终端车端数据采集及上报的功能&#xff0c;提供数据管理平台的模拟和验证功能。 2.系统组成&#xff1a; 系统示意图 功能要求&#xff1a; 本地电脑实现Imx6配置功能&#xff0c;能够通过运行不同的脚本&#xff0c;模拟不…

Java“牵手”京东商品详情数据,京东API接口申请指南

京东平台商品详情接口是开放平台提供的一种API接口&#xff0c;通过调用API接口&#xff0c;开发者可以获取京东商品的标题、价格、库存、月销量、总销量、库存、详情描述、图片等详细信息 。 获取商品详情接口API是一种用于获取电商平台上商品详情数据的接口&#xff0c;通过…

说说Flink双流join

分析&回答 Flink双流JOIN主要分为两大类 一类是基于原生State的Connect算子操作另一类是基于窗口的JOIN操作。其中基于窗口的JOIN可细分为window join和interval join两种。 基于原生State的Connect算子操作 实现原理&#xff1a;底层原理依赖Flink的State状态存储&…

大学物理 之 安培环路定理

文章目录 前言什么是安培环路定理安培环路定理有什么作用 深入了解深入学习 前言 什么是安培环路定理 安培环路定理的物理意义在于描述了电流和磁场之间的相互作用&#xff0c;以及如何在一个封闭的回路中分析这种相互作用。 简单的来说 , 用环路定理来解决在磁场中B对任意封…

C++ 浅拷贝和深拷贝

目录 1. 浅拷贝 2. 深拷贝 1. 浅拷贝 浅拷贝只是拷贝一个指针&#xff0c;并没有新开辟一个地址&#xff0c;拷贝的指针和原来的指针指向同一块地址&#xff0c;如果原来的指针所指向的资源释放了&#xff0c;那么再释放浅拷贝的指针的资源就会出现错误 对一个已知对象进行拷贝…

springMVC之拦截器

文章目录 前言一、拦截器的配置二、拦截器的三个抽象方法三、多个拦截器的执行顺序总结 前言 拦截器 一、拦截器的配置 SpringMVC中的拦截器用于拦截控制器方法的执行 SpringMVC中的拦截器需要实现HandlerInterceptor SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置&…

springboot使用logback配置彩色日志

springboot使用logback配置彩色日志 前言一、logback文件二、效果 前言 应该有很多同学发现&#xff0c;使用了logback以后&#xff0c;我们的控制台日志都变成灰色了&#xff0c;网络上搜到的logback配置大多数没有进行配色&#xff0c;所以会把springboot的默认配色方案给覆盖…

MySQL访问和配置

目录 1.使用MySQL自带的客户端工具访问 2.使用DOS访问(命令行窗口WinR → cmd) 3.连接工具&#xff08;SQLyog或其它&#xff09; MySQL从小白到总裁完整教程目录:https://blog.csdn.net/weixin_67859959/article/details/129334507?spm1001.2014.3001.5502 1.使用MySQL自…

如何实现的手机实景自动直播,都有哪些功能呢?

手机实景自动直播最近真的太火了&#xff0c;全程只需要一部手机&#xff0c;就能完成24小时直播带货&#xff0c;不需要真人出镜&#xff0c;不需要场地&#xff0c;不需要搭建直播间&#xff0c;只需要一部手机就可以了。真人语音讲解&#xff0c;真人智能回复&#xff0c;实…

说说Flink运行模式

分析&回答 1.开发者模式 在idea中运行Flink程序的方式就是开发模式。 2.local-cluster模式 Flink中的Local-cluster(本地集群)模式,单节点运行&#xff0c;主要用于测试, 学习。 3.Standalone模式 独立集群模式&#xff0c;由Flink自身提供计算资源。 4.Yarn模式 把Fl…
最新文章