android--性能优化1--首屏优化&启动速度与执行效率检测

2023-05-16

文章目录

  • 实战篇
  • traceview 工具使用
    • 操作步骤
    • 操作步骤2
  • systrace 工具使用
    • 操作步骤
  • AOP 工具 hugo 的使用
    • 使用方法
    • 效果
  • BlockCanary 使用
  • AOP 工具使用 AspectJ
    • 操作步骤
  • 优化方案:
      • 异步线程优化:
      • 针对主线程需要异步线程的结果所采用的方案 CountDownLauch:
    • 使用启动器
  • 我的APP内应用效果
  • 理论篇
    • 启动时间测量方式
      • 1 ADB命令
    • 启动时间测量方式
      • 2 手动打点 使用LaunchTimer工具类记录时间
    • traceview 工具使用 使用说明
    • Thread 说明: 看图可知有12个线程.
    • flam chart
    • topDown
    • buttomUp
    • 使用traceview注意事项
    • systrace 工具使用 使用说明

  • 我会先把实战篇写在前面, 把理论篇写在后面. 我太清楚实用党是怎么想的了,只想抓紧时间吧APP的性能搞好. 关于原理方面都往后放. 哈哈 . 因为我以前也是这样的. 为了方便快速使用 直接上干货. 先按照教程做,后面有功夫再看理论.

实战篇

卡顿工具 BlockCanary

http://blog.zhaiyifan.cn/2016/01/16/BlockCanaryTransparentPerformanceMonitor/

traceview 工具使用

操作步骤

利用Debug类的startMethodTracing和stopMethodTracing函数分别来打开和关闭日志记录功能。记录两个方法中间所有函数执行的时间统计.
方法执行完后,会在手机sdcard中生成一个dmtrace.trace文件

  1. 第一步: 在MyApplication 的onCreate 最前面输入如下代码
 if (BuildConfig.DEBUG) {
            Debug.startMethodTracing("APP");
        }
  1. 第二步: 在MyApplication 的onCreate 结束位置输入如下代码
 if (BuildConfig.DEBUG) {
            Debug.stopMethodTracing();
    }
  1. 第三步: 找到生成的文件

在/sdcard/Android/data/packageName/files 目录下面 有一个 APP.trace 的文件

从androidstudio 上面打开来看 就有下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Kv6rsBg-1612277341019)(https://raw.githubusercontent.com/liudao01/picture/master/img/QQ%E5%9B%BE%E7%89%8720210130123716.png)]

操作步骤2

使用android studio profiler 双击cpu -> record 按钮 即可有文件

systrace 工具使用

操作步骤

  1. 第一步: 在MyApplication 的onCreate 最前面输入如下代码
        if (BuildConfig.DEBUG) {
            TraceCompat.beginAsyncSection("App_onCreate",0);
//            Debug.startMethodTracing("APP");
        }
  1. 第二步: 在MyApplication 的onCreate 结束位置输入如下代码
        if (BuildConfig.DEBUG) {
            TraceCompat.endSection();
//            Debug.stopMethodTracing();
        }
  1. 第三步: 进入sdk目录 使用脚本命令

我的在这里

E:\dev\sdk\platform-tools\systrace>

执行下面的命令
package-name 是app的名字

./systrace.py -b -t 5 sched gfx view wm am app webview -a <package-name>

./systrace.py -b 32768 -t 5  -a <package-name> 

systrace.py -b 32768 -t 5  -a com.sinochem.www.car.owne -o performance.html sched gfx view wm am app

遇到问题: ImportError: No module named win32con

下载地址 https://pypi.org/project/pypiwin32/219/#files
PyPI(Python Package Index)是python官方的第三方库的仓库,找python2.7对应的版本。

打开网页即可

AOP 工具 hugo 的使用

为什么用这个: 用于埋点计算函数运行的时间. 非侵入性.

使用方法

  1. 项目根目录build.gradle添加hugo插件依赖
classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1'
  1. 主工程或者library的录build.gradle中声明hugo插件。
apply plugin: 'com.jakewharton.hugo'

注意在每个lib里面都要加上 你想在那个lib里面打印就在那个lib里面加上这句
3. 在类或方法上声明@DebugLog注解。


    @Override @DebugLog
    public void onCreate() {
        super.onCreate();
}

效果

2021-01-31 15:03:01.871 26943-26943/com.sinochem.www.car.owner V/MyApplication: ⇢ onCreate()
2021-01-31 15:03:02.161 26943-26943/com.sinochem.www.car.owner V/MyApplication: ⇠ onCreate [289ms]

可以看到运行时间289ms

参考资料:

https://github.com/JakeWharton/hugo

https://juejin.cn/post/6844903945186476040

https://xiaozhuanlan.com/topic/1428095376

BlockCanary 使用

AOP 工具使用 AspectJ

https://ciruy.blog.csdn.net/article/details/102621417?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

https://blog.csdn.net/eclipsexys/article/details/54425414

为什么用这个: 用于埋点计算函数运行的时间. 非侵入性.

操作步骤

Android中使用AspectJ

  1. 第一步:
    在项目的根目录的build.gradle文件中添加依赖,修改后文件如下
repositories {
    jcenter()
}
dependencies {
    classpath 'com.android.tools.build:gradle:2.3.0'
    classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:1.0.8'

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}
  1. 然后在项目或者库的build.gradle文件中添加AspectJ的依赖
compile 'org.aspectj:aspectjrt:1.8.9'

同时在该文件中加入AspectJX模块

apply plugin: 'android-aspectjx'
  1. aspectjx默认会遍历项目编译后所有的.class文件和依赖的第三方库去查找符合织入条件的切点,为了提升编译效率,可以加入过滤条件指定遍历某些库或者不遍历某些库。

includeJarFilter和excludeJarFilter可以支持groupId过滤,artifactId过滤,或者依赖路径匹配过滤

aspectjx {
    //织入遍历符合条件的库
    includeJarFilter 'universal-image-loader', 'AspectJX-Demo/library'
    //排除包含‘universal-image-loader’的库
    excludeJarFilter 'universal-image-loader'
}
  1. 创建性能收集类PreformanceAop
    代码如下,直接拷贝
package android.androidlib.utils;

import android.util.Log;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

/**
 * @author liuml
 * @explain
 * @time 2021/1/30 20:47
 */
@Aspect
public class PreformanceAop {

    /**
     * 针对调用的接口(日志的形式)观察执行时间
     */
    private static final String MyApplication = "call(** com.application.MyApplication.*(..))";
    private static final String AcgGlobalInitImpl = "call(** com.init.AcgGlobalInitImpl.*(..))";
    private static final String SplashActivity = "call(** com.biz.splash.SplashActivity.*(..))";

    /**
     * 方法的执行时长
     */
    @Around(MyApplication + "||" + AcgGlobalInitImpl + "||" + SplashActivity)
    public void getComicsApplicationTime(ProceedingJoinPoint joinPoint) {
        getTime(joinPoint);
    }
    /**
     * 获取一个类中所有方法的执行时长
     * call : 代表的是在方法调用的地方添加代码
     * 第一个 * : 代表的方法的修饰符
     * 第二个 * : 代表的是方法的返回值类型
     * 第三个 * : 类名
     * 第四个 * : 代表的是方法名
     * (..)    : 参数列表
     * 该方法拦截的是: com.example.qydemo1包下的所有类的方法
     */

    private void getTime(ProceedingJoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        String name = signature.toShortString();
        long time = System.currentTimeMillis();
        try {
            joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        LogUtils.d(name + " 花费 " + (System.currentTimeMillis() - time)+" 毫秒");
//        LogUtils.d(name + " cost " + (System.currentTimeMillis() - time));
    }

}


  • 注意 MyApplication = “call(** com.application.MyApplication.*(…))”; 是你想拦截的类,每个人的都不一样我这里只是demo样例

AspectJ 语法

https://juejin.cn/post/6844903941054922760

https://zhuanlan.zhihu.com/p/72575832

https://www.jianshu.com/p/691acc98c0b8

优化方案:

异步线程优化:

在MyApplication 初始化一些第三方库的时候使用线程池异步加载

原来的时间:

2021-01-31 15:03:01.871 26943-26943/com.sinochem.www.car.owner V/MyApplication: ⇢ onCreate()
2021-01-31 15:03:02.161 26943-26943/com.sinochem.www.car.owner V/MyApplication: ⇠ onCreate [289ms]

效果:

2021-01-31 16:46:45.652 26568-26568/com.sinochem.www.car.owner V/MyApplication: ⇢ onCreate()
2021-01-31 16:46:45.882 26568-26568/com.sinochem.www.car.owner V/MyApplication: ⇠ onCreate [229ms]

优化了60多 毫秒.

针对主线程需要异步线程的结果所采用的方案 CountDownLauch:

不仅可以用在这里. 也可以用在其他地方.

比如在第一个页面就需要异步的结果,就可以使用 CountDownLauch

countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。

是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。

使用方法:

  1. 创建
 private CountDownLatch mCounDownLatch = new CountDownLatch(1);

这里的1 是指有几个地方用到了,也就是说异步任务有几个需要主线程确定执行完毕的.

  1. 使用
   ThreadManager.getDownloadPool().execute(new Runnable() {
            @Override
            public void run() {
                //屏幕适配
                configUnits();
                mCounDownLatch.countDown();
            }
        });

//在代码的最后 也就是需要确定的地方加上这个
   try {
            mCounDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

这样就形成了 必须等屏幕适配结束 才继续.

使用启动器

为什么采用启动器. 比如多个异步任务,第二个任务需要第一个任务的结果.这样就不好处理了,任务之间有以来关系不好处理. 另一方面不好统计, 代码也不优雅且维护成本高.

启动器核心思想: 充分利用cpu多核,自动梳理任务顺序

  • 代码task化,启动逻辑抽象为Task(比如初始化每一个初始化的操作进行抽象,以及分类)
  • 根据素有任务以来关系排序生成一个有向无环图.(对所有任务进行排序)
  • 多现场按照排序后的优先级依次执行

这个有点像gradle 的task了 思想应该是共通的

启动流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kNtifQG7-1612277341022)(https://raw.githubusercontent.com/liudao01/picture/master/img/20210131172532.png)]

我的APP内应用效果

理论篇

启动时间测量方式

1 ADB命令

adb shell am start -W packegname/首屏activity
  • thisTime : 最后一个Activity启动耗时
  • TotalTime : 所有Activity 启动耗时
  • WaitTime : AMS 启动Activity 的总耗时.

特征: 线下方便. 非严谨, 无法带到线上.

启动时间测量方式

2 手动打点 使用LaunchTimer工具类记录时间

  • 抽取一个类LaunchTimer 用作工具打点的类
  • 代码如下: 拷贝拿走
public class LaunchTimer {

    private static long sTime;

    public static void startRecord() {
        sTime = System.currentTimeMillis();
    }

    public static void endRecord() {
        endRecord("");
    }

    public static void endRecord(String msg) {
        long cost = System.currentTimeMillis() - sTime;
        LogUtils.d(msg + " cost " + cost + "ms");
    }

}

  • 首页若有列表,在列表adapter里面打点
boolean mHasRecorde;


  if (helper.getAdapterPosition() == 0 && !mHasRecorde) {
            mHasRecorde = true;
            helper.getView(R.id.item_container).getViewTreeObserver()
                    .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                        @Override
                        public boolean onPreDraw() {
                            helper.getView(R.id.item_container).getViewTreeObserver().removeOnPreDrawListener(this);
                            LaunchTimer.endRecord("feed show");
                            return true;
                        }
                    });
        }
  • 在MainActivity里面的 onWindowFocesChanged 里面打点

  • 代码如下

 @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        LaunchTimer.endRecord("onWindowFocusChanged");
    }

  • 打印效果如下:
 feed show cost 1611909626616ms
 onWindowFocusChanged cost 1611909627011ms
  • 手动打点误区: onWindowFocusChanged 只是首帧时间 并不是用户所看到的时间
  • 正解: 真实数据展示, (首页若有列表)feed第一条展示的时候,在adapter里面加上监听/ 页面展示的时候

所以我们认为应当将feed第一条展示的时候,当做启动开始时间,在onWindowFocusChanged 是当做启动时间是偏早的.

traceview 工具使用 使用说明

startMethodTracing 有几个重载的方法.

     * @param tracePath Path to the trace log file to create. If {@code null},
     *            this will default to "dmtrace.trace". If the file already
     *            exists, it will be truncated. If the path given does not end
     *            in ".trace", it will be appended for you.
     * @param bufferSize The maximum amount of trace data we gather. If not
     *            given, it defaults to 8MB.
     */
    public static void startMethodTracing(String tracePath, int bufferSize) {
        startMethodTracing(tracePath, bufferSize, 0);
    }

下面是解析

  /**
     * tracePath 是路径  bufferSize 文件最大的大小 默认8M  0是个flag 只有一个选项
     */
    startMethodTracing(tracePath, bufferSize, 0);

下表是Traceview界面每个字段表示的含义

列名描述
Name该线程运行过程中所调用的函数名
Incl Cpu Time某函数占用的CPU时间,包含内部调用其它函数的CPU时间
Excl Cpu Time某函数占用的CPU时间,但不含内部调用其它函数所占用的CPU时间
Incl Real Time某函数运行的真实时间(以毫秒为单位),内含调用其它函数所占用的真实时间
Excl Real Time某函数运行的真实时间(以毫秒为单位),不含调用其它函数所占用的真实时间
Call+Recur Calls/Total某函数被调用次数以及递归调用占总调用次数的百分比
Cpu Time/Call某函数调用CPU时间与调用次数的比。相当于该函数平均执行时间
Real Time/Call同CPU Time/Call类似,只不过统计单位换成了真实时间
  • 图表如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J3qxR0Li-1612277341026)(https://raw.githubusercontent.com/liudao01/picture/master/img/QQ%E5%9B%BE%E7%89%8720210130123716.png)]

图表说明:

Thread 说明: 看图可知有12个线程.

左边的图表作用很大:

  • 系统API 是橙色
  • 应用自身的调用是绿色
  • 第三方的 sdk是蓝色

flam chart

重要性不高

火焰图 只用来收集相同函数调用的次数

topDown

告诉我们函数的调用列表, 右键点击 jump to source 可以跳转到源码

buttomUp

重要性不高

用于显示一个函数的调用列表, 和topDown 是相反的

使用traceview注意事项

  • 运行时开销很大 程序一定会变慢. 可能会带骗优化方向
  • 新版本是用cpu profiler

知道哪个函数耗时,就可以逐个优化耗时操作了

systrace 工具使用 使用说明

  • 结合Android内核的数据,生成html报告

  • API18以上使用,推荐TraeCompat

  • systrace 实际上是个python脚本.

  • 脚本解析

systrace.py -b 32768 -t 5  -a com.sinochem.www.car.owne -o performance.html sched gfx view wm am app

-b 是生成最大文件的大小 , -t 是监听事件 , -a 后面跟的是包名 , -o 后面是生成的文件名.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android--性能优化1--首屏优化&启动速度与执行效率检测 的相关文章

  • socket网络编程select使用方法

    文章以及源码均为原创 xff0c 当然欢迎转载 xff0c 转载请加说明 server h int select int nfds fd set readfds fd set writefds fd set exceptfds const
  • 海豚蓝牙ASIO软件设置方法

    1 为什么要使用海豚蓝牙音箱 xff0c 能带给我什么样的音乐体验 目前市面上的蓝牙音箱基本上是一个全频段的喇叭来播放CD音质的音乐 xff0c 如果是立体声的是不能通过一个喇叭来播放 xff0c 无法实现空间上的立体效果 xff0c 必须
  • pixhawk学习笔记-----mavlink

    mavlink协议 一帧数据的长度为8到263个字节 其具体的解析如下所示 xff1a 字节的索引 值 含义 0 0xFE V1 0 帧头 xff0c 表示一帧数据的开始 1 0 255 表示有效数据的长度 2 0 255 包序列 xff0
  • Ubuntu搭建本地web站点,并内网穿透实现公网访问

    本次教程我们通过搭建Apache服务 xff0c 部署一个简单的静态样例站点 xff0c 并使用cpolar内网穿透将内网样例站点发布到公网来进行演示 1 设置 Apache Web 服务器 1 1 安装Apache Web span cl
  • 为何某些公司不允许使用 C++ STL?

    最初开始禁用 C 43 43 STL xff0c 更多地是早期项目编码实践中留下的惯例 xff0c 被后来的程序员继承下来 老项目中这种选择尤其地多 不过如果有人将其上升到公司行为在不同项目中全面禁用 STL xff0c 则没有必要 xff
  • 手把手教你无线数传电台透明传输的配置全攻略

    透明传输 功能说明 任意电台发送数据 xff0c 具有相同地址且相同信道的电台均可同时接收数据 数据以透明方式发送和接收 xff0c 所发即所收 电台设置 1 需将 OPTION 特殊功能寄存器的第 7 位配置成 0 xff0c 透明传输模
  • unity寻路插件(A* Pathfinding)小结

    A Pathfinding 详细使用教程 基本功能 1 astarpath cs 核心组件 xff0c 相当于 路 xff0c 场景里应该只存在一个 2 Seeker cs 相当于一个代理 xff0c 寻找路径 xff0c 需要绑定在每一个
  • Socket网络通信C++编程总结

    概述 Socket编程有三种 xff0c 流式套接字 xff08 SOCK STREAM xff09 数据报套接字 SOCK DGRAM 原始套接字 SOCK RAW 前两者较常用 xff0c 这里简单总结前两种编程步骤以及一些参考资料 编
  • 【STM32+cubemx】0029 HAL库开发:HMC5883L磁力计的应用(电子指南针)

    今天我们来学习电子磁力计HMC5883L的使用 先介绍磁力计的基础知识 xff0c 再给一个获取磁力计数据的例子 xff0c 最后讲解HMC5883L磁力计的校准 xff0c 以及一些使用中的经验 1 xff09 HMC5883L磁力计的基
  • stm32F103R6之BKP(备份寄存器)

    目录 概述 侵入检测 RTC校准 概述 Stm32F103有42个16位的备份寄存器 他们处在备份域里 xff0c 当VDD电源被切断 xff0c 他们仍然由VBAT维持供电 当系统在待机模式下被唤醒 xff0c 或系统复位或电源复位时 x
  • Stm32F103R6之控制器局域网

    目录 概述 双CAN bxCAN工作模式 CAN协议特点 xff1a ISO11898标准CAN物理特性 CAN协议帧 概述 bxCAN是基本扩展CAN Basic Extended CAN 的缩写 xff0c 它支持CAN协议2 0A和2
  • 如何输出一个数的二进制数

    实现思想 xff1a 二进制数是以bit为操作数 xff0c 所以要想将一个数转换为二进制数 xff0c 我们需要先要将输入的数字转化为二进制数 xff0c 然后从高位到低位判断每一位是 1 还是 0 xff0c 最后把对应的 1 和 0
  • 使用libcurl库编写HTTP客户端(包括GET/POST/HTTPS)

    最近在写一个应用程序 需要与HTTP服务器进行数据交互 于是乎自己写了一个类似wget的功能的客户端 实现很简单 但是功能不给力 只可基本功能 于是又在网上找了找 发现使用libcurl库很方便 很强大 比起wget之类的 强大不是一点点
  • 修改系统默认shell为bash

    xfeff xfeff 从 ubuntu 6 10 开始 xff0c ubuntu 就将先前默认的bash shell 更换成了dash shell xff1b 其表现为 bin sh 链接倒了 bin dash而不是传统的 bin bas
  • 如何解决Reporting Services目录数据库文件存在的问题

    出处 xff1a http blog sina com cn s blog 6bace3cc0101jlxv html 错误提示 xff1a 自检时提示 Reporting Services目录数据库文件存在 失败 xff0c Report
  • 无线射频专题《射频合规,2.4GHz WIFI测试指标详解》

    目录 引言 Transmitter Power 发送功率 Transmit Spectrum Mask 发送信号频谱模版 Frequency Error 频率误差 EVM 矢量误差幅度 Band Edges and harmonics 频带
  • 获取当前访问的路径

    String returl 61 request getRequestURL 43 request getQueryString 61 61 null 34 34 34 34 43 request getQueryString
  • 抓取百度关键词排名

    最近在做百度关键词排名的功能 xff0c 发现网上资源比较少 xff0c 于是自己琢磨了一下 xff0c 写一下笔记 xff1b 本文重点在于提供思路 xff0c 请不要过分依赖 xff0c 本文主要靠抓取页面标签来完成 xff0c 如果百
  • 抓取百度关键词排名、标题、连接、描述

    抓取百度关键词排名 标题 连接 描述 转载请标明出处 最近在做百度关键词排名的功能 xff0c 发现网上资源比较这里写代码片少 xff0c 于是自己琢磨了一下 xff0c 写一下笔记 xff1b 本文重点在于提供思路 xff0c 请不要过分
  • Windows Server 2008远程桌面端口的修改

    Windows Server 2008远程桌面端口系统默认的是3389端口 xff0c 但出于安全考虑 xff08 谁都不希望任何都可以远程连接到自己的服务器吧 xff0c 哈哈 xff09 xff0c 经常我们把系统默认的3389端口更改

随机推荐

  • jsp 登陆成功后,显示登录的用户名

    首先在登陆界面将用户名保存起来 xff0c 我这里是将用户名提交到Servlet然后再进行保存 xff0c 从登录界面取用户参数 String uname 61 request getParameter 34 userName 34 req
  • 背景图片随网页的变化而变化(指大小)

    lt DOCTYPE HTML PUBLIC 34 W3C DTD HTML 4 01 Transitional EN 34 gt lt html xmlns 61 34 http www w3 org 1999 xhtml 34 gt l
  • 为什么vscode用久了电脑速度变慢?

    1 vscode 插件占用的内存 1 已经安装的插件 2 插件占用内存 我可以看到 xff0c vs code 这个程序下面有多个进程在跑 xff0c 插件占用的内存比我电脑剩下所有占用的内存还要高 xff0c 但是vs code 性能还是
  • ROS基础学习(一)---创建工作空间

    工作空间 xff08 workspace xff1a 是一个存放工程开发相关文件的文件夹 src xff1a 代码空间 xff08 Source Space build 编译空间 xff08 Build Space devel 开发空间 x
  • 一个简单的爬虫程序,爬取网站的图片

    最简单的爬虫是分析网页 xff0c 如果要爬取图片 xff0c 就要将图片在网页中的格式进行分析 xff0c 取到图片的连接 xff0c 接着下载图片 xff1b 由于网页中还会链接到其他的网页 xff0c 所以需要将其中的所有网页取出 x
  • python文件操作及引申的代码行数统计

    文件操作一般包括文件的读写 xff0c 文件夹的创建 xff0c 文件夹的删除等 第一部分 xff1a python文件读写的基本操作 python打开文件一般使用 open函数 xff1a open file mode 61 39 r 3
  • 超声波测距仪

    基本原理 超声波是利用反射的原理测量距离的 xff0c 被测距离一端为超声波传感器 xff0c 另一端必须有能反射超声波的物体 测量距离时 xff0c 将超声波传感器对准反射物发射超声波 xff0c 并开始计时 xff0c 超声波在空气中传
  • Authorization 值中Bearer空格加token值在python接口请求中如何实现

    在项目中每个接口请求都需要Authorization 值 xff0c 而Authorization他的值必须 Bearer 加token值 xff0c 刚开始自己忘记添加Bearer 接口请求一直拒绝访问 xff0c 后来用fiddler抓
  • printf格式化字符串漏洞原理解析

    读任意地址 printf 34 x 34 只给格式化字符串 xff0c 而不给参数 xff0c 会导致内存泄漏从而读到内存中其他地址的数据 N x参数可以以16进制方式打印第N个参数的内容 xff0c 通过修改N xff0c 我们可以遍历栈
  • 教程丨利用微软官方工具制作U盘安装Win10系统

    一 制作Win10安装U盘 1 登录网站 https www microsoft com zh cn software download windows10 下载 MediaCreationTool 工具 xff0c 这里我们直接点击 立即
  • Linux常用命令大全

    发布jar包 nohup java jar xxxx jar gt dev null 2 gt amp 1 amp 修改nginx conf 后刷新配置 usr local nginx sbin nginx t 测试配置文件修改是否正常 u
  • Zab协议详解

    什么是Zab协议 xff1f Zab协议 的全称是 Zookeeper Atomic Broadcast xff08 Zookeeper原子广播 xff09 Zookeeper 是通过 Zab 协议来保证分布式事务的最终一致性 Zab协议是
  • 谷歌浏览器安装json格式化插件

    实际开发工作中经常用到json数据 xff0c 那么就会有这样一个需求 xff1a 在谷歌浏览器中访问URL地址返回的json数据能否按照json格式展现出来 比如 xff0c 在谷歌浏览器中访问 xff1a http jsonview c
  • Seata详解(一)

    分布式事务 事务是数据库的概念 xff0c 数据库事务 xff08 ACID xff1a 原子性 一致性 隔离性和持久性 xff09 xff1b 分布式事务的产生 xff0c 是由于数据库的拆分和分布式架构 微服务 带来的 xff0c 在常
  • RocketMQ的事务消息和改造

    什么是 rmq分布式事务消息 xff1f Apache RocketMQ在4 3 0版中已经支持分布式事务消息 xff0c 这里RocketMQ采用了2PC的思想来实现了提交事务消息 xff0c 同时增加一个补偿逻辑来处理二阶段超时或者失败
  • session和token区别

    一 session的状态保持及弊端 xff08 1 xff09 当用户第1次通过浏览器使用用户名和密码访问服务器时 xff0c 服务器对用户名和密码进行验证 xff08 2 xff09 验证成功后 xff0c 在服务器端生成并保存sessi
  • 关于阿里云对RocketMQ的topic,tag,consumer关系的理解

    什么是订阅关系一致 消息队列RocketMQ版 阿里云帮助中心 RocketMQ 中Topic Tag GroupName基本概念介绍 Young丶的博客 CSDN博客 rocketmq topic和group的区别 转载
  • MySql Workbench 8.0汉化插件分享

    打开workbench的安装数据目录 xff0c 路径是 xff1a C Program Files MySQL MySQL Workbench 8 0 CE data 打开以后 xff0c 可以看到下面有一堆的xml结尾的文件 xff0c
  • Java-Jdk12版本下载后没有Jre的解决方案以及配置环境变量

    新本Jdk12版本下载后不像以前的版本会自动生成Jre文件夹 xff0c 通过dos命令行可以解决 1 下载jdk12 网址 xff1a https www oracle com technetwork java javase downlo
  • android--性能优化1--首屏优化&启动速度与执行效率检测

    文章目录 实战篇traceview 工具使用操作步骤操作步骤2 systrace 工具使用操作步骤 AOP 工具 hugo 的使用使用方法效果 BlockCanary 使用AOP 工具使用 AspectJ操作步骤 优化方案 异步线程优化 针