ARM Linux 基础学习 / 配置交叉编译工具链 / 编译 Linux 应用和驱动 / 编译内核
编辑整理 by Staok。
本文部分内容摘自 “100ask imx6ull” 开发板的配套资料(如 百问网的《嵌入式Linux应用开发完全手册》,在 百问网 imx6ull pro 开发板 页面 中的《2.1 100ASK_IMX6ULL_PRO:开发板资料》或《2.2 全系列Linux教程:在线视频与配套资料》里面可以下载到),还有参考 菜鸟教程、C语言中文网、红联的等等等等,比较广泛,侵删。进行了精髓提取,方便日后查阅。过于基础的内容不会在此提及。如有错误恭谢指出!
注:在 Github 上的原版文章日后可能会更新,在其它位置发的不会跟进。文章的 Gitee 仓库地址,Gitee 访问更流畅。
注意本文是基于 IMX6ULL 这个 SoC,即 A7 内核(ARM 各个内核介绍 【主线剧情 番外01】ARM 系列快速鸟瞰 - 欢迎来到 Staok - 瞰百易 (gitee.io)),本文所配置的交叉编译器也是对应的,即 ARMv7 32位,若是 i.mx8mm 这种基于 A53 内核的,就是对应 ARMv8 64位 的交叉编译器,要注意,不熟悉的仔细看一下~祝好
任何文章都有时效性,学习 linux 这种复杂系统,保持脑袋清醒和逻辑链清晰,耐下心来,共勉!
更全面的 Linux 应用 和 驱动编程,还见仓库 Github 仓库 或 Gitee 仓库 中,见里面相关的文件夹,东西真的很丰富~
Linux 驱动和应用的体验
Ubuntu 主机 的配置工作
-
首先换源,参考前面 “换源 和 添加系统变量” 一节。
-
配置 100ask Ubuntu 主机 的环境,执行:
wget --no-check-certificate -O Configuring_ubuntu.sh https://weidongshan.coding.net/p/DevelopmentEnvConf/d/DevelopmentEnvConf/git/raw/master/Configuring_ubuntu.sh && sudo chmod +x Configuring_ubuntu.sh && sudo ./Configuring_ubuntu.sh
这个会配置/安装一些基本应用如 NFS/TFTP 等,还建立 /home/book 目录,book 用户 等,具体看其 shell 程序。
-
百问网的 imx6ull pro 开发板的 SDK包(包括 Linux、uboot、buildroot 等源码和工具链,这个需要 windows 电脑 和 虚拟机 ubuntu 各存一份,前者用来阅读,后者用来编译)两个下载途径:
-
本地拷贝法:百问网 imx6ull pro 开发板 页面,找到 100ask_imx6ull_pro_2020.02.29_v2.0(这个很大,网盘下载),里面有固件、SDK包、原理图(底板+核心板)、应用例程、工具软件等等。其中 SDK包(包括 Linux、uboot、buildroot 等源码和工具链)在 07_Bsp_sdk (系统源码,包含uboot kernel rootfs 工具链 测试代码等)) 里面,自行拷贝到虚拟机 ubuntu 里面并解压。但是这是本地拷贝的不是最新的,最新的可以 git 下载(注意很大),看下面 “在线下载&更新法”。
-
在线下载&更新法:参考 百问网的《嵌入式Linux应用开发完全手册》里面 第二篇 的 《8.2 使用repo获取内核及工具链等》 里面的 《8.2.2 在线下载》。
-
配置 Git 邮箱和用户名:
git config --global user.email "user@100ask.com"
、git config --global user.name "100ask"
。 -
执行四条命令:
git clone https://e.coding.net/codebug8/repo.git mkdir -p 100ask_imx6ull-sdk && cd 100ask_imx6ull-sdk ../repo/repo init -u https://gitee.com/weidongshan/manifests.git -b linux-sdk -m imx6ull/100ask_imx6ull_linux4.9.88_release.xml --no-repo-verify ../repo/repo sync -j4
-
今后可以直接在
100ask_imx6ull-sdk
目录下执行../repo/repo sync -c
进行同步更新最新代码!
-
-
-
推荐在 windows 端 使用 Source Insight 来阅读 Linux 内核源码,详见 百问网的《嵌入式Linux应用开发完全手册》里面 第二篇 的《8.4 使用Source Insight阅读Linux内核源码》。
获取交叉编译工具链
这里提供三个获取方式。
用开发板厂家提供的 SDK 里的工具链
这里是 百问网的 imx6ull pro 开发板 的 SDK 中的工具链,在 /.../100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin
里面,使用 Vim 工具编辑 ~/.bashrc
文件,在最后添加:
export ARCH=arm export CROSS_COMPILE=arm-buildroot-linux-gnueabihf- export PATH=$PATH:/.../100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin
并在终端键入 source ~/.bashrc
使其生效。
然后在终端测试一下 arm-buildroot-linux-gnueabihf-gcc -v
。
ARM 官网下载 合适的工具链
-
ARM GUN-A 官方编译器下载页面: GNU Toolchain | GNU-A Downloads – Arm Developer。下面几个连接是对各个编译器命名的说明,必看。
-
arm-linux-gnueabihf、aarch64-linux-gnu等ARM交叉编译GCC的区别_Namcodream521的博客-CSDN博客。
-
转:ARM交叉编译工具链分类说明 arm-linux-gnueabi和arm-linux-gnueabihf 的区别_Beyoungbehappy的博客-CSDN博客。
-
arm交叉编译器gnueabi、none-eabi、arm-eabi、gnueabihf等的区别 - 涛少& - 博客园 (cnblogs.com)。
-
带有 “bare-metal” 的为不支持操作系统的。
-
总的来说:
-
经过 Codesourcery 公司基于GCC优化,带有 none 标识的编译器。
-
ARM GUN-A 官方编译器下载页面 Downloads | GNU-A Downloads – Arm Developer。要下载的编译器要运行在 x86_x64 机器的虚拟机里面的ubuntu 18.04 里面,因此找到 x86_64 Linux hosted cross toolchains 下面的各个编译器版本。
-
AArch32 target with hard float (arm-none-linux-gnueabihf) —— 可用于交叉编译ARMv7 32位 目标系统中所有环节的代码,包括裸机程序、u-boot、Linux kernel、filesystem和App应用程序。
-
AArch64 GNU/Linux target (aarch64-none-linux-gnu) —— 可用于交叉编译ARMv8 64位目标中的裸机程序、u-boot、Linux kernel、filesystem和App应用程序。
-
-
由 Linaro 公司基于GCC推出。
-
Linaro Releases 页面 Linaro Releases。
-
arm-linux-gnueabihf-gcc:可用于交叉编译ARMv7 32位 目标系统中所有环节的代码,包括裸机程序、u-boot、Linux kernel、filesystem和App应用程序。
-
aarch64-linux-gnu-gcc:可用于交叉编译ARMv8 64位目标中的裸机程序、u-boot、Linux kernel、filesystem和App应用程序。
-
-
-
-
在
x86_64 Linux hosted cross compilers
下面找到AArch32 target with hard float (arm-none-linux-gnueabihf)
(i.mx6ull 为 A7 内核,即为 32 位的 armv7 指令集),并下载;(AArch64 Linux hosted cross compilers
下的编译器可以运行在 64位的 嵌入式板子 SoC 的 Linux 上); -
使用
tar xvf
命令解压。
最后,添加环境变量。使用 Vim 工具编辑 ~/.bashrc
文件,在最后添加:
export ARCH=arm export CROSS_COMPILE=arm-none-linux-gnueabihf- # 添加名为 CROSS_COMPILE、ARCH 环境变量,写 makefile 用 make 工具编译的时候会用到 export PATH=$PATH:/<交叉编译器工具链的目录>/bin # 交叉编译器工具链的 路径,可以直接在 shell 中 打编译器的名字来 执行编译器 bin 应用
并在终端键入 source ~/.bashrc
使其生效。
然后在终端测试一下 arm-none-linux-gnueabihf-gcc -v
。
使用交叉编译工具链编译程序产生 固件/应用 后,通过 “PC 与 嵌入式板 传输文件的方式汇总” 一节提供的方法,传给 嵌入式 linux 开发板,再执行,也许需要添加执行的权限:chmod +x <应用>
。
使用 Linaro GCC 编译器
p.s 这里作者没有试验,只是把说明放在这里。
正点原子的文章【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.5.1
在 4.3.1.2 小节
里说到个别版本能编译通过但是不能运行,多换换版本试试。
到 Linaro Releases 下载适合的编译器,使用方法与上面类似。Linaro 的编译器对应的名字为 arm-linux-gnueabihf-
。
第一个应用
略,略略略~。(在 百问网 imx6ull pro 开发板 页面 中的《2.2 全系列Linux教程:在线视频与配套资料》里面的 \01_all_series_quickstart\04_嵌入式Linux应用开发基础知识\source
里面)
第一个驱动
注意:
-
驱动程序用到 Linux 内核的 API,编译驱动程序之前要先编译内核。
-
编译驱动时用的内核和嵌入式板子上运行的内核,要一致(不一致的话,不能正常安装 .ko 模块,强装会有意想不到的问题)。
-
板子使用新编译出来的内核时,板子上原来的其他驱动也要更换为新编译出来的。
编译内核
不同的开发板对应不同的配置文件,配置文件位于内核源码 arch/arm/configs/
目录。
在 Linux 源码目录里执行:
make mrproper make xxx_imx6ull_defconfig make zImage -j4 make dtbs
释义:
-
make mrproper
命令会删除所有的编译生成文件、内核配置文件(.config文件)和各种备份文件,所以几乎只在第一次执行内核编译前才用这条命令。make clean
命令则是用于删除大多数的编译生成文件,但是会保留内核的配置文件 .config,还有足够的编译支持来建立扩展模块。所以你若只想删除前一次编译过程的残留数据,只需执行 make clean 命令。总而言之,make mrproper 删除的范围比 make clean 大,实际上,make mrproper 在具体执行时第一步就是调用 make clean。
得到 内核文件 和 设备树文件 这两个文件:
arch/arm/boot/zImage arch/arm/boot/dts/100ask_imx6ull-14x14.dtb
编译内核模块
在 Linux 源码目录里执行:
make ARCH=arm CROSS_COMPILE=<选择一个编译器,比如 Linaro 的 arm-linux-gnueabihf-> modules sudo make ARCH=arm INSTALL_MOD_PATH=/home/book/nfs_rootfs modules_install # 编译出的模块 都装存到 /home/book/nfs_rootfs 下,自行更换
释义:
-
第一条,如果设置好了 ARCH 和 CROSS_COMPILE 环境变量,直接键入
make modules
也可。 -
第二条命令是把模块安装到
/home/book/nfs_rootfs
目录下备用 , 会得到/home/book/nfs_rootfs/lib/modules
目录。
更新目标板
有很多种方式传输文件,详见 "PC 与 嵌入式板 传输文件的方式汇总" 章节。将 zImage 、100ask_imx6ull-14x14.dtb 和 内核模块的 lib 目录 这三者 分别放到嵌入式板子的 /boot 、 /boot 和 /lib 目录,比如使用方便的 nfs 文件系统;然后存储 sync
,重启 reboot
。
编写、编译驱动
按照驱动程序的编写规则,写好驱动程序(hello_drv.c)和 对其进行编译的 Makefile 文件,以及 相应的 应用程序/测试程序(hello_drv_test.c)。
举例 Makefile 文件(这里面也同时将 测试程序 给编译了):
# 修改为 Linux 内核所在目录 KERN_DIR = /home/book/100ask_roc-rk3399-pc/linux-4.4 all:make -C $(KERN_DIR) M=`pwd` modules $(CROSS_COMPILE)gcc -o hello_drv_test hello_drv_test.c # 这里就用到 环境变量 CROSS_COMPILE 了 clean:make -C $(KERN_DIR) M=`pwd` modules cleanrm -rf modules.orderrm -f hello_drv_test obj-m += hello_drv.o
确保三个环境变量 ARCH、CROSS_COMPILE 和 PATH(交叉编译器的 /bin 目录)都以就绪。
-
执行
make
或make all
。产生 驱动程序的内核模块(hello_drv.ko)和 测试程序 ARM 端的二进制可执行文件,共两个文件,转移其到 嵌入式目标板子上。 -
在嵌入式 Linux 开发板上 安装驱动程序模块
insmod hello_drv.ko
。 -
在
lsmod
命令下可以看到hello_drv
模块;执行cat /proc/devices
可以看到 对应的设备及其主设备号;执行ls -l /dev/<设备名称>
可以看到此设备的主、此设备号等更多信息。 -
执行测试程序进行验证。
linux内核编译操作
make bzImage # 编译生成压缩的内核二进制文件 make vmlinux # 编译生成二进制内核文件 make modules # 编译生成内核模块 make modules_install # 安装模块 make bzdisk|fdimage|isoimage # 编译生成启动软盘镜像或者光盘镜像 make install # 安装内核文件 make all # 相当于vmlinux+modules+bzImage make rpm # 构建内核rpm包 make foo/bar/foobar.ko # 编译单个驱动 make header_install # 安装内核头文件 make M=some/sub/dir # 编译指定目录 make O=/path/to/some/dir # 指定生成的文件放到该目录 make kernelversion # 输出内核版本信息 make kernelrelease # 输出内核发行标识 make rpm-pkg|deb-pkg|tar-pkg|targz-pkg|tarbz2-pkg # 构建这种格式的内核包 make clean # 清除生成文件(保留.config和部分模块文件) make mrproper # 清除全部文件(包括.config和备份文件) make distclean # 在make mrproper上还清除编辑器其他的备份文件
学至此的一点启示
芯片厂家(大概)应该都会提供完整的 U-boot、 Linux 内核、芯片上硬件资源的驱动程序。
看韦东山的 imx6ull 板子的裸机开发源码,可以得知,启动文件 .s 文件需要看懂,都大同小异,然后官网会提供所有寄存器的 .h 文件及其结构体,然后每个外设似乎还会提供初始化、配置的代码(因为韦的源码里面,外设底层配置代码为英文注释的,99%的概率是官方提供的),这样就好了嘛,外设的底层驱动可以都扒官方例程。
构建系统简约步骤
这里只简约说明编译步骤,并非详细使用说明(以后的系列文章可能会有)。
每个部分单独手动简约步骤
以下工作进行前,先配置好环境变量和开发链工具等工作,详见 "准备交叉编译工具链" 章节。
1、编译 u-boot,配置文件位于 u-boot 源码的 configs/ 目录,生成 u-boot 启动镜像 u-boot-dtb.imx。在 Uboot 目录下执行:
make distclean make mx6ull_14x14_evk_defconfig make
2、编译内核,配置文件位于内核源码 arch/arm/configs/ 目录,生成 arch/arm/boot/zImage 内核文件 和 arch/arm/boot/dts/xxx_imx6ull-14x14.dtb 设备树文件。在 Linux 内核目录下执行:
Linux-4.9.88$ make mrproper Linux-4.9.88$ make xxx_imx6ull_defconfig Linux-4.9.88$ make zImage -j4 Linux-4.9.88$ make dtbs
3、编译内核模块,并把模块文件导入 /home/book/nfs_rootfs/lib/modules 目录。在 Linux 内核目录下执行:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules sudo make ARCH=arm INSTALL_MOD_PATH=/home/book/nfs_rootfs modules_install
使用 Buildroot 构建系统简约步骤
Linux 平台上有许多开源的嵌入式 linux 系统构建框架,这些框架极大的方便了开发者进行嵌入式系统的定制化构建,目前比较常见的有 OpenWrt, Buildroot, Yocto 等等。其中 Buildroot 功能强大,使用简单,而且采用了类似于 linux kernel 的配置和编译框架。
制作根文件系统方法比较:
-
Busybox。Busybox 本身包含了很了 Linux 命令,但是要编译其他程序的话需要手工下载、编译,如果它需要某些依赖库,你还需要手工下载、编译这些依赖库。如果想做一个极简的文件系统,可以使用 Busybox 手工制作。
-
Buildroot。它是一个自动化程序很高的系统,可以在里面配置、编译内核,配置编译 u-boot、配置编译根文件系统。在编译某些APP时,它会自动去下载源码、下载它的依赖库,自动编译这些程序。Buildroot 的语法跟一般的 Makefile 语法类似,很容易掌握。
-
Yocto。NXP、 ST 等公司的官方开发包是使用 Yocto,Yocto 语法复杂,容量大(10GB 以上),编译时间长。
Buildroot 是一组 Makefile 和补丁,可简化并自动化地为嵌入式系统构建完整的、可启动的 Linux 环境(包括 bootloader、 Linux 内核、包含各种 APP 的文件系统)。 Buildroot 运行于 Linux 平台,可以使用交叉编译工具为多个目标板构建嵌入式 Linux 平台。 Buildroot 可以自动构建所需的交叉编译工具链,创建根文件系统,编译 Linux 内核映像,并生成引导加载程序用于目标嵌入式系统,或者它可以执行这些步骤的任何独立组合。例如,可以单独使用已安装的交叉编译工具链,而 Buildroot 仅创建根文件系统。
学习更多关于 Buildroot 知识请参考这里。
扩展学习:
-
buildroot 下进入 menuconfig 包选择配置配置界面
make menuconfig
。 -
buildroot 下单独编译 u-boot
make uboot-rebuild
。 -
buildroot 下进入内核 make menuconfig 配置选项界面
make linux-menuconfig
。 -
buildroot 下单独编译某个软件包
make <pkg>-rebuild
。 -
buildroot 下进入 busybox 配置界面
make busybox-menuconfig
。 -
buildroot 下生成系统 sdk,最后生成的目录在 output/images/ 目录下
make sdk
。
构建根文件系统:
在 Buildroot 目录下执行:
make clean make xxx_imx6ull_defconfig make all
漫长长长(2~6个小时,视电脑性能)的等待后编译完成。
可以配置多个不同的配置文件 xxx_imx6ull_defconfig,比如有的带 qt5 ,有的用于构建最精简的文件系统,有的用于另一块板子等待。
编译成功后文件输出路径为 output/images:
buildroot 20xx.xx ├── output├── images├── xxx_imx6ull-14x14.dtb <--设备树文件├── rootfs.ext2 <--ext2 格式根文件系统├── rootfs.ext4 -> rootfs.ext2 <--ext2 格式根文件系统├── rootfs.tar├── rootfs.tar.bz2 <--打包并压缩的根文件系统,用于 NFSROOT 启动├── sdcard.img <--完整的 SD 卡系统镜像├── u-boot-dtb.imx <--u-boot 镜像└── zImage <--内核镜像
对应的文件更新到嵌入式板子的对应位置,或者使用 sdcard.img 或者 emmc.img 完整系统映像文件烧入 sd卡 或 emmc。
相关文章:
ARM Linux 基础学习 / 配置交叉编译工具链 / 编译 Linux 应用和驱动 / 编译内核
编辑整理 by Staok。 本文部分内容摘自 “100ask imx6ull” 开发板的配套资料(如 百问网的《嵌入式Linux应用开发完全手册》,在 百问网 imx6ull pro 开发板 页面 中的《2.1 100ASK_IMX6ULL_PRO:开发板资料》或《2.2 全系列Linux教程…...

通讯协议学习之路(实践部分):SPI开发实践
通讯协议之路主要分为两部分,第一部分从理论上面讲解各类协议的通讯原理以及通讯格式,第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN;视频会发布在bilibili(UID:399951374) 本文…...

【系统安装】ubuntu20.04启动盘制作,正经教程,小白安装教程,百分百成功安装
1.所需材料: 64GBU盘(其实8g和16g也可以) 2.制作U盘启动盘 使用windows制作ubuntu 20.04启动盘 1)下载制作工具:Rufus:Rufus - 轻松创建 USB 启动盘 2)插入用来做启动盘的U盘 3࿰…...
2023云计算发展趋势
目录 一、云计算是什么? 二、云计算发展趋势 三、总结 一、云计算是什么? 云计算是一种基于互联网的计算方式,通过网络连接的方式提供计算能力、存储服务、应用程序和数据资源。它通常通过虚拟化技术实现多个计算机资源的池化,…...

C# .NET Core API Controller以及辅助专案
准备工作 Windows 10Visual Studio 2019(2017就有可以集中发布到publish目录的功能了吧)C#将方法封装(据说可以提高效率,就像是我们用的dll那种感觉新增专案作为我们API的辅助专案(作用类似dll,此处,你也可以在你自己的API专案里建文件夹,但…...

asp.net图书管理系统
asp.net图书管理系统 基本操作图书管理 读者管理 借书 修改资料 修改密码 说明文档 运行前附加数据库.mdf(或sql生成数据库) 主要技术: 基于C#winform架构和sql server数据库 功能模块: 图书管理 读者管理 借书 修改资料 修改…...
概念解析 | LoRA:低秩矩阵分解在神经网络微调中的作用
注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:基于低秩矩阵分解的神经网络微调方法LoRA LoRA: Low-Rank Adaptation of Large Language Models LoRA由如下论文提出,详细信息请参见论文原文 https://arxiv.org/abs/2106.0968…...

前端---CSS的盒模型
文章目录 什么是盒模型?设置边框设置内边距设置外边距块级元素水平居中 什么是盒模型? 页面上的每个HTML元素都是一个一个的“盒子”,这些盒子由:内容、内边距、边框、外边距组成。 我们可以和住的房子联系起来,更好…...

Linux可以投屏到电视吗?用网页浏览器就能投屏到电视!
Linux系统的电脑如果要投屏到安卓电视屏幕上,可以使用投屏工具AirDroid Cast的网页版和TV版一起实现。 首先,在Linux系统的电脑里用chrome浏览器或edge浏览器打开webcast.airdroid.com。这就是AirDroid Cast的网页版。你可以看到中间白色框框的右上角有个…...

云汇优想:抖音矩阵系统有哪些类型?
抖音作为中国最热门的短视频分享平台之一,不断推陈出新,在内容管理和展示方面也进行了创新。其中,抖音矩阵系统是一项重要的功能,它提供了多种类型的矩阵,帮助用户更好地管理和展示自己的内容。那么,抖音矩…...
XSS 漏洞的理解
谈一谈你对XSS 漏洞的理解 1.漏洞描述 跨站脚本攻击是一种Web安全漏洞。攻击者利用该漏洞,在网页中注入恶意代码,等待受害者访问被注入恶意代码的网页。网页中的恶意代码会被浏览器识别,并执行。恶意代码通常是Javascript脚本,由…...

cocosCreator 之内存管理和释放
版本: 3.4.0 语言: TypeScript 环境: Mac 回顾 前面有两篇博客说明了: cocosCreator 之 resources动态加载、预加载 讲述了静态引用资源,动态加载和预加载相关cocosCreator 之 Bundle 讲述了AssetManager关于对内置…...

飞天使-template模版相关知识
遇到报错django.template.exceptions.TemplateSyntaxError: ‘staticfiles’ is not a registered tag library. Must ROOT_URLCONF TEMPLATES [{BACKEND: django.template.backends.django.DjangoTemplates,DIRS: [os.path.join(BASE_DIR, templates)],APP_DIRS: True,OPTI…...
一、Hadoop3.1.3集群搭建
一、集群规划 hadoop01(209.2)hadoop02(209.3)hadoop03(209.4)HDFSNameNode DataNodeDataNodeSecondaryNameNode DataNodeYARNNodeManagerResourceManager NodeManagerNodeManager NameNode和SecondaryNameNode不要放在同一台服务器上 二、创建用户 useradd atguigu passwd *…...
QML16、从 C++ 定义 QML 类型
从 C++ 定义 QML 类型 当使用 C++ 代码扩展 QML 时,可以向 QML 类型系统注册 C++ 类,以使该类能够用作 QML 代码中的数据类型。 虽然任何 QObject 派生类的属性、方法和信号都可以从 QML 访问,如将 C++ 类型的属性暴露给 QML 中所讨论的,但在向类型系统注册之前,此类类不能…...

【中间件篇-Redis缓存数据库06】Redis主从复制/哨兵 高并发高可用
Redis高并发高可用 复制 在分布式系统中为了解决单点问题,通常会把数据复制多个副本部署到其他机器,满足故障恢复和负载均衡等需求。Redis也是如此,它为我们提供了复制功能,实现了相同数据的多个Redis 副本。复制功能是高可用Re…...

LeetCode(12)时间插入、删除和获取随机元素【数组/字符串】【中等】
目录 1.题目2.答案3.提交结果截图 链接: 380. O(1) 时间插入、删除和获取随机元素 1.题目 实现RandomizedSet 类: RandomizedSet() 初始化 RandomizedSet 对象bool insert(int val) 当元素 val 不存在时,向集合中插入该项,并返回…...

前端面试题 计算机网络
文章目录 ios 7层协议tcp协议和udp协议的区别tcp协议如何确保数据的可靠http和tcp的关系url输入地址到呈现网页有哪些步骤post和get本质区别,什么时候会触发二次预检GET请求:POST请求:触发二次预检(CORS中的预检请求)&…...

windows aseprite编译指南(白嫖)
aseprite是画像素图的专业软件,steam上有售卖,不过官方也在github开源了,需要自己编译。 1. 首先获取源码 直接在github上clone源码到本地指定目录 需要先下载git,下载好后在git.bash中执行(需要腾一个用来安放源码的…...

生活污水处理一体化处理设备有哪些
生活污水处理一体化处理设备有多种类型,包括但不限于以下几种: 鼓风机:提供曝气系统所需的气流。潜水污水提升泵:将污水从低处提升到高处。旋转式滚筒筛分机:对污水中的悬浮物进行分离和筛选。回旋式格栅:…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)
错误一:yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因,后面把yaml.safe_dump直接替换成yaml.dump,确实能保存,但出现乱码: 放弃yaml.dump,又切…...