Android编译优化~Gradle构建基准测试

news2024/9/22 10:08:13

背景

之前对安卓打包编译优化有所实践,但当时对优化提升结果采取了手动测试的办法才拿到结果,而且遇到大型工程更是痛不欲生。不过当时采取的策略是将增量测试代码提到了Git,编译一次抄一次代码,样本数据只重复了10次,中间不能出现错误操作不然样本数据参考意义不大。当时不清楚有更好的测试方案,但后续随着了解的深入,谷歌官方有介绍如何对Gradle构建过程进行基准测试。

基本使用

安装gradle-profiler

这块GitHub有说明,但实操后还是建议用MAC来做。如果是Windows还需要安装SDKMAN和子系统。
MAC命令行切到我们的项目根目录,执行会自动根据我们工程配置下载Gradle

brew install gradle-profiler
gradle-profiler --benchmark help


* Writing results to /Users/hynson/StudioProjects/SimpleGallery/profile-out

* Settings
Project dir: /Users/hynson/StudioProjects/SimpleGallery
Output dir: /Users/hynson/StudioProjects/SimpleGallery/profile-out
Profiler: none
Benchmark: true
Versions: []
Gradle User Home: /Users/hynson/StudioProjects/SimpleGallery/gradle-user-home
Targets: [help]

* Inspecting the build using its default Gradle version
Downloading https://services.gradle.org/distributions/gradle-7.3.3-bin.zip
..............................................................................................................
* Stopping daemons

* Scenarios
Scenario: using Gradle 7.3.3
  Gradle 7.3.3 (/Users/hynson/StudioProjects/SimpleGallery/gradle-user-home/wrapper/dists/gradle-7.3.3-bin/6a41zxkdtcxs8rphpq6y0069z/gradle-7.3.3)
  Run using: Tooling API
  Run: run tasks help
  Cleanup: do nothing
  Gradle args: []
  Build changes: []
  Warm-ups: 6
  Builds: 10

* Running scenario using Gradle 7.3.3 (scenario 1/1)

编写测试场景文件

在项目根目录新建scenarios.txt文件,参考文档编写JSON格式的场景命令。如

# <root-project>/scenarios.txt
clean_build_2gb_4workers {
    tasks = [":app:assembleDebug"]
    gradle-args = ["--max-workers=1"]
    jvm-args = ["-Xmx2048m"]
    cleanup-tasks = ["clean"]
}
clean_build_G1GC_4gb {
    tasks = [":app:assembleDebug"]
    gradle-args = ["--max-workers=4"]
    jvm-args = ["-Xmx2048m"]
    cleanup-tasks = ["clean"]
}

关于如何写场景命令,更详细的使用说明,GitHub有更详细的指导。

执行测试用例

执行下面命令后,命令行运行效果

gradle-profiler --benchmark --project-dir ./ --scenario-file scenarios.txt

运行测试用例执行完后,到这一步我们项目目录发生了如下变化,profile.log是我们Gradle执行的编译日志,CSV则是数据,html就是我们的测试报告了。
在这里插入图片描述

分析测试结果

用浏览器打开benchmark.html报告
测试结果以上是Gradle --max-workers=1和Gradle --max-workers=4两次的测试结果对比。

增量Build分析(Profiling incremental builds)

增量是我们进行性能分析最重要的场景,Gradle支持以下自动更改操作,它执行修改完成后会恢复原始代码。

  • 修改方法征文、添加新方法
  • 修改布局和字符串资源
incremental_build {
    tasks = ["assemble"]

    apply-build-script-change-to = "build.gradle.kts"
    apply-project-dependency-change-to {
        files = ["build.gradle"]
        # Default number of dependency-count is 3.
        # Gradle Profiler will simulate changes to project dependencies by generate some additional projects and then add a combination of project dependencies to every non-generated subprojects before each iteration.
        # The profiler will generate the minimal number of subprojects to allow for a unique combination of dependencies to be used for each iteration.
        # Note: Number of generated projects is calculated as binomial coffiecient: "from `x` choose `dependency-count` = `iterations * files`", where number of generated projects is `x`.
        dependency-count = 3
    }
    apply-abi-change-to = "src/main/java/MyThing.java"
    apply-non-abi-change-to = ["src/main/java/MyThing.java", "src/main/java/MyOtherThing.java"]
    apply-h-change-to = "src/main/headers/app.h"
    apply-cpp-change-to = "src/main/cpp/app.cpp"
    apply-property-resource-change-to = "src/main/resources/thing.properties"
    apply-android-resource-change-to = "src/main/res/values/strings.xml"
    apply-android-resource-value-change-to = "src/main/res/values/strings.xml"
    apply-android-manifest-change-to = "src/main/AndroidManifest.xml"
    clear-build-cache-before = SCENARIO
    clear-transform-cache-before = BUILD
    show-build-cache-size = true
    git-checkout = {
        cleanup = "efb43a1"
        build = "master"
    }
    git-revert = ["efb43a1"]
    jvm-args = ["-Xmx2500m", "-XX:MaxMetaspaceSize=512m"]
}

这里需要注意,场景文件的任务执行顺序是自下而上的,还有更高级的用法值得深入研究。

androidStudioSync

这里附上一个用到的一个场景供参考,有时我们需要执行AS的Sync(比如我们修改了local.properties文件),我们就需要在场景文件中新增

androidStudioSync {
title = “Android Studio Sync”
# Measure an Android studio sync
# Note: Android Studio Bumblebee (2021.1.1) or newer is required
android-studio-sync {
# Override default Android Studio jvm args
# studio-jvm-args = [“-Xms256m”, “-Xmx4096m”]
}
}

然后在命令行执行需要指定AS的安装目录,然后它会自动打开AS执行同样的操作10次后自动关闭AS,这个还是比较耗时,建议非必要测试场景不要配置AS同步。

gradle-profiler --benchmark --project-dir ./ --scenario-file scenarios_add.txt

* Writing results to /Users/hynson/StudioProjects/SimpleGallery/profile-out-11

* Settings
Project dir: /Users/hynson/StudioProjects/SimpleGallery/.
Output dir: /Users/hynson/StudioProjects/SimpleGallery/profile-out-11
Profiler: none
Benchmark: true
Versions: []
Gradle User Home: /Users/hynson/StudioProjects/SimpleGallery/gradle-user-home
Targets: []

* Inspecting the build using its default Gradle version

* Stopping daemons
java.lang.IllegalArgumentException: Android Studio installation directory should be specified using --studio-install-dir when measuring Android studio sync.
	at org.gradle.profiler.ScenarioLoader.getBuildAction(ScenarioLoader.java:474)
	at org.gradle.profiler.ScenarioLoader.loadScenarios(ScenarioLoader.java:270)
	at org.gradle.profiler.ScenarioLoader.doLoadScenarios(ScenarioLoader.java:175)
	at org.gradle.profiler.ScenarioLoader.loadScenarios(ScenarioLoader.java:156)
	at org.gradle.profiler.Main.run(Main.java:56)
	at org.gradle.profiler.Main.main(Main.java:25)

hynson@housaibangdeiMac SimpleGallery % gradle-profiler --benchmark --studio-install-dir "/Applications/Android Studio.app/" --project-dir ./ --scenario-file scenarios_add.txt 

* Writing results to /Users/hynson/StudioProjects/SimpleGallery/profile-out-20

* Settings
Project dir: /Users/hynson/StudioProjects/SimpleGallery/.
Output dir: /Users/hynson/StudioProjects/SimpleGallery/profile-out-20
Profiler: none
Benchmark: true
Versions: []
Gradle User Home: /Users/hynson/StudioProjects/SimpleGallery/gradle-user-home
Targets: []

* Inspecting the build using its default Gradle version

* Stopping daemons

* Scenarios
Scenario: Android Studio Sync using Gradle 7.3.3
  Gradle 7.3.3 (/Users/hynson/StudioProjects/SimpleGallery/gradle-user-home/wrapper/dists/gradle-7.3.3-bin/6a41zxkdtcxs8rphpq6y0069z/gradle-7.3.3)
  Run using: Android Studio
  Run: Android Studio sync
  Cleanup: do nothing
  Gradle args: []
  Build changes: []
  Warm-ups: 6
  Builds: 10
Scenario: string_resource_change using Gradle 7.3.3
  Gradle 7.3.3 (/Users/hynson/StudioProjects/SimpleGallery/gradle-user-home/wrapper/dists/gradle-7.3.3-bin/6a41zxkdtcxs8rphpq6y0069z/gradle-7.3.3)
  Run using: Tooling API
  Run: run tasks :app_kt:assembleDebug
  Cleanup: do nothing
  Gradle args: []
  Build changes: [ApplyValueChangeToAndroidResourceFileMutator(/Users/hynson/StudioProjects/SimpleGallery/./app_kt/src/main/res/values/strings.xml)]
  Warm-ups: 6
  Builds: 10

* Running scenario Android Studio Sync using Gradle 7.3.3 (scenario 1/2)

* Stopping daemons

* Running warm-up build #1


* Starting Android Studio at /Applications/Android Studio.app
* Java command: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
* Classpath:
  /Applications/Android Studio.app/Contents/lib/util.jar
  /Applications/Android Studio.app/Contents/lib/bootstrap.jar
* System properties:
  gradle.profiler.startup.port -> 59499
  gradle.profiler.port -> 59500
  idea.config.path -> /Users/hynson/StudioProjects/SimpleGallery/profile-out-20/studio-sandbox/config
  idea.log.path -> /Users/hynson/StudioProjects/SimpleGallery/profile-out-20/studio-sandbox/logs
  idea.jre.check -> true
  idea.system.path -> /Users/hynson/StudioProjects/SimpleGallery/profile-out-20/studio-sandbox/system
  idea.paths.selector -> AndroidStudio2021.3
  idea.vendor.name -> Google
  java.system.class.loader -> com.intellij.util.lang.PathClassLoader
  idea.gradle.distributionType -> BUNDLED
  idea.plugins.path -> /Users/hynson/StudioProjects/SimpleGallery/profile-out-20/studio-sandbox/plugins
  idea.trust.all.projects -> true
  splash -> true
  idea.platform.prefix -> AndroidStudio
  idea.executable -> studio
  idea.home.path -> /Applications/Android Studio.app/Contents
* Main class: com.intellij.idea.Main
* Android Studio logs can be found at: /Users/hynson/StudioProjects/SimpleGallery/profile-out-20/studio-sandbox/logs/idea.log
* Using command line: [/Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java, -cp, /Applications/Android Studio.app/Contents/lib/util.jar:/Applications/Android Studio.app/Contents/lib/bootstrap.jar, -Dgradle.profiler.startup.port=59499, -Dgradle.profiler.port=59500, -Didea.config.path=/Users/hynson/StudioProjects/SimpleGallery/profile-out-20/studio-sandbox/config, -Didea.log.path=/Users/hynson/StudioProjects/SimpleGallery/profile-out-20/studio-sandbox/logs, -Didea.jre.check=true, -Didea.system.path=/Users/hynson/StudioProjects/SimpleGallery/profile-out-20/studio-sandbox/system, -Didea.paths.selector=AndroidStudio2021.3, -Didea.vendor.name=Google, -Djava.system.class.loader=com.intellij.util.lang.PathClassLoader, -Didea.gradle.distributionType=BUNDLED, -Didea.plugins.path=/Users/hynson/StudioProjects/SimpleGallery/profile-out-20/studio-sandbox/plugins, -Didea.trust.all.projects=true, -Dsplash=true, -Didea.platform.prefix=AndroidStudio, -Didea.executable=studio, -Didea.home.path=/Applications/Android Studio.app/Contents, --add-opens=java.base/java.io=ALL-UNNAMED, --add-opens=java.base/java.lang=ALL-UNNAMED, --add-opens=java.base/java.lang.reflect=ALL-UNNAMED, --add-opens=java.base/java.net=ALL-UNNAMED, --add-opens=java.base/java.nio=ALL-UNNAMED, --add-opens=java.base/java.nio.charset=ALL-UNNAMED, --add-opens=java.base/java.text=ALL-UNNAMED, --add-opens=java.base/java.time=ALL-UNNAMED, --add-opens=java.base/java.util=ALL-UNNAMED, --add-opens=java.base/java.util.concurrent=ALL-UNNAMED, --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED, --add-opens=java.base/jdk.internal.vm=ALL-UNNAMED, --add-opens=java.base/sun.nio.ch=ALL-UNNAMED, --add-opens=java.base/sun.security.ssl=ALL-UNNAMED, --add-opens=java.base/sun.security.util=ALL-UNNAMED, --add-opens=java.desktop/com.sun.java.swing.plaf.gtk=ALL-UNNAMED, --add-opens=java.desktop/java.awt=ALL-UNNAMED, --add-opens=java.desktop/java.awt.dnd.peer=ALL-UNNAMED, --add-opens=java.desktop/java.awt.event=ALL-UNNAMED, --add-opens=java.desktop/java.awt.image=ALL-UNNAMED, --add-opens=java.desktop/java.awt.peer=ALL-UNNAMED, --add-opens=java.desktop/javax.swing=ALL-UNNAMED, --add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED, --add-opens=java.desktop/javax.swing.text.html=ALL-UNNAMED, --add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED, --add-opens=java.desktop/sun.awt.datatransfer=ALL-UNNAMED, --add-opens=java.desktop/sun.awt.image=ALL-UNNAMED, --add-opens=java.desktop/sun.awt=ALL-UNNAMED, --add-opens=java.desktop/sun.font=ALL-UNNAMED, --add-opens=java.desktop/sun.java2d=ALL-UNNAMED, --add-opens=java.desktop/sun.swing=ALL-UNNAMED, --add-opens=jdk.attach/sun.tools.attach=ALL-UNNAMED, --add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED, --add-opens=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED, --add-opens=jdk.jdi/com.sun.tools.jdi=ALL-UNNAMED, --add-exports=java.desktop/com.apple.eawt=ALL-UNNAMED, --add-exports=java.desktop/com.apple.laf=ALL-UNNAMED, --add-exports=java.desktop/com.apple.eawt.event=ALL-UNNAMED, -javaagent:/private/var/folders/93/fk0382_90qbcctczf5s2xhkr0000gn/T/studio-agent13826845936541378830.jar=59501,/private/var/folders/93/fk0382_90qbcctczf5s2xhkr0000gn/T/instrumentation-support8915076811485037397.jar, --add-exports, java.base/jdk.internal.misc=ALL-UNNAMED, -Xbootclasspath/a:/private/var/folders/93/fk0382_90qbcctczf5s2xhkr0000gn/T/asm14122579247830138713.jar:/private/var/folders/93/fk0382_90qbcctczf5s2xhkr0000gn/T/client-protocol15407110553657043473.jar, -Xms256m, -Xmx4096m, com.intellij.idea.Main, /Users/hynson/StudioProjects/SimpleGallery/.]

* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 441762ms
* Full Gradle execution time: 441762ms
* Full IDE execution time: 398563ms
* Full sync has completed in: 840325ms and it SUCCEEDED
Execution time 840325 ms

* Running warm-up build #2
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 22032ms
* Full Gradle execution time: 22032ms
* Full IDE execution time: 2025ms
* Full sync has completed in: 24057ms and it SUCCEEDED
Execution time 24057 ms

* Running warm-up build #3
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 3824ms
* Full Gradle execution time: 3824ms
* Full IDE execution time: 1073ms
* Full sync has completed in: 4897ms and it SUCCEEDED
Execution time 4897 ms

* Running warm-up build #4
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 1175ms
* Full Gradle execution time: 1175ms
* Full IDE execution time: 427ms
* Full sync has completed in: 1602ms and it SUCCEEDED
Execution time 1602 ms

* Running warm-up build #5
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 964ms
* Full Gradle execution time: 964ms
* Full IDE execution time: 394ms
* Full sync has completed in: 1358ms and it SUCCEEDED
Execution time 1358 ms

* Running warm-up build #6
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 1014ms
* Full Gradle execution time: 1014ms
* Full IDE execution time: 301ms
* Full sync has completed in: 1315ms and it SUCCEEDED
Execution time 1315 ms

* Running measured build #1
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 1227ms
* Full Gradle execution time: 1227ms
* Full IDE execution time: 282ms
* Full sync has completed in: 1509ms and it SUCCEEDED
Execution time 1509 ms

* Running measured build #2
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 1453ms
* Full Gradle execution time: 1453ms
* Full IDE execution time: 350ms
* Full sync has completed in: 1803ms and it SUCCEEDED
Execution time 1803 ms

* Running measured build #3
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 883ms
* Full Gradle execution time: 883ms
* Full IDE execution time: 353ms
* Full sync has completed in: 1236ms and it SUCCEEDED
Execution time 1236 ms

* Running measured build #4
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 997ms
* Full Gradle execution time: 997ms
* Full IDE execution time: 370ms
* Full sync has completed in: 1367ms and it SUCCEEDED
Execution time 1367 ms

* Running measured build #5
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 923ms
* Full Gradle execution time: 923ms
* Full IDE execution time: 320ms
* Full sync has completed in: 1243ms and it SUCCEEDED
Execution time 1243 ms

* Running measured build #6
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 1386ms
* Full Gradle execution time: 1386ms
* Full IDE execution time: 320ms
* Full sync has completed in: 1706ms and it SUCCEEDED
Execution time 1706 ms

* Running measured build #7
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 934ms
* Full Gradle execution time: 934ms
* Full IDE execution time: 3469ms
* Full sync has completed in: 4403ms and it SUCCEEDED
Execution time 4403 ms

* Running measured build #8
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 755ms
* Full Gradle execution time: 755ms
* Full IDE execution time: 331ms
* Full sync has completed in: 1086ms and it SUCCEEDED
Execution time 1086 ms

* Running measured build #9
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 702ms
* Full Gradle execution time: 702ms
* Full IDE execution time: 299ms
* Full sync has completed in: 1001ms and it SUCCEEDED
Execution time 1001 ms

* Running measured build #10
* Running sync in Android Studio...
* Sent sync request
* Sync has started, waiting for it to complete...
* Gradle invocation 1 has started, waiting for it to complete...
* Gradle invocation 1 has completed in: 723ms
* Full Gradle execution time: 723ms
* Full IDE execution time: 340ms
* Full sync has completed in: 1063ms and it SUCCEEDED
Execution time 1063 ms
* Stopping Android Studio....
* Android Studio stopped.

* Stopping daemons

相关文章介绍较少,看了之后也有点一头雾水。如果对你有帮忙,欢迎点赞和关注!

参考:
https://developer.android.google.cn/studio/build/profile-your-build
https://github.com/gradle/gradle-profiler

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【实时数仓】业务数据采集之Maxwell的介绍、底层原理、安装及初始化、监控功能、采集服务和MySQL的binlog

文章目录一 业务数据采集0 业务数据采集思路1 Maxwell 介绍2 Maxwell工作原理&#xff08;1&#xff09; MySQL主从复制过程&#xff08;2&#xff09;Maxwell的工作原理3 MySQL的binlog&#xff08;1&#xff09;什么是binlog&#xff08;2&#xff09;binlog的开启&#xff0…

算法基础篇-07-排序-希尔排序(Shell Sort)

1. 希尔排序简介 希尔排序(Shell Sort) 是一种分组插入排序算法&#xff0c;是基于插入排序算法演进而来&#xff1b;首先取一个整数d1n/2, 将元素分为d1个组&#xff0c;每组相邻元素之间距离d1,在各组内进行直接插入排序&#xff1b;取第二个整数d2d1/2,重复上述分组排序过程…

微信小程序框架(二)-全面详解(学习总结---从入门到深化)

目录 组件_基础视图 容器 view 文本 text 图片 image 组件_滑块视图容器 基本实现 Swiper常用属性说明 组件_滚动视图区域 水平滚动 垂直滚动 常用属性 组件_icon 图标使用 字体图标属性 组件_progress 基本进度条 属性说明 组件_表单 登录页面 组件_button 按钮属…

这个队列的思路是真的好,现在它是我简历上的亮点了。

前几天在一个开源项目的 github 里面看到这样的一个 pr&#xff1a; 光是看这个名字&#xff0c;里面有个 MemorySafe&#xff0c;我就有点陷进去了。 我先给你看看这个东西&#xff1a; 这个肯定很眼熟吧&#xff1f;我是从阿里巴巴开发规范中截的图。 为什么不建议使用 Fix…

k8s-使用kube-install一键部署(亲测超详细)

文章目录测试环境操作系统环境配置升级操作系统内核基础配置k8s前置配置docker 安装kube-install1.获取kube-install软件包kube-install提供两种安装方式通过Web平台安装kubernetes集群通过命令行快速安装kubernetes集群扩容与销毁Node|修复Master|卸载集群Kubernetes Dashboar…

“特耐苏“牌传递窗——洁净区与洁净之间的辅助设备

传递窗安于高洁净要求的洁净区与洁净之间; 传递窗是一种洁净室的辅助设备&#xff0c;主要用于洁净区与洁净区之间、洁净区与非洁净区之间小件物品的传递&#xff0c;以减少洁净室的开门次数&#xff0c;把对洁净室的污染降低到zui低程度。传递窗采用不锈钢板制作&#xff0c;…

【期末过过过90+】【数据库系统概述】亲笔备考笔记+知识点整理+备考建议

文章目录&#xff1a;故事的开头总是极尽温柔&#xff0c;故事会一直温柔……&#x1f49c;一、前言二、考试题型三、必考重点四、知识点梳理及笔记第1章&#xff1a;绪论第2章&#xff1a;关系数据库第3章&#xff1a;关系数据库标准语言SQL第4章&#xff1a;数据库安全性第5章…

动物静态HTML网页作业作品 大学生野生动物保护网页设计制作成品 简单DIV CSS布局网站

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

网络基础------IP协议

文章目录IP协议的主要功能网段划分IP数量限制WAN口的IP 和 LAN口的IP路由IP协议的主要功能 网络层&#xff08;IP协议&#xff09;的主要功能&#xff1a; 地址转换和路由选择 传输层&#xff08;TCP协议&#xff09;的主要功能&#xff1a; 传输数据的控制。 有什么区别吗&am…

小程序不在以下request合法域名,http协议添加不了

每个微信小程序需要事先设置通讯域名&#xff0c;小程序只可以跟指定的域名进行网络通信 问题描述 出现http://xxx.不在以下request合法域名列表中&#xff0c;请参考文档 解决方法 在开发中可以勾上不校验合法域名 在发版中就需要把域名放在通讯域名中 [外链图片转存失败,…

ADI Blackfin DSP处理器-BF533的开发详解26:电子书的应用(含源代码)

硬件准备 ADSP-EDU-BF533&#xff1a;BF533开发板 AD-HP530ICE&#xff1a;ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 功能介绍 代码实现了读取 SD 卡中“/txt/test.txt”路径下的 TXT 文件&#xff0c;将 TXT 文件内容显示到液晶屏上&#xff0c;通过按键“Lift-&…

java计算机毕业设计ssm疫苗接种预约系统小程序24tfm(附源码、数据库)

java计算机毕业设计ssm疫苗接种预约系统小程序24tfm&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&…

【数据结构】TopK问题

TopK 在N个数中 找出最大或最小的前k个数&#xff0c;就是TopK算法。比如有一组数字&#xff0c;[1,2,3,4,5,6,7,8,9]&#xff0c;这组数中最大的前 3(k)个数是 9,8,7。最小的 前3个数是 1&#xff0c;2&#xff0c;3。而TopK算法就是找出最大或者最小的前K个数。我们就用堆来实…

【mmdetection系列】mmdetection之backbone讲解

如果是自己来写这部分代码的话&#xff0c;真的是很容易&#xff0c;如果这个框架中有自带的backbone结构的话&#xff0c;那可以从其他地方找到对应的pytorch版本实现&#xff0c;或者自己写。 配置部分在configs/_base_/models目录下&#xff0c;具体实现在mmdet/models/bac…

微信小程序——云音乐界面

文章目录第一章 开发前的准备一、项目展示二、项目分析三、项目初始化第二章 标签页切换一、任务分析二、常用组件介绍三、编写页面结构和样式第三章 音乐推荐一、任务分析二、组件介绍三、编写音乐推荐页面结构和样式第一章 开发前的准备 一、项目展示 音乐小程序项目效果展…

.net开发安卓入门 - Notification(通知)

.net开发安卓入门 - Notification&#xff08;通知&#xff09;通知的布局创建通知通道创建和发布通知我的样例效果图代码资源文件常见问题一切代码都准备就绪了&#xff0c;为什么就是不提示消息内容呢&#xff1f;为什么我的通知不是弹出式的同系列文章推荐通知的布局 创建通…

yolov7运行自己的VOC格式数据集

yolov7运行VOC格式数据集测试开发环境使用自己的VOC格式数据集训练修改配置文件yolov7.yaml修改配置文件voc.yamlVOC格式数据集转换COCO格式开始训练重头开始fine-trainBUG常见报错1常见报错2成功训练网络评价指标可视化测试开发环境 去官网下载yolov7的权重文件&#xff0c;放…

async/await

理解async函数就要先理解generator (生成器)函数,因为async是generator函数的语法糖。 Generator函数 Generator 函数是 ES6 提供的一种异步编程解决方案&#xff0c;可以先理解为一个状态机&#xff0c;封装了多个内部状态&#xff0c;执行Generator函数返回一个遍历器对象&…

【ChatGPT 中文版插件】无需注册体验 ChatGPT 的攻略

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

假设检验介绍

数据科学是一个不断发展的领域&#xff0c;近年来越来越受欢迎。数据科学的一个重要组成部分是假设检验的使用&#xff0c;它可用于从数据中得出结论并做出明智的决策。 什么是假设检验&#xff1f; 假设检验是数据科学中常用的方法&#xff0c;用于评估关于总体参数的假设的有…