Android 源码的下载与编译

Android 源码的下载与编译

本章节主要介绍安卓系统的编译以及编译产物,根据我自己的经验只总结个人觉得重要的部分。

有价值的博客:

https://blog.csdn.net/wuye110/article/details/8463409

https://juejin.cn/post/7288166472131018786

值得一看的视频教程(AOSP源码编译):

https://www.bilibili.com/video/BV1y84y1k7be

一、Android源码的编译

我们日常工作中可能是基于某厂商的SDK进行个性化定制的编译,对于Android源码的编译,官方有给出简单的过程:https://source.android.com/source/building?hl=zh-cn

1. 构建环境

官方说明,AOSP会定期在 Ubuntu LTS (14.04) 和 Debian 测试版本中对 Android 构建系统进行内部测试。其他大多数分发版本都应该具有所需的构建工具。只支持Linux操作系统上编译。

官网文档如下

https://source.android.com/docs/setup/start/initializing?hl=zh-cn

首先你要有一个Ubuntu虚拟机

  1. 按照官方文档下载软件包

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这里默认用的是美国镜像,所以我们要换成清华源的。

官网:https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/

配置源的路径在/etc/apt/sources.list,先备份一个

sudo cp sources.;ist sources.list.bak

然后在sources.list第二行添加就行了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当下载出错的时候可以尝试换源,此时他会接着已经下载的部分下载,而不是重下

2. 下载源码

下载源码需要安装Repo工具,Repo 启动器会提供一个 Python 脚本,因此使用Repo首先需要安装python。

sudo apt-get install python

然后看官方文档

https://source.android.com/docs/setup/download?hl=zh-cn#installing-repo

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3. 初始化Repo仓库

这里我们切换到清华源的文档,按照下面的部分操作

https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后中途可能要设置git邮箱和用户名

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这里同步源码树建议使用:

repo sync -j4

数字太大会很占用资源

4. 编译Android

Step1:初始化编译环境

初始化编译环境主要是执行

source ./build/envsetup.sh命令执行envsetup.sh脚本( 或者用.代替source),脚本的具体内容将在后续介绍。

注意,在Android9等较老的安卓版本上,需要使用bash来执行该脚本,否则会有如下警告。

WARNING: Only bash is supported, use of other shell would lead to erroneous results

如果有和我一样使用zsh 的同学记得切换回bash

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Step2: 选择编译目标

lunch BUILD-BUILDTYPE

也可以直接输入lunch ,系统会给出所有可以选择的选项。选择之后即会确定TARGET_PRODUCT、TARGET_BUILD_VARIANT、TARGET_PLATFORM_VERSION、TARGET_BUILD_TYPE等变量的值。

这些值都是在device/xxxx/product/AndroidProducts.mk文件中的COMMON_LUNCH_CHOICES属性定义的。

Step3: 编译

make -j8 这里的选项"-jN"中的N值取决于你编译的服务器的CPU核心数。你可以使用 nproc 查看核心数,也可以大胆尝试,写高了会报错的。这里的make指的是编译整个Android代码。

Android根目录的Makefile include进来一个编译核心文件:build/make/core/main.mk

我们在编译的时候会有很多log但是由于控制台的buffer限制我们不能看到全部的log。于是将log输出到文件里面更便于我们查看,

make -j16 2>&1 | tee build.log

比如遇到本地化的错误,除了可以在每次执行之前使用export LC_ALL=C之外,还可以把这段代码添加到envsetup.sh的第一行,这样就不用每次都输入了

由于安卓已经出来很多年了,所以大部分的错误往往搜索都能找到解决答案

以后在编译的时候,当你修改了.mk文件之后记得使用 make clean清楚out目录下已经生成的文件

5. envsetup.sh介绍

现在来详细介绍一下envsetup.sh这个脚本

这个脚本记录了编译过程中所需要的各种函数实现,如m\mm\mmm\lunch 等函数,进入这个脚本可以看到里面给出的提示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可以使用m help命令获取提示。

添加编译目标:将以下文件搜索并source进来

device/**/vendorsetup.sh
vendor/**/vendorsetup.sh
product/**/vendorsetup.sh

下面介绍一些常用的命令:

m命令
  • m 源码树的根目录执行编译,编译的是根目录下所有的代码;
  • mm 编译当前路径下所有模块,但不包含依赖关系的模块;
  • mmm [module_path] 编译指定路径下的所有模块,但不包含依赖关系的模块;
  • mma 编译当前路径下所有模块,且包含依赖关系的模块;
  • mmma [module_path] 编译指定路径下的所有模块,且包含依赖关系的模块;
make命令
  • make [module_name] 无参数,则表示编译整个Android代码,如果有module_name,是会遍历module,编译指定的module;

  • make clean:执行清理操作,等价于 rm -rf out/

  • make installclean:删除已安装的应用程序,如中间文件、临时文件、APK文件等

  • make otapackage 生成升级包

  • make update-api:更新API,在framework API改动后需执行该指令,Api记录在目录frameworks/base/api;

    其他还有

    make sdk 编译出 Android 的 SDK;

    make clean-sdk 清理 SDK 的编译产物;

    make help 帮助信息,显示主要的 make 目标;

    make snod 从已经编译出的包快速重建系统镜像;

    make clean- 清理一个指定模块的编译结果;

    make dump-products 显示所有产品的编译配置信息;

    make libandroid_runtime 编译所有 JNI framework 内容

    make framework 编译所有 Java framework 内容

    make services 编译系统服务和相关内容。

    make bootimage 生成 boot.img

    make systemimage 编译生成system.img

    make recoveryimage 生成 recovery.img

    make userdataimage 生成 userdata.img

    make cacheimage 生成 cache.img

    make dist 执行 Build,并将 MAKECMDGOALS 变量定义的输出文件拷贝到 /out/dist 目录。

    常见module编译例:

    {模块} make命令 | mmm命令
    {init} make init | mmm system/core/init
    {zygote} make app_process | mmm frameworks/base/cmds/app_process
    {system_server} make services | mmm frameworks/base/services
    {java framework} make framework | mmm frameworks/base
    {framework资源} make framework-res | mmm frameworks/base/core/res
    {jni framework} make libandroid_runtime | mmm frameworks/base/core/jni
    {binder} make libbinder | mmm frameworks/native/libs/binder
    {RefBase等} make libutils | mmm framworks/base/libs/utils
    {Looper等} make framework | mmm framworks/base
    {AudioTrack} make libmedia | mmm framworks/base/media/kibmedia
    {AudioFlinger} make libaudiofliginger | mmm framworks/base/libs/audioflinger
    {AudioPolicyService} make libaudiopolicy | mmm hardware/msm7k/libaudio-qsd8k
    {SurfaceFlinger} make libsurfaceflinger | mmm frameworks/base/libs/surfaceflinger
    {Vold} make vold | mmm system/vold
    {Rild} make rild | mmm hardware/ril/rild
    {MediaProvider} make MediaProvider | mmm packages/providers/MediaProvider
    {Phone} make phone | mmm packages/apps/Phone

编译配置和搜索命令
  • add_lunch_combo [product] 将某个产品加入到用户选项中
  • print_lunch_menu 查询lunch可选的product
  • check_product [product] 检查产品是否有效
  • printconfig 打印当前选择的产品配置
  • get_build_var [build_var] 查找编译时各种变量值;
  • get_abs_build_var [build_var] 获取系统中的编译变量的值
  • cgrep [keyword] 所有 C/C++文件执行搜索操作
  • jgrep [keyword] 所有 Java 文件执行搜索操作
  • ggrep [keyword] 所有 Gradle 文件执行搜索操作
  • mgrep [keyword] 所有 Android.mk 文件执行搜索操作
  • mangrep [keyword] 所有AndroidManifest.xml文件执行搜索操作
  • sepgrep [keyword] 所有 sepolicy 文件执行搜索操作
  • resgrep [keyword] 所有本地res/*.xml文件执行搜索操作
导航命令
  • croot 切换至Android根目录
  • godir [filename] 跳转到包含某个文件的目录

5. 编译完成之后的产物

编译完成之后,结果会在out/target/product里面

如果使用emulator有个报错
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是因为没有kvm加速器,安装一下就好了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

二、定制产品的编译与烧录

1. 在lunch中添加产品

添加自己的产品的目标是让lunch菜单有我们的产品显示,通过搜索envsetup.sh可以发现,添加产品的地方在AndroidProducts.mk下

我们在编译过程中执行lunch命令的时候会发现有许多编译目标(产品)可以选择。我们前面提到lunch的这些值都是在device/xxxx/product/AndroidProducts.mk文件中的COMMON_LUNCH_CHOICES属性定义的。事实上在device目录下我们会发现很多厂商名录的文件夹,比如google。在添加新产品的时候我们也往往是在自己公司命名的文件夹下进行添加。

首先我们要先在该文件的同级目录下加一个mk文件。比如suzhe.mk(现在里面是空的,只有一个vendorsetup.sh)

然后再AndroidProducts.mk里面引入suzhe.mk再加suzhe-userdebug,就可以添加到lunch的目录了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

记得先执行source build/envsetup.sh才会把你的改动添加进来,再使用lunch命令就可以发现我们定义的已经成功添加进来了:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

后续就是添加mk的操作了,这里不做介绍(因为我没有亲自试验过)

2. tips:vendorsetup.sh介绍

注意,在安卓9可能有这个文件,更新版本就没有了,这里也会解释原因。

当我们进入device/xxxx/product/ 目录下后会发现里面有很多mk文件,其中比较重要的有AndroidProducts.mk 、device.mk、vendorsetup.sh、BoardConfig.mk 。这里我们来介绍一下vendorsetup.sh脚本。

脚本的目的:和AndroidProducts.mk中的COMMON_LUNCH_CHOICES属性一样,用于声明产品。

脚本内容:脚本内容参考如下:

add_lunch_combo suzhe-eng
add_lunch_combo suzhe-user
add_lunch_combo suzhe-userdebug

add_lunch_combo 是在哪里定义的: envsetup.sh

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

看到这里的注释了没有,这里提示我们说 add_lunch_combo 函数不再建议使用,而应该在 AndroidProducts.mk 文件中使用 COMMON_LUNCH_CHOICES。在安卓9的时候vendorsetup.sh还是存在的,但是后面就没了,这里仅做了解。

三、MK文件的包含路径

值得一看:

https://blog.csdn.net/wuye110/article/details/8463409

我们Make文件总共有三类

第一类是build目录下或者vendor下的,属于控制我们编译的一个框架,也就是控制编译的流程。

第二类是device目录下的,跟产品主板有关的,

第三类是跟应用有关的,编译jar包,编译可执行文件,编译apk之类的,Android.mk

首先应该是我们根目录下的Makefile文件,我们可以查看里面的内容

### DO NOT EDIT THIS FILE ###
include build/make/core/main.mk
### DO NOT EDIT THIS FILE ###

很简单,里面指示了我们的.mk文件的路径

那现在我们进入到main.mk里面去看看可以发现包括了很多的mk,子mk里面又包含了子mk,是一个非常庞大的树结构

其中,安卓产品的加载会走config.mk文件。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1. build/core/main.mk

  • 包含了build/core/config.mk

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. build/core/config.mk

  • 包含envsetup.mk

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3. build/make/core/envsetup.mk

  • 该文件负责配置 Build 系统需要的环境变量
  • 这里面包含了product_config.mk文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 部分重要变量如下:

    • TARGET_BUILD_VARIANT:构建变种的变量,(例如 enguseruserdebug 等)默认eng

    • TARGET_BUILD_TYPE:构建类型的变量,可以是 releasedebug 默认release

    • PRODUCT_OUT:编译输出目录 out/target/product/

4. build/core/product_config.mk

值得一看:

https://blog.csdn.net/lewif/article/details/50016179

  • 包含了product.mk文件

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 读取vendor目录下不同厂商自己定义的AndrodProducts.mk文件,根据lunch选择的编译项TARGET_PRODUCT,找到与之对应的配置文件,然后读取产品配置文件,找到里面的PRODUCT_DEVICE的值,设置给TARGET_DEVICE变量,用于后续编译。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 部分重要变量如下:

    PRODUCT_LOCALES :用于定义产品支持的语言和地区设置,通常是一个以逗号分隔的列表,例如 en_US, zh_CN, fr_FR 等。
    PRODUCT_SYSTEM_NAME:系统中的产品名称,默认为 PRODUCT_NAME。
    PRODUCT_SYSTEM_DEVICE:系统中的设备名称,默认为 PRODUCT_DEVICE。
    PRODUCT_SYSTEM_BRAND:系统中的品牌名称,默认为 PRODUCT_BRAND。
    PRODUCT_MODEL:产品的模型名称,默认为 PRODUCT_NAME。
    PRODUCT_SYSTEM_MODEL:系统中的模型名称,默认为 PRODUCT_MODEL。
    PRODUCT_MANUFACTURER:产品的制造商名称,默认为 unknown。
    PRODUCT_SYSTEM_MANUFACTURER:系统中的制造商名称,默认为 PRODUCT_MANUFACTURER。
    PRODUCT_DEFAULT_DEV_CERTIFICATE:默认的开发者签名证书路径,确保该变量只包含一个证书路径。

5. build/core/product.mk

该文件主要是一些用来处理AndroidProducts.mk的函数,用于定义产品构建过程中使用的变量

6. BoardConfig.mk介绍

BoardConfig.mk是板卡配置,主要是针对底层的配置文件。该文件由build/make/core/board_config.mk包含,board_config.mk又由envsetup.mk包含。这个文件它里面主要写了product使用的硬件所支持和不支持的功能性内容。BroadConfig.mk设置了每个设备的自己的一些变量值,来区别编译时的行为。

  • 最常见的改动就是SELINUX_PERMISSIVE对于SELinux模式的改动,如:
ifeq ($(AN_BOOT_SELINUX_PERMISSIVE), true)
BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive
endif

这表明当我们配置了AN_BOOT_SELINUX_PERMISSIVE环境变量为true的时候,设置SELinux为permissive模式。

其他一些变量:

TARGET_CPU_ABI:表示CPU的编程接口。比如armeabi-v7a。

TARGET_CPU_ABI2:表示CPU的编程接口。

TARGET_CPU_SMP:表示CPU是否为多核CPU。

TARGET_ARCH:定义CPU的架构。比如arm。

TARGET_ARCH_VARIANT:定义CPU的架构版本。比如:armv7-a-neon

TARGET_CPU_VARIANT:定义CPU的代号。比如:contex-a9

TARGET_NO_BOOTLOADER:如果为true,编译出的image不包含bootloader。

BOARD_KERNEL_BASE:装载kernel镜像时的基地址。比如:0x0

BOARD_KERNEL_OFFSET:kernel镜像的偏移地址。比如:0x1080000

BOARD_KERNEL_CMDLINE:装载kernel时传给kernel的命令行参数。比如:–cmdline “root=/dev/mmcblc0p20”

BOARD_MKBOOTIMG_ARGS:使用mkbooting工具生成boot.img时的参数。比如:–kernel_offset 0x1080000

BOARD_USES_ALSA_AUDIO:为true时,表示主板声音系统使用的是ALSA架构。

BOARD_HAVE_BLUETOOTH:为true时,表示主板支持蓝牙。

BOARD_WLAN_DEVICE:定义WiFi设备名称。

TARGET_BOARD_PLATFORM:表示主板平台的型号。比如tl1

TARGET_USERIMAGES_USE_EXT4:为true时,表示目标文件系统采用EXT4格式。

TARGET_NO_RADIOIMAGE:为true时,表示编译的镜像中没有射频部分。

WPA_SPPLICANT_VERSION:定义 WIFI WPA 的版本。

BOARD_WPA_SUPPLICANT_DRIVER:指定一种WPA_SUPPLICANT的驱动。

BOARD_HOSTAPD_DRIVER:指定WiFi热点的驱动。

WIFI_DRIVER_FW_PATH_PARAM:指定WiFi驱动的参数路径。

WIFI_DRIVER_FW_PATH_AP:定义WiFi热点firmware文件的路径。

7. AndroidProducts.mk介绍

其实上面已经差不多把AndroidProducts.mk的内容介绍完了,该mk在特定产品目录下,定义了product-eng 、product-user、product-userdebug等选项

还添加了同一目录下的product.mk进来,而product.mk当中又添加了同一目录下的device.mk。

8. device.mk介绍

这里面根据不同厂商会有非常多不同的实现,我们一般定制产品的各种属性也会有其中的改动。下面列出我这里有的一些:

  • 根据LAUNCH_VERSION决定产品发布的 API 级别
ifeq ($(LAUNCH_VERSION),U)
PRODUCT_SHIPPING_API_LEVEL := 34
else ifeq ($(LAUNCH_VERSION),T)
PRODUCT_SHIPPING_API_LEVEL := 33
else ifeq ($(LAUNCH_VERSION),S)
PRODUCT_SHIPPING_API_LEVEL := 31
else ifeq ($(LAUNCH_VERSION),R)
PRODUCT_SHIPPING_API_LEVEL := 30
else
PRODUCT_SHIPPING_API_LEVEL := 29
endif

显示密度资源选项DPI

# Include drawables for all densities
PRODUCT_AAPT_CONFIG := normal large xlarge hdpi xhdpi
ifeq ($(BOARD_COMPILE_ATV), true)
PRODUCT_AAPT_PREF_CONFIG := xhdpi
else
PRODUCT_AAPT_PREF_CONFIG := hdpi
endif

不同资源选项的默认分辨率和DPI 在device/xxxxx/display_config_aosp.xml

四、Multilib build多库构建

早期的安卓系统只支持32位CPU架构,但是现在基本上都是64位的了,为了在一个操作系统环境下同时支持 32 位和 64 位应用程序于是有了Multilib build。

Android.mk中有这样一个变量LOCAL_MULTILIB。 它的值可以是32,64,both,表示可以编译的apk可以运行在32位、64位,或者32&64位硬件平台。

最经典的支持Multilib build的是zygote。Multilib 编译会产生两个不同版本的zygote来支持不同位数的应用程序,即Zygote64和Zygote32。

在这里插入图片描述

这俩文件分别代表 32 位优先的启动模式和 64 位优先的启动模式。zygote的Android.mk中做了同时编译32位和64位程序的配置。

以init.zygote64_32.rc为例,他所属的进程为app_process64

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在较早以前的版本中,会有framework/base/cmds/app_process/Android.mk文件,里面内容如下:

LOCAL_MODULE:= app_process
LOCAL_MULTILIB := both
LOCAL_MODULE_STEM_32 := app_process32
LOCAL_MODULE_STEM_64 := app_process64LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-codeinclude $(BUILD_EXECUTABLE)

LOCAL_MODULE_STEM_32 := app_process32
LOCAL_MODULE_STEM_64 := app_process64
这两句分别指定了两种情况下的应用程序的名字,对应了init.zygote32_64.rc 中的service的路径中的/system/bin/app_process64。

但是在较新的版本中,改成了frameworks/base/cmds/app_process/Android.bp,相应的内容变为如下:

    // Create a symlink from app_process to app_process32 or 64// depending on the target configuration.symlink_preferred_arch: true,

这个配置表示会根据系统的首选架构(例如,64 位或 32 位)创建一个符号链接(symlink),指向相应的二进制文件。比如,在一个支持 32 位和 64 位的系统上,app_process 可能有 app_process32app_process64 这两个文件,系统会自动为 app_process 创建一个符号链接,指向当前架构需要使用的版本。如果目标架构是 64 位,符号链接会指向 app_process64;如果目标架构是 32 位,符号链接会指向 app_process32。这种方式可以避免为每个架构都独立生成多个模块,而是通过符号链接来实现架构特定版本的自动切换。

关于bp文件的具体内容可以参考:https://juejin.cn/post/7099005083202879502

五、镜像文件

这里先顺便提一下编译速度的优化:https://www.jb51.net/article/258618.htm

APK编译打包流程:https://juejin.cn/post/7113713363900694565

在编译完安卓之后,会在out/target/product/[YOUR_PRODUCT_NAME]/ 目录下生成最终要烧录到设备中的映像文件,包括system.img,userdata.img,recovery.img,ramdisk.img等

我不打算一个一个详细探究他们的具体内容,这里直接贴优秀博客。

https://blog.csdn.net/lijunjun1120/article/details/108720372

ramdisk.img

根文件系统,android启动时 首先加载ramdisk.img镜像,并挂载到/目录下,并进行了一系列的初始化动作,包括创建各种需要的目录,初始化console,开启服务等。System.img是在init.rc中指定一些脚本命令,通过init.c进行解析并挂载到根目录下的/system目录下的。

ramdisk.img其实是对root目录的打包和压缩。主要有以下内容:

  • init:Android最重要的进程——init,这是Android启动运行的的第一个进程,还有两个非常重要的脚本文件: init.fs100.rc和init.rc这是Android在刚开始启动时,需要首先加载的两个启动脚本,根据脚本里的内容,来完成一系列的启动工作,
  • data目录是 userdata.img镜像要挂载的目录,
  • system即为 system.img镜像需要挂载的目录,
  • dev目录是系统启动后,系统的设备文件目录。

system.img

挂载到 / 下的镜像,它包含了全部的系统可执行文件
system.img 文件是下面system目录的一个映像,类似于linux的根文件系统的映像

  1. bin:包含系统的二进制可执行文件。
  2. etc:包含配置文件。
  3. lib:包含共享库文件。
  4. framework:包含Android框架的JAR文件。
  5. app:包含系统应用程序。
  6. priv-app:包含具有更高权限的系统应用程序。
  7. media:包含音频、视频等媒体文件。
  8. fonts:包含系统字体文件。
  9. build.prop:系统属性文件,定义了系统的各种属性和参数。
  10. xbin:包含其他可执行文件和工具。

需要了解更多请看:

https://cloud.tencent.com/developer/article/2425851

https://www.cnblogs.com/xunbu7/p/10844099.html

userdata.img

Userdata.img来来自于data目录,默认里面是没有文件的。

需要了解请看:

https://blog.csdn.net/m0_59789328/article/details/139393603

recovery.img

recovery分区的镜像,一般用作系统恢复

六、OTA升级

OTA升级在我的另一篇博客中已经详细提到了,这里不做赘述

https://suzhelevel6.github.io/suzhe_blog/study-notes/android/theory/OTA%E5%8D%87%E7%BA%A7%E6%9C%BA%E5%88%B6.html

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

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

相关文章

docker安装portainer

1、拉取镜像 docker pull portainer/portainer-ce:latest2、执行 docker run -d --restartalways --name portainer -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v /data/portainer/data:/data -v /data/portainer/public:/public portainer/portain…

手写jdbc 工具类(封装思维,解决硬编码...)

目录 前言 手写jdbc 工具类 封装思维 对于封装思维的理解 举一个关于封装思维的例子 解决硬编码 什么是硬编码? 硬编码的例子: 解决办法 解法1 解法2 解法3 jdbc工具类总的代码如下 资源关闭的先后问题 解决办法: 总结 …

The First项目报告:抗 MEV 交易的CoW Protocol什么?

2023年,当UNIswap推出UniswapX 时,市场迎接它的不是赞叹,而是一片争议。UniswapX被指抄袭 CoWSwap 和 1inch。Curve 官方称 1inch 和 CoWSwap 早已改变游戏规则,UniswapX 非首创。CoWSwap 强调其 Intent Based Trading 的先驱地位…

微服务day06

MQ入门 同步处理业务: 异步处理: 将任务处理后交给MQ来进行分发处理。 MQ的相关知识 同步调用 同步调用的小结 异步调用 MQ技术选型 RabbitMQ 安装部署 其中包含几个概念: publisher:生产者,也就是发送消息的一方 …

C语言 | Leetcode C语言题解之第541题反转字符串II

题目&#xff1a; 题解&#xff1a; void swap(char* a, char* b) {char tmp *a;*a *b, *b tmp; }void reverse(char* l, char* r) {while (l < r) {swap(l, --r);} }int min(int a, int b) {return a < b ? a : b; }char* reverseStr(char* s, int k) {int n strl…

众创空间全民清债行动助力“三箭齐发”,共化地方债务危机

近日,中国财政领域迎来重大利好消息,政府“三箭齐发”策略出台,旨在高效化解地方债务问题,为经济稳健前行扫清障碍。而在这场化解债务的风暴中,众创空间全民清债行动以其独特的创新模式和卓越的服务能力,成为备受瞩目的助力者。历经15天的内测,众创空间全民清债行动于11月10日正…

Spring的XML配置:从“啊这...“到“啊,就这...“ --手写Spring第六篇了

这一篇让我想起来学习 Spring 的时&#xff0c;被 XML 支配的恐惧。明明是写Java&#xff0c;为啥要搞个XML呢&#xff1f;大佬们永远不知道&#xff0c;我认为最难的是 XML 头&#xff0c;但凡 Spring 用 JSON来做配置文件&#xff0c;Java 界都有可能再诞生一个扛把子。 <…

短剧小程序开发定制

短剧小程序的开发定做是一项结合了创意与技术的工作&#xff0c;它不仅能够为用户提供沉浸式的娱乐体验&#xff0c;还能为企业或个人创造新的商业机会。在开始开发之前&#xff0c;首先需要明确几个关键点&#xff1a; 需求分析&#xff1a;与客户深入沟通&#xff0c;了解他…

Step-by-step指南,带你飞越技术障碍!稳联技术Profinet转CanOpen网关连接步科电机!

嘿&#xff0c;宝子们&#xff01;今天我要给大家分享一个超好玩的工业自动化“大玩具”——通过稳联技术CanOpen转Profinet网关连接步科电机。 在工业自动化的奇妙世界里&#xff0c;不同协议的设备连接就像一场刺激的冒险游戏。而这个神奇的组合&#xff0c;简直就是打开冒险…

【9692】基于springcloud+vue的智慧养老平台

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取免费源码 项目描述 困扰管理层的许多问题当中,智慧养老平台一定是养老平…

Greenplum 可观测最佳实践

Greenplum 简介 Greenplum 是一个基于大规模并行处理&#xff08;MPP&#xff09;架构的高性能、高可用的数据库系统&#xff0c;它主要用于处理和分析大规模数据集。Greenplum 的架构由 Master 节点和 Segment 节点组成&#xff0c;其中 Master 节点负责接收客户端的查询请求…

博眼球还是真本事?参考平面不完整信号串扰反而好

高速先生成员--黄刚 Chris最近由于项目和培训都比较多&#xff0c;感觉每周为大家带来高速先生文档分享都有点儿力不从心了。这不在发布文章前的这个周末的下午还在发愁到底能给粉丝们带来什么有用的知识。热门而正常的高速理论感觉已经写得八九不离十了&#xff0c;再翻翻Chri…

ssm+jsp704学术团队管理系统设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm 等开发框架&#xff09; vue .net php phython node.js uniapp 微信小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不…

【LeetCode】每日一题 2024_11_11 切棍子的最小成本(区间 DP,记忆化搜索)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;切棍子的最小成本 双十一光棍节力扣给我们准备了 . . . 一根棍子 代码与解题思路 先读题&#xff1a; 题目给了 n 代表棍子的长度&#xff0c;给了 cuts 数组代表我们需要在这几个地方…

卡内基音乐厅回响肖邦旋律:旅美钢琴学者何超与导师洪勋的师生情缘

正是柿红蟹肥的时节&#xff0c;浙江杭州的青年钢琴演奏家洪勋老师收获了一份来自美国的大礼。他的弟子~正在就读美国哥伦比亚大学统计学硕士的何超受纽约卡耐基音乐厅盛邀以跨专业演奏者的身份于2025年1月19日晚上7点独奏肖邦的《叙事曲》&#xff0c;是该音乐厅创建130多年来…

Django SSE 高并发分析与解决

在 Django 中使用 Server-Sent Events (SSE) 实现高并发应用时&#xff0c;可能会遇到性能瓶颈和可扩展性问题。以下是高并发场景下使用 SSE 的问题分析及其解决方案。 问题背景 一位开发者在使用 Django/Gunicorn/Django-SSE 开发项目时&#xff0c;发现如果 SSE 连接数量超过…

Mono-InternVL 多模型大模型测评

一、简介 上海人工智能实验室的代季峰教授团队最近开发了一种新型多模态大模型Mono-InternVL&#xff0c;该模型在多模态任务中表现卓越&#xff0c;显示出技术上的显著优势。Mono-InternVL通过内嵌视觉专家&#xff0c;优化了视觉感知与理解的集成&#xff0c;大幅提高了处理效…

springboot快递物流管理系统-计算机设计毕业源码85178

目 录 摘要 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2 快递物流管理系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 操作可行性分析 2.2 系统流程分析 2.2.1数据增加流程 2.2.2 数据修改流程 2.2.3 数据…

《过山车之星2》启动不了解决方法

过山车之星2如果遇到启动不了的情况&#xff0c;玩家可以采取多种有效的办法进行解决&#xff0c;其中包括等待服务器维护结束、优化网络连接以及验证游戏文件完整性等。 过山车之星2启动不了怎么办 等待服务器维护结束 在维护期间会对服务器进行优化、修复Bug和更新&#xf…

【C#】创建一个主菜单和弹出菜单系统

文章目录 1. 创建WinForms项目2. 设计窗体3. 添加MenuStrip4. 配置菜单项5. 添加TextBox6. 编写事件处理代码7. 运行和测试 根据您提供的文件内容&#xff0c;看起来您需要在C# WinForms应用程序中设置一个窗体&#xff0c;其中包含一个文本框和几个菜单项&#xff0c;用于改变…