Android APP性能及专项测试
Android篇
1. 性能测试
- Android性能测试分为两类: 1、一类为rom版本(系统)的性能测试 2、一类为应用app的性能测试
- Android的app性能测试包括的测试项比如: 1、资源消耗 2、内存泄露 3、电量功耗 4、耗时 5、网络流量消耗 6、移动终端相关资源利用率 7、帧率 8、渲染等等....
- 工具: (工具的原理都是基于调用android底层的一些api来获取到测试所用到的值)GT等
- 测试方法: 1、设计场景 :手工或自动化场景 2、获取数据:可获取的数据包括:内存、cpu、电量功耗、hprof(内存泄露分析文件)、响应时间等等。。。。配合手工或自动化场景来获取数据(最好多取几次而且每次配合不同的设备看平均值)作为最后的对比分析 3、结果分析 :拿到数据后分析哪些模块的数据异常再去Check code定位问题的原因
- Android系统的几种场景状态: 1、空闲状态: 指打开应用后,点击home键让应用后台运行,此时应用处于的状态叫做空闲 2、中等规格和满规格状态:中等规格和满规格指的是对应用的操作时间的间隔长短不一,中等规格时间较长,满规格时间较短
1.1 内存篇
背景知识: C/C++申请的内存空间在native heap中,而java申请的内存空间则在dalvik heap中。这个是因为Android系统对dalvik的vmheapsize作了硬性限制,当java进程申请的java空间超过阈值时,就会抛出OOM异常(这个阈值可以是48M、24M、16M等,视机型而定),可以通过adb shell getprop | grep dalvik.vm.heapgrowthlimit查看此值。也就是说,程序发生OMM并不表示RAM不足,而是因为程序申请的java heap对象超过了dalvik vmheapgrowthlimit。也就是说,在RAM充足的情况下,也可能发生OOM。 这样的设计似乎有些不合理,但是Google为什么这样做呢?这样设计的目的是为了让Android系统能同时让比较多的进程常驻内存,这样程序启动时就不用每次都重新加载到内存,能够给用户更快的响应。迫使每个应用程序使用较小的内存,移动设备非常有限的RAM就能使比较多的app常驻其中。但是有一些大型应用程序是无法忍受vmheapgrowthlimit的限制的 实际上dalvik.vm.heapgrowthlimit和dalvik.vm.heapsize都是java虚拟机的最大内存限制,应用如果不想在dalvikheap达到heapgrowthlimit限制的时候出现OOM,需要在Manifest中的application标签中声明android:largeHeap=“true”,声明后应用dalvik heap达到heapsize的时候才会出现OOM
内存测试中的测试子项:
- 1)空闲状态下的应用内存消耗情况
- 2)中等规格状态下的应用内存消耗情况
- 3)满规格状态下的应用内存消耗情况
- 4)应用内存峰值情况
- 5)应用内存泄露情况
- 6)应用是否常驻内存
- 7)压力测试后的内存使用情况
内存问题现象:
- 1)内存抖动
- 2)大内存对象被分配
- 3)内存不断增长
- 4)频繁GC
内存数据获取:
- 1、各种linux命令(top、free、meminfo…)
- 2、通过dumpsys
adb shell dumpsys meminfo [pakagename | pid]
- 3、通过/system/xbin/procrank工具
adb shell procrank
- 说明: VSS – Virtual Set Size 虚拟耗用内存(包含共享库占用的内存) RSS – Resident Set Size 实际使用物理内存(包含共享库占用的内存) PSS – Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存) USS – Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存) USS 是针对某个进程开始有可疑内存泄露的情况,是一个程序启动了会产生的虚拟内存,一旦这个程序进程杀掉就会释放。不过USS需要通过root的手机。一般没有root的手机我们可以获取PSS。而PSS通过如下命令来获取:
adb shell dumpsys meminfo <Package Name>|grep TOTAL
4、通过android提供的procrank 1)首先去google获取procrank、procmem、libpagemap.so三个文件 2)然后push文件,执行 adb push procrank /system/xbin adb push procmem /system/xbin adb push libpagemap.so /system/lib 3)赋权 adb shell chmod 6755 /system/xbin/procrank adb shell chmod 6755 /system/xbin/procmem adb shell chmod 6755 /system/lib/libpagemap.so , 4)在开启工具记录 adb shell procrank |grep packagename >/address/procrank.txt 5、通过android提供的ActivityManager的getMemoryInfo(ActivityManager.MemoryInfo outInfo)(这个方法是写一个简单的app去监控的时候用到的,轻便简单)
复制
private void GetMemory()
{
final ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(info);
Log.i(tag,"系统剩余内存:"+(info.availMem >> 10)+"k");
Log.i(tag,"系统是否处于低内存运行:"+info.lowMemory);
Log.i(tag,"当系统剩余内存低于"+info.threshold+"时就看成低内存运行");
}
6、Memory Monitor (android studio的插件) 【makedown???】4. /proc/meminfo文件里列出的字段解释:
复制
MemTotal: 所有可用RAM大小。 MemFree: LowFree与HighFree的总和,被系统留着未使用的内存。 Buffers: 用来给文件做缓冲大小。 Cached: 被高速缓冲存储器(cache memory)用的内存的大小(等于diskcache minus SwapCache)。 SwapCached:被高速缓冲存储器(cache memory)用的交换空间的大小。已经被交换出来的内存,仍然被存放在swapfile中,用来在需要的时候很快的被替换而不需要再次打开I/O端口。 Active: 在活跃使用中的缓冲或高速缓冲存储器页面文件的大小,除非非常必要,否则不会被移作他用。 Inactive: 在不经常使用中的缓冲或高速缓冲存储器页面文件的大小,可能被用于其他途径。 SwapTotal: 交换空间的总大小。 SwapFree: 未被使用交换空间的大小。 Dirty: 等待被写回到磁盘的内存大小。 Writeback: 正在被写回到磁盘的内存大小。 AnonPages:未映射页的内存大小。 Mapped: 设备和文件等映射的大小。 Slab: 内核数据结构缓存的大小,可以减少申请和释放内存带来的消耗。 SReclaimable:可收回Slab的大小。 SUnreclaim:不可收回Slab的大小(SUnreclaim+SReclaimable=Slab)。 PageTables:管理内存分页页面的索引表的大小。 NFS_Unstable:不稳定页表的大小。
5. android检查内存泄露步骤:
复制
1、运行Monkey进行压力测试: adb shell monkey -p cn.microinvestment.weitou --pct-touch 100 --ingore-crashes --throttle 1000 -s 100 -v -v 50
2、监控内存值,如果出现过大等递增异常则保存HPROF文件(hprof文件是Java 虚拟机的Heap快照)用于分析查看应用内存的命令: adb shell dumpsys meminfo cn.microinvestment.weitou(进程名)
如果发现内存过大,则保存HPROF文件:adb shell am dumpheap <进程名> <保存路径>
3、分析hprof文件 用工具MAT来查看,首先还要这个HPROF文件转换成MAT可读的文件 在Android SDK tool里面有个hprof-conv命令: hprof-conv <原HPROF文件路径> <转换后的HPROF路径> hprof-conv a.hprof b.hprof
4、用MAT工具打开转换后的HPROF文件 一般选择Leak Suspects Report(通过SQL语句来查询对象有没有被释放掉,如果有多个相同的对象,则会存在内存泄露的问题)
1.2 CPU篇
- CPU测试中的测试子项: 1)空闲状态下的应用CPU消耗情况 2)中等规格状态下的应用CPU消耗情况 3)满规格状态下的应用CPU消耗情况 4)应用CPU峰值情况
- CPU数据获取: 1)
adb shell dumpsys cpuinfo | grep packagename
2)top命令adb shell top -m 10 -s cpu
#查看占用cpu最高的前10个程序(-t 显示进程名称,-s 按指定行排序,-n 在退出前刷新几次,-d 刷新间隔,-m 显示最大数量)adb shell top | grep PackageName > /address/cpu.txt
1.3 流量篇
- 概念: 中等负荷:应用正常操作 高负荷:应用极限操作
- 流量测试中的测试子项: 1、应用首次启动流量值 2、应用后台连续运行 2 小时的流量值 3、应用高负荷运行的流量峰值 4、应用中等负荷运行时的流量均值
- 获取流量数据: 1、tcpdump+wireshark 2、/proc/net/目录下相关文件 cat /proc/net/dev 获取系统的流量信息 3、查询应用的pid: adb shell ps | grep tataufo #如:31002 通过PID获取该应用的流量数据: adb shell cat /proc/31002/net/dev (wlan0代表wifi上传下载量标识, 单位是字节可以/1024换算成KB, 打开手机飞行模式再关掉就可以将wlan0中的值初始化0) 4、查询应用的pid: adb shell ps | grep tataufo #如:31002 通过PID获取UID:adb shell cat /proc//status 通过UID获取:adb shell cat /proc/net/xt_qtaguid/stats | grep 31002 5、通过adb shell dumpsys package来获取应用的uid信息,然后在未操作应用之前,通过查看 : adb shell cat /proc/uid_stat/uid/tcp_rcv adb shell cat /proc/uid_stat/uid/tcp_snd 获取到应用的起始的接收及发送的流量,然后我们再操作应用,再次通过上述2条命令可以获取到应用的结束的接收及发送的流量,通过相减及得到应用的整体流量消耗 6、Android代码:Android的TrafficStats类
1.4 功耗篇
- 功耗测试中的测试子项: 1、手机安装目标APK前后待机功耗无明显差异 2、常见使用场景中能够正常进入待机,待机电流在正常范围内 3、长时间连续使用应用无异常耗电现象
- 功耗测试方法: 方法一:软件 1、采用市场上提供的第三方工具,如金山电池管家之类的。 2、就是自写工具进行,这里一般会使用3种方法: 1)基于android提供的PowerManager.WakeLock来进行 2)比较复杂一点,功耗的计算=CPU消耗+Wake lock消耗+数据传输消耗+GPS消耗+Wi-Fi连接消耗 3)通过 adb shell dumpsys battery来获取 3、battery-historian(google开源工具) 方法二:硬件 一般使用万用表或者功耗仪安捷伦进行测试,使用功耗仪测试的时候,需要制作假电池来进行的,有些不能拔插电池的手机还需要焊接才能进行功耗测试
1.5 GPU篇(FPS)
- 概念: 过度绘制: 界面显示的activity套接了多层而导致 帧率:屏幕滑动帧速率 帧方差: 屏幕滑动平滑度 **FPS:**Frames Per Second 每秒显示的帧数 根据人眼的生理结构,帧率高于24时就被认为是连贯的。对于游戏画面30fps是最低能接受的,60fps逼真感,如果帧率高于屏幕刷新频率就是浪费。要达到30fps,每帧所占用的时间要小于33毫秒
- GPU测试中的测试子项: 1、界面过度绘制 2、屏幕滑动帧速率 3、屏幕滑动平滑度
- 过度绘制测试:(人工进行测试) 打开开发者选项中的显示GPU过度绘制(Debug GPU overdraw) 验收的标准: 1、不允许出现黑色像素 2、不允许存在4x过度绘制 3、不允许存在面积超过屏幕1/4区域的3x过度绘制(淡红色区域)
- 屏幕滑动帧速率测试: 方法一: 1.手机端打开开发者选项中的启用跟踪后勾选Graphics和View 2.启动SDK工具Systrace,勾选被测应用,点击Systrace,在弹出的对话框中设置持续抓取时间,在trace taps下面勾选gfx及view选项 3.手工滑动界面可以通过节拍来进行滑动或者扫动,帧率数据会保存到默认路径下,默认名称为trace.html 4.将trace.html文件拷贝到linux系统下通过命令进行转换,生成trace.csv文件 grep 'postFramebuffer' trace.html | sed -e 's/.]\W//g' -e 's/:.*$//g' -e 's/.//g' > trace.csv 5.用excel打开文件计算得到帧率 方法二: 硬件的方法,打开高速相机,开启摄像模式,录制手工滑动或者扫动被测应用的视频,再通过人工或者程序数帧的方法对结果进行计算得到帧率
- 屏幕滑动平滑度的测试: 方法如同帧率测试,唯一的差异就是最后的结果计算公式的差异
- 捕获app帧率(android流畅度FPS测试): 1、打开手机开发者选项,勾选GPU显示配置文件(系统会记录保留每个界面最后128帧图像绘制的相关时间信息) 2、adb shell dumpsys gfxinfo com.xxx.xxx > zinfo.txt 3、结果数据分析 Profile data in ms部分: Draw: 创建显示列表的时间(DisplayList),所有View对象OnDraw方法占用的时间 Process: Android 2D渲染引擎执行显示列表所花的时间,View越多时间越长 Execute:将一帧图像交给合成器(compsitor)的时间,较小
- 其他工具: GameBench 测试android app的FPS工具 Gfxinfo 查看app绘制性能工具
1.6 响应时间篇
- 理解: 1)从单击事件触发到容器启动NativeAPP消耗的时间(埋点) 2)NativeAPP完整启动消耗的时间(可以通过system.log获取) 3)Native调用RPC请求方法的延迟时间(埋点) 4)RPC请求发出去过程中的具体数据(req_size req_header req_time等,通过埋点获取) 5)RPC请求返回的具体数据(res_size res_header res_time等,通过埋点获取) 6)本地解析返回数据所消耗的时间(埋点或者TraceView工具可获取) 7)界面渲染的时间(可以通过慢速摄像机或者埋点获取)
- android app启动时间测试 (安卓Activity启动过程性能剖视: http://www.rudy-yuan.net/archives/59/)
- 应用的启动时间的测试,分为三类: 1)首次启动 --应用首次启动所花费的时间 2)非首次启动 --应用非首次启动所花费的时间 3)应用界面切换--应用界面内切换所花费的时间
- 应用启动时间数据获取: 1、
adb logcat > /address/logcat.txt
#所有activity打印的日志find “Displayed” /address/logcat.txt > /newaddress/fl.txt
#通过日志过滤关键字Displayed来过滤find “ActivityName” /newaddress/fl.txt > /newaddress/last.txt
#通过activity名来过滤获取所测应用 通过计算activity最后剩余的时间之和即可 2、硬件测试, 使用高速相机或者手机采用录像的方法把应用启动过程给录制下来,然后通过人工数帧或者程序数帧的方式计算启动时间
2 弱网测试
测试方法:
- 1、使用真实的SIM卡、运营商网络来进行测试(移动无线测试中存在一些特别的BUG必须在特定的真实的运营商网络下才会发现)
- 2、通过代理的方式模拟弱网环境进行测试(charles 硬延迟)
- 3、连接模拟弱网的热点进行测试
热点模拟方法:
- 1)通过设置iPhone的开发者模式之后共享热点(硬延迟)
- 2)FaceBook开源的ATC(可使用树莓派来搭建ACT环境)
用户体验需要做的:
- 1)在应用中统一弱网加载的界面样式、动画效果、菊花icon等
- 2)统一网络错误、服务端错误、超时等展现给用户的界面和提示语句
- 3)定义清楚在每个中间过程是的用户交互行为
最后: 为了回馈铁杆粉丝们,我给大家整理了完整的软件测试视频学习教程,朋友们如果需要可以自行免费领取 【保证100%免费】
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
资料获取方式:
相关文章:

Android APP性能及专项测试
Android篇 1. 性能测试 Android性能测试分为两类: 1、一类为rom版本(系统)的性能测试 2、一类为应用app的性能测试Android的app性能测试包括的测试项比如: 1、资源消耗 2、内存泄露 3、电量功耗 4、耗时 5、网络流量消耗 6、移动…...

人工智能自然语言处理:N-gram和TF-IDF模型详解
人工智能自然语言处理:N-gram和TF-IDF模型详解 1.N-gram 模型 N-Gram 是一种基于统计语言模型的算法。它的基本思想是将文本里面的内容按照字节进行大小为 N 的滑动窗口操作,形成了长度是 N 的字节片段序列。 每一个字节片段称为 gram,对所…...

linux内核调试工具记录
Linux性能测试使用的工具在github网站可见,网址如下: slides: http://www.slideshare.net/brendangregg/linux-performance-analysis-new-tools-and-old-secrets video: https://www.usenix.org/conference/lisa14/conference-program/presentation/greg…...

XSS 攻击的检测和修复方法
XSS 攻击的检测和修复方法 XSS(Cross-Site Scripting)攻击是一种最为常见和危险的 Web 攻击,即攻击者通过在 Web 页面中注入恶意代码,使得用户在访问该页面时,恶意代码被执行,从而导致用户信息泄露、账户被…...

Spring后置处理器BeanFactoryPostProcessor与BeanPostProcessor源码解析
文章目录 一、简介1、BeanFactoryPostProcessor2、BeanPostProcessor 二、BeanFactoryPostProcessor 源码解析1、BeanDefinitionRegistryPostProcessor 接口实现类的处理流程2、BeanFactoryPostProcessor 接口实现类的处理流程3、总结 三、BeanPostProcessor 源码解析 一、简介…...

NXP i.MX 6ULL工业开发板硬件说明书( ARM Cortex-A7,主频792MHz)
前 言 本文档主要介绍TLIMX6U-EVM评估板硬件接口资源以及设计注意事项等内容。 创龙科技TLIMX6U-EVM是一款基于NXP i.MX 6ULL的ARM Cortex-A7高性能低功耗处理器设计的评估板,由核心板和评估底板组成。核心板经过专业的PCB Layout和高低温测试验证,稳…...

Ubuntu 放弃了战斗向微软投降
导读这几天看到 Ubuntu 放弃 Unity 和 Mir 开发,转向 Gnome 作为默认桌面环境的新闻,作为一个Linux十几年的老兵和Linux桌面的开发者,内心颇感良多。Ubuntu 做为全世界Linux界的桌面先驱者和创新者,突然宣布放弃自己多年开发的Uni…...

高并发的哲学原理(六)-- 拆分网络单点(下):SDN 如何替代百万人民币的负载均衡硬件
上一篇文章的末尾,我们利用负载均衡器打造了一个五万 QPS 的系统,本篇文章我们就来了解一下负载均衡技术的发展历程,并一起用 SDN(软件定义网络)技术打造出一个能够扛住 200Gbps 的负载均衡集群。 负载均衡发展史 F5 …...

用OpenCV进行图像分割--进阶篇
1. 引言 大家好,我的图像处理爱好者们! 在上一篇幅中,我们简单介绍了图像分割领域中的基础知识,包含基于固定阈值的分割和基于OSTU的分割算法。这一次,我们将通过介绍基于色度的分割来进一步巩固大家的基础知识。 闲…...

Spring框架概述及核心设计思想
文章目录 一. Spring框架概述1. 什么是Spring框架2. 为什么要学习框架?3. Spring框架学习的难点 二. Spring核心设计思想1. 容器是什么?2. IoC是什么?3. Spring是IoC容器4. DI(依赖注入)5. DL(依赖查找&…...

Unity自定义后处理——Vignette暗角
大家好,我是阿赵。 继续说一下屏幕后处理的做法,这一期讲的是Vignette暗角效果。 一、Vignette效果介绍 Vignette暗角的效果可以给画面提供一个氛围,或者模拟一些特殊的效果。 还是拿这个角色作为底图 添加了Vignette效果后࿰…...

Java读取Excel 单元格包含换行问题
Java读取Excel 单元格包含换行问题 需求解决方案 需求 针对用户上传的Excel数据,或者本地读取的Excel数据。单元格中包含了换行,导致读取的数据被进行了切片。 正常读取如下图所示。 解决方案 目前是把数据读取出来的cell转成字符串后,…...

Django实现接口自动化平台(十)自定义action names【持续更新中】
相关文章: Django实现接口自动化平台(九)环境envs序列化器及视图【持续更新中】_做测试的喵酱的博客-CSDN博客 深入理解DRF中的Mixin类_做测试的喵酱的博客-CSDN博客 python中Mixin类的使用_做测试的喵酱的博客-CSDN博客 本章是项目的一…...

[爬虫]解决机票网站文本混淆问题-实战讲解
前言 最近有遇到很多小伙伴私信向我求助,遇到的问题基本上都是关于文本混淆或者是字体反爬的问题。今天给大家带来其中一个小伙伴的实际案例给大家讲讲解决方法 📝个人主页→数据挖掘博主ZTLJQ的主页 个人推荐python学习系列: ☄️爬虫J…...
【已解决】Flask项目报错AttributeError: ‘Request‘ object has no attribute ‘is_xhr‘
文章目录 报错及分析报错代码分析 解决方案必要的解决方法可能有用的解决方法 报错及分析 报错代码 File "/www/kuaidi/6f47274023d4ad9b608f078c76a900e5_venv/lib/python3.6/site-packages/flask/json.py", line 251, in jsonifyif current_app.config[JSONIFY_PR…...

【Java基础教程】Java学习路线攻略导图——史诗级别的细粒度归纳,持续更新中 ~
Java学习路线攻略导图 上篇 前言1、入门介绍篇2、程序基础概念篇3、包及访问权限篇4、异常处理篇5、特别篇6、面向对象篇7、新特性篇8、常用类库篇 前言 🍺🍺 各位读者朋友大家好!得益于各位朋友的支持和关注,我的专栏《Java基础…...
IntelliJ IDEA 2023.1 更新内容总结
IntelliJ IDEA 2023.1 更新内容总结 * 主要更新内容 * UI 大改版 * 性能改进项 * 其它更新内容IntelliJ IDEA 2023.1 更新内容总结 主要更新内容 IntelliJ IDEA 2023.1 针对新的用户界面进行了大量重构,这些改进都是基于收到的宝贵反馈而实现的。官方还实施了性能增强措施, …...

什么是计算机蠕虫?
计算机蠕虫诞生的背景 计算机蠕虫的诞生与计算机网络的发展密切相关。20世纪60年代末和70年代初,互联网还处于早期阶段,存在着相对较少的计算机和网络连接。然而,随着计算机技术的进步和互联网的普及,计算机网络得以迅速扩张&…...

【机器学习】吴恩达课程1-Introduction
一、机器学习 1. 定义 计算机程序从经验E中学习,解决某一任务T,进行某一性能P,通过P测定在T上的表现因经验E而提高。 2. 例子 跳棋程序 E:程序自身下的上万盘棋局 T:下跳棋 P:与新对手下跳棋时赢的概…...
DBC转excel(python语言)
重复造轮子,只是为了熟悉一下DBC格式。 与同类工具的不同点: 能批量转换在同一文件夹下的所有DBC,省时省力。很多同类工具转换后的excel列宽较小,不能直接显示全部信息。本代码使用了自适应的列宽,看起来更方便。** …...

C++ 类模板三参数深度解析:从链表迭代器看类型推导与实例化(为什么迭代器类模版使用三参数?实例化又会是怎样?)
本篇主要续上一篇的list模拟实现遇到的问题详细讲解:<传送门> 一、引言:模板参数的 "三角锁钥" 在 C 双向链表实现中,__list_iterator类模板的三个参数(T、Ref、Ptr)如同精密仪器的调节旋钮&#x…...
计算机网络物理层基础练习
第二章 物理层 填空题 从通信双方信息交互的方式来看,通信的三种基本方式为单工、半双工和全双工。其中,单工数据传输只支持数据在一个方向上传输,全双工数据传输则允许数据同时在两个方向上传输。最基本的带通调制方法包括三种:…...
第十三篇:MySQL 运维自动化与可观测性建设实践指南
本篇重点介绍 MySQL 运维自动化的关键工具与流程,深入实践如何构建高效可观测体系,实现数据库系统的持续稳定运行与故障快速响应。 一、为什么需要 MySQL 运维自动化与可观测性? 运维挑战: 手动备份容易遗漏或失败; …...
TCP 四次挥手
引言:优雅的告别 在网络通信中,建立连接需要三次握手,而终止连接则需要四次挥手。这种设计体现了 TCP 协议的可靠性和完整性原则。本文将用通俗易懂的方式,深入解析四次挥手的原理、状态转换和实际应用,帮助您掌握这一…...
开源的JT1078转GB28181服务器
JT1078转GB28181流程 项目地址: JT1078转GB28181的流媒体服务器: https://github.com/lkmio/lkm JT1078转GB28181的信令服务器: https://github.com/lkmio/gb-cms 1. 创建GB28181 UA 调用接口: http://localhost:9000/api/v1/jt/device/add 请求体如下…...

BiliNote部署实践
开源地址: https://github.com/JefferyHcool/BiliNote 🚀 快速开始 1. 克隆仓库 git clone https://github.com/JefferyHcool/BiliNote.git cd BiliNote mv .env.example .env2. 启动后端(FastAPI) cd backend pip insta…...
`docker run`、`docker start`、`docker exec` 区别
🧠 先给你一句话理解: docker run ≈ docker create docker start docker exec(第一次) ✅ 三者的区别一览表 命令作用类比真实生活常用场景docker run创建 启动 执行命令(一次性)你买了一台新电脑&am…...

【优选算法 | 队列 BFS】构建搜索流程的核心思维
算法相关知识点可以通过点击以下链接进行学习一起加油!双指针滑动窗口二分查找前缀和位运算模拟链表哈希表字符串模拟栈模拟(非单调栈)优先级队列 很多人学 BFS 的时候都知道“用队列”,但为什么一定是队列?它到底在整个搜索流程中起了什么作…...

【nssctf第三题】[NSSCTF 2022 Spring Recruit]easy C
这是题目,下载附件打开是个C文件 #include <stdio.h> #include <string.h>int main(){char a[]"wwwwwww";char b[]"dvxbQd";//try to find out the flagprintf("please input flag:");scanf(" %s",&a);if…...
Mac电脑上本地安装 MySQL并配置开启自启完整流程
文章目录 一、mysql安装1.1 使用 Homebrew 安装(推荐)1.2 手动下载 MySQL 社区版1.3 常见问题1.4 图形化管理工具(可选) 二、Mac 上配置 MySQL 开机自动启动2.1 使用 launchd 系统服务(原生支持)2.2 通过 H…...