Android vendor.img中文件执行权问题
问题
Android 9、11往vendor.img增加文件,烧写到设备后发现增加的可执行文件没有执行权限。经过漫长查找,终于找到了问题的根源,谨以此篇献给哪些脚踏实地的人们。
根本原因
system/core/libcutils/fs_config.cpp文件,fs_config函数根据android_dirs、android_files中的配置修改文件的uid、gui、mode(权限)。除了/vendor/bin/、/vendor/xbin/目录下的文件的有执行权限,/vendor目录下的其他文件都没有执行权限。
vendor.img是如何生成的
build/core/Makefile
INSTALLED_VENDORIMAGE_TARGET
3314 # We just build this directly to the install location.
3315 INSTALLED_VENDORIMAGE_TARGET := $(BUILT_VENDORIMAGE_TARGET)
3316 $(INSTALLED_VENDORIMAGE_TARGET): \
3317 $(INTERNAL_USERIMAGES_DEPS) \
3318 $(INTERNAL_VENDORIMAGE_FILES) \
3319 $(INSTALLED_FILES_FILE_VENDOR) \
3320 $(RECOVERY_FROM_BOOT_PATCH)
3321 $(build-vendorimage-target)
build-vendorimage-target
BUILT_VENDORIMAGE_TARGET
3294 vendorimage_intermediates := \
3295 $(call intermediates-dir-for,PACKAGING,vendor)
3296 BUILT_VENDORIMAGE_TARGET := $(PRODUCT_OUT)/vendor.img
3297 define build-vendorimage-target
3298 # $(hide) /usr/bin/python build/tools/rcmerge.py $(subst full_,,$(TARGET_PRODUCT)) vnd
3299 $(call pretty,"Target vendor fs image: $(INSTALLED_VENDORIMAGE_TARGET)")
3300 @mkdir -p $(TARGET_OUT_VENDOR)
3301 @rm -rf $(TARGET_OUT_VENDOR)/avm
3302 @mkdir -p $(TARGET_OUT_VENDOR)/avm
3303 $(call create-vendor-odm-symlink)
3304 @mkdir -p $(vendorimage_intermediates) && rm -rf $(vendorimage_intermediates)/vendor_image_info.txt
3305 $(hide) cp -rf $(TOP)/vendor/autochips/proprietary/frameworks/base/avm/file/* $(TARGET_OUT_VENDOR)/avm
3306 $(call generate-image-prop-dictionary, $(vendorimage_intermediates)/vendor_image_info.txt,vendor,skip_fsck=true)
3307 PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
3308 $(BUILD_IMAGE) \
3309 $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt \
3310 $(INSTALLED_VENDORIMAGE_TARGET) $(TARGET_OUT)
3311 $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET) $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_VENDORIMAGE_PARTITION_SIZE))
3312 endef
build_image
build/core/config.mk
635 BUILD_IMAGE := $(HOST_OUT_EXECUTABLES)/build_image$(HOST_EXECUTABLE_SUFFIX)
out/host/linux-x86/bin/build_image
Builds output_image from the given input_directory, properties_file,
and writes the image to target_output_directory.Usage: build_image input_directory properties_file output_image \target_output_directory
build_image.py
build/tools/releasetools/build_image.py
BuildImageMkfs
231 def BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config):
232 """Builds a pure image for the files under in_dir and writes it to out_file.
233
234 Args:
235 in_dir: Path to input directory.
236 prop_dict: A property dict that contains info like partition size. Values
237 will be updated with computed values.
238 out_file: The output image file.
239 target_out: Path to the TARGET_OUT directory as in Makefile. It actually
240 points to the /system directory under PRODUCT_OUT. fs_config (the one
241 under system/core/libcutils) reads device specific FS config files from
242 there.
243 fs_config: The fs_config file that drives the prototype
244
245 Raises:
246 BuildImageError: On build image failures.
247 """
build_command
mkuserimg_mke2fs -s out/target/product/ac8257_64bit/vendor out/target/product/ac8257_64bit/vendor.img ext4 vendor 825540608 -j 0 -D out/target/product/ac8257_64bit/system -L vendor -M 0 --inode_size 256 out/target/product/ac8257_64bit/obj/ETC/file_contexts.bin_intermediates/file_contexts.bin
mkuserimg_mke2fs.py
system/extras/ext4_utils/mkuserimg_mke2fs.py
mke2fs
Usage: mke2fs [-c|-l filename] [-b block-size] [-C cluster-size][-i bytes-per-inode] [-I inode-size] [-J journal-options][-G flex-group-size] [-N number-of-inodes] [-d root-directory][-m reserved-blocks-percentage] [-o creator-os][-g blocks-per-group] [-L volume-label] [-M last-mounted-directory][-O feature[,...]] [-r fs-revision] [-E extended-option[,...]][-t fs-type] [-T usage-type ] [-U UUID] [-e errors_behavior][-z undo_file][-jnqvDFSV] device [blocks-count]
MKE2FS_CONFIG=out/soong/.temp/tmpGyRCz5mke2fs -O ^has_journal -L vendor -I 256 -M /vendor -m 0 -E android_sparse -t ext4 -b 4096 out/target/product/ac8257_64bit/vendor.img 201548
e2fsdroid
e2fsdroid -p out/target/product/ac8257_64bit/system -S out/target/product/ac8257_64bit/obj/ETC/file_contexts.bin_intermediates/file_contexts.bin -f out/target/product/ac8257_64bit/vendor -a /vendor out/target/product/ac8257_64bit/vendor.img
file_contexts
obj/ETC/file_contexts.bin_intermediates
system/sepolicy/private/file_contexts
device/autochips/sepolicy/basic/plat_private/file_contexts
device/autochips/sepolicy/bsp/plat_private/file_contexts
SetUpInDirAndFsConfig
e2fsdroid源在何处
external/e2fsprogs/contrib/android/e2fsdroid.c
Usage
e2fsdroid [-B block_list] [-D basefs_out] [-T timestamp][-C fs_config] [-S file_contexts] [-p product_out][-a mountpoint] [-d basefs_in] [-f src_dir] [-e] [-s] image
android_configure_fs
326 errcode_t android_configure_fs(ext2_filsys fs, char *src_dir, char *target_out,
327 char *mountpoint,
328 struct selinux_opt *seopts EXT2FS_ATTR((unused)),
329 unsigned int nopt EXT2FS_ATTR((unused)),
330 char *fs_config_file, time_t fixed_time,
331 const struct ugid_map* uid_map,
332 const struct ugid_map* gid_map)
333 {359 /* Load the FS config */
360 if (fs_config_file) {
361 retval = load_canned_fs_config(fs_config_file);
362 if (retval < 0) {
363 com_err(__func__, retval,
364 _("while loading fs_config \"%s\""),
365 fs_config_file);
366 return retval;
367 }
368 fs_config_func = canned_fs_config;
369 } else if (mountpoint)
370 fs_config_func = fs_config;
371
372 return __android_configure_fs(fs, src_dir, target_out, mountpoint,
373 fs_config_func, sehnd, fixed_time,
374 uid_map, gid_map);
375 }
fs_config
system/core/libcutils/fs_config.cpp文件,fs_config函数根据android_dirs、android_files中的配置修改文件的uid、gui、mode(权限)。除了/vendor/bin/、/vendor/xbin/目录下的文件的有执行权限,/vendor目录下的其他文件都没有执行权限。
366 for (pc = dir ? android_dirs : android_files; pc->prefix; pc++) {
367 if (fs_config_cmp(dir, pc->prefix, strlen(pc->prefix), path, plen)) {
368 break;
369 }
370 }
371 *uid = pc->uid;
372 *gid = pc->gid;
373 *mode = (*mode & (~07777)) | pc->mode;
374 *capabilities = pc->capabilities;
375 }
android_dirs
59 static const struct fs_path_config android_dirs[] = {60 // clang-format off61 { 00770, AID_SYSTEM, AID_CACHE, 0, "cache" },62 { 00555, AID_ROOT, AID_ROOT, 0, "config" },63 { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app" },64 { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private" },65 { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app-ephemeral" },66 { 00771, AID_ROOT, AID_ROOT, 0, "data/dalvik-cache" },67 { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/data" },68 { 00771, AID_SHELL, AID_SHELL, 0, "data/local/tmp" },69 { 00771, AID_SHELL, AID_SHELL, 0, "data/local" },70 { 00770, AID_DHCP, AID_DHCP, 0, "data/misc/dhcp" },71 { 00771, AID_SHARED_RELRO, AID_SHARED_RELRO, 0, "data/misc/shared_relro" },72 { 01771, AID_SYSTEM, AID_MISC, 0, "data/misc" },73 { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/Music" },74 { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media" },75 { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest" },76 { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest64" },77 { 00750, AID_ROOT, AID_SHELL, 0, "data/benchmarktest" },78 { 00750, AID_ROOT, AID_SHELL, 0, "data/benchmarktest64" },79 { 00775, AID_ROOT, AID_ROOT, 0, "data/preloads" },80 { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data" },81 { 00755, AID_ROOT, AID_SYSTEM, 0, "mnt" },82 { 00751, AID_ROOT, AID_SHELL, 0, "product/bin" },83 { 00777, AID_ROOT, AID_ROOT, 0, "sdcard" },84 { 00751, AID_ROOT, AID_SDCARD_R, 0, "storage" },85 { 00751, AID_ROOT, AID_SHELL, 0, "system/bin" },86 { 00755, AID_ROOT, AID_ROOT, 0, "system/etc/ppp" },87 { 00755, AID_ROOT, AID_SHELL, 0, "system/vendor" },88 { 00751, AID_ROOT, AID_SHELL, 0, "system/xbin" },89 { 00751, AID_ROOT, AID_SHELL, 0, "system/apex/*/bin" },90 { 00751, AID_ROOT, AID_SHELL, 0, "system_ext/bin" },91 { 00751, AID_ROOT, AID_SHELL, 0, "system_ext/apex/*/bin" },92 { 00751, AID_ROOT, AID_SHELL, 0, "vendor/bin" },93 { 00755, AID_ROOT, AID_SHELL, 0, "vendor" },94 { 00755, AID_ROOT, AID_ROOT, 0, 0 },95 // clang-format on96 };
android_files
139 static const struct fs_path_config android_files[] = {
140 // clang-format off
141 { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app/*" },
142 { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-ephemeral/*" },
143 { 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private/*" },
144 { 00644, AID_APP, AID_APP, 0, "data/data/*" },
145 { 00644, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/*" },
146 { 00640, AID_ROOT, AID_SHELL, 0, "data/nativetest/tests.txt" },
147 { 00640, AID_ROOT, AID_SHELL, 0, "data/nativetest64/tests.txt" },
148 { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest/*" },
149 { 00750, AID_ROOT, AID_SHELL, 0, "data/nativetest64/*" },
150 { 00750, AID_ROOT, AID_SHELL, 0, "data/benchmarktest/*" },
151 { 00750, AID_ROOT, AID_SHELL, 0, "data/benchmarktest64/*" },
152 { 00600, AID_ROOT, AID_ROOT, 0, "default.prop" }, // legacy
153 { 00600, AID_ROOT, AID_ROOT, 0, "system/etc/prop.default" },
154 { 00600, AID_ROOT, AID_ROOT, 0, "odm/build.prop" }, // legacy; only for P release
155 { 00600, AID_ROOT, AID_ROOT, 0, "odm/default.prop" }, // legacy; only for P release
156 { 00600, AID_ROOT, AID_ROOT, 0, "odm/etc/build.prop" },
157 { 00444, AID_ROOT, AID_ROOT, 0, odm_conf_dir + 1 },
158 { 00444, AID_ROOT, AID_ROOT, 0, odm_conf_file + 1 },
159 { 00444, AID_ROOT, AID_ROOT, 0, oem_conf_dir + 1 },
160 { 00444, AID_ROOT, AID_ROOT, 0, oem_conf_file + 1 },
161 { 00600, AID_ROOT, AID_ROOT, 0, "product/build.prop" },
162 { 00444, AID_ROOT, AID_ROOT, 0, product_conf_dir + 1 },
163 { 00444, AID_ROOT, AID_ROOT, 0, product_conf_file + 1 },
164 { 00600, AID_ROOT, AID_ROOT, 0, "system_ext/build.prop" },
165 { 00444, AID_ROOT, AID_ROOT, 0, system_ext_conf_dir + 1 },
166 { 00444, AID_ROOT, AID_ROOT, 0, system_ext_conf_file + 1 },
167 { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/crash_dump32" },
168 { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/crash_dump64" },
169 { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/debuggerd" },
170 { 00550, AID_LOGD, AID_LOGD, 0, "system/bin/logd" },
171 { 00700, AID_ROOT, AID_ROOT, 0, "system/bin/secilc" },
172 { 00750, AID_ROOT, AID_ROOT, 0, "system/bin/uncrypt" },
173 { 00600, AID_ROOT, AID_ROOT, 0, "system/build.prop" },
174 { 00444, AID_ROOT, AID_ROOT, 0, sys_conf_dir + 1 },
175 { 00444, AID_ROOT, AID_ROOT, 0, sys_conf_file + 1 },
176 { 00440, AID_ROOT, AID_SHELL, 0, "system/etc/init.goldfish.rc" },
177 { 00550, AID_ROOT, AID_SHELL, 0, "system/etc/init.goldfish.sh" },
178 { 00550, AID_ROOT, AID_SHELL, 0, "system/etc/init.ril" },
179 { 00555, AID_ROOT, AID_ROOT, 0, "system/etc/ppp/*" },
180 { 00555, AID_ROOT, AID_ROOT, 0, "system/etc/rc.*" },
181 { 00750, AID_ROOT, AID_ROOT, 0, "vendor/bin/install-recovery.sh" },
182 { 00600, AID_ROOT, AID_ROOT, 0, "vendor/build.prop" },
183 { 00600, AID_ROOT, AID_ROOT, 0, "vendor/default.prop" },
184 { 00440, AID_ROOT, AID_ROOT, 0, "vendor/etc/recovery.img" },
185 { 00444, AID_ROOT, AID_ROOT, 0, ven_conf_dir + 1 },
186 { 00444, AID_ROOT, AID_ROOT, 0, ven_conf_file + 1 },
187
188 // the following two files are INTENTIONALLY set-uid, but they
189 // are NOT included on user builds.
190 { 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procmem" },
191 { 04750, AID_ROOT, AID_SHELL, 0, "system/xbin/su" },
192
193 // the following files have enhanced capabilities and ARE included
194 // in user builds.
195 { 00700, AID_SYSTEM, AID_SHELL, CAP_MASK_LONG(CAP_BLOCK_SUSPEND),
196 "system/bin/inputflinger" },
197 { 00750, AID_ROOT, AID_SHELL, CAP_MASK_LONG(CAP_SETUID) |
198 CAP_MASK_LONG(CAP_SETGID),
199 "system/bin/run-as" },
200 { 00750, AID_ROOT, AID_SHELL, CAP_MASK_LONG(CAP_SETUID) |
201 CAP_MASK_LONG(CAP_SETGID),
202 "system/bin/simpleperf_app_runner" },
203 { 00755, AID_ROOT, AID_ROOT, 0, "first_stage_ramdisk/system/bin/e2fsck" },
204 { 00755, AID_ROOT, AID_ROOT, 0, "first_stage_ramdisk/system/bin/tune2fs" },
205 { 00755, AID_ROOT, AID_ROOT, 0, "first_stage_ramdisk/system/bin/resize2fs" },
206 // generic defaults
207 { 00755, AID_ROOT, AID_ROOT, 0, "bin/*" },
208 { 00640, AID_ROOT, AID_SHELL, 0, "fstab.*" },
209 { 00750, AID_ROOT, AID_SHELL, 0, "init*" },
210 { 00755, AID_ROOT, AID_SHELL, 0, "odm/bin/*" },
211 { 00755, AID_ROOT, AID_SHELL, 0, "product/bin/*" },
212 { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/*" },
213 { 00755, AID_ROOT, AID_SHELL, 0, "system/xbin/*" },
214 { 00755, AID_ROOT, AID_SHELL, 0, "system/apex/*/bin/*" },
215 { 00755, AID_ROOT, AID_SHELL, 0, "system_ext/bin/*" },
216 { 00755, AID_ROOT, AID_SHELL, 0, "system_ext/apex/*/bin/*" },
217 { 00755, AID_ROOT, AID_SHELL, 0, "vendor/bin/*" },
218 { 00755, AID_ROOT, AID_SHELL, 0, "vendor/xbin/*" },
219 { 00771, AID_ROOT, AID_SYSTEM, 0, "avm/*" },
220 { 00644, AID_ROOT, AID_ROOT, 0, 0 },
221 // clang-format on
222 };
如何调试
build_image.py
build/core
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -341,8 +341,12 @@ def BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config):raise BuildImageError("Error: unknown filesystem type: {}".format(fs_type))+ if "vendor" == prop_dict["mount_point"]:
+ print("build_command: %s" % (build_command))try:mkfs_output = common.RunAndCheckOutput(build_command)
+ if "vendor" == prop_dict["mount_point"]:
+ print("mkfs_output: %s" % mkfs_output)except:try:du = GetDiskUsage(in_dir)
mkuserimg_mke2fs.py
system/extras
--- a/ext4_utils/mkuserimg_mke2fs.py
+++ b/ext4_utils/mkuserimg_mke2fs.py
@@ -223,6 +223,7 @@ def main(argv):if args.timestamp:mke2fs_env["E2FSPROGS_FAKE_TIME"] = args.timestamp+ print("mke2fs_cmd: %s, mke2fs_env: %s\n" % (mke2fs_cmd, mke2fs_env))output, ret = RunCommand(mke2fs_cmd, mke2fs_env)print(output)if ret != 0:
@@ -234,6 +235,7 @@ def main(argv):if args.timestamp:e2fsdroid_env["E2FSPROGS_FAKE_TIME"] = args.timestamp+ print("e2fsdroid_cmd: %s, e2fsdroid_env: %s\n" % (e2fsdroid_cmd, e2fsdroid_env))output, ret = RunCommand(e2fsdroid_cmd, e2fsdroid_env)# The build script is parsing the raw output of e2fsdroid; keep the pattern# unchanged for now.
fs_config.cpp
system/core
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -367,6 +367,7 @@ void fs_config(const char* path, int dir, const char* target_out_path, unsigned*break;}}
+ printf("%s %s, prefix: %s %o\n", path, target_out_path, pc->prefix, pc->mode);*uid = pc->uid;*gid = pc->gid;*mode = (*mode & (~07777)) | pc->mode;
相关文章:
Android vendor.img中文件执行权问题
问题 Android 9、11往vendor.img增加文件,烧写到设备后发现增加的可执行文件没有执行权限。经过漫长查找,终于找到了问题的根源,谨以此篇献给哪些脚踏实地的人们。 根本原因 system/core/libcutils/fs_config.cpp文件,fs_confi…...
关于使用微服务的注意要点总结
一、防止过度设计 微服务的拆分一定要结合团队人员规模来考虑,笔者就曾遇到过一个公司的项目,是从外部采购回来的,微服务划分为十几个应用,我们在此项目基础上进行自行维护和扩展。由于公司业务规模不大,而且二次开发的…...
C++17 新增属性详解
文章目录 1. [[fallthrough]]用途示例应用场景 2. [[maybe_unused]]用途示例应用场景 3. [[nodiscard]]用途示例应用场景 总结 C17标准引入了多个新的属性(Attributes),这些属性为代码提供了更丰富的语义表达能力,同时帮助编译器生…...
使用python-docx包进行多文件word文字、字符批量替换
1、首先下载pycharm。 2、改为中文。 3、安装python-docx包。 搜索包名字,安装。 4、新建py文件,写程序。 from docx import Documentdef replace1(array1):# 替换词典(标签值按实际情况修改)dic {替换词1: array1[0], 替换…...
15_业务系统基类
创建脚本 SystemRoot.cs 因为 业务系统基类的子类 会涉及资源加载服务层ResSvc.cs 和 音乐播放服务层AudioSvc.cs 所以在业务系统基类 提取引用资源加载服务层ResSvc.cs 和 音乐播放服务层AudioSvc.cs 并调用单例初始化 using UnityEngine; // 功能 : 业务系统基类 public c…...
Pyecharts之散点图的视觉扩展
在数据可视化中,散点图是一种强大的工具,可用于展示数据点在二维平面上的分布情况。通过添加各种视觉组件,我们可以让散点图变得更加丰富和具有表现力,更能反映数据的多维度特征。本文将详细解读如何为散点图添加不同的视觉组件&a…...
Java学习教程,从入门到精通,JDBC删除数据库语法知识点(101)
一、JDBC删除数据库语法知识点 1. 概述 JDBC(Java Database Connectivity)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。 在JDBC中,删除数据库的操作主要是通过执行…...
Baklib如何推动企业知识管理的创新与转型探讨
内容概要 在当今快速发展的数字化时代,企业需要不断适应变化,以保持竞争优势。Baklib作为一款企业知识管理中台,扮演着推动数字化转型的重要角色。它通过提供一个集成的知识管理平台,帮助企业高效管理和共享内部及外部的知识资源…...
【算法】递归型枚举与回溯剪枝初识
递归型枚举与回溯剪枝初识 1.枚举子集2.组合型枚举3.枚举排列4.全排列问题 什么是搜索?搜索,是一种枚举,通过穷举所有的情况来找到最优解,或者统计合法解的个数。因此,搜索有时候也叫作暴搜。搜索一般分为深度优先搜索…...
无人机 PX4 飞控 | PX4源码添加自定义参数方法并用QGC显示与调整
无人机 PX4 飞控 | PX4源码添加自定义参数方法并用QGC显示与调整 0 前言 之前文章添加了一个自定义的模块,本篇文章在之前的自定义模块中,添加两个自定义参数 使用QGC显示出来,并通过QGC调整参数值,代码实现参数更新 新增的参…...
《CPython Internals》阅读笔记:p356-p359
《CPython Internals》学习第 19天,p356-p359 总结,总计 4 页。 一、技术总结 1.benchmark suite The benchmark suite is the tool to use when comparing the complete performance of Python. The Python Benchmark suite is a collection of Pyth…...
Linux--权限
Linux系统的权限管理是保障系统安全的重要机制,以下详细讲解权限相关概念及操作指令: 一、基础权限机制 1. 权限的三元组,读(r)、写(w)、执行(x) 每个文件或目录有三组…...
java后端之登录认证
基础登录功能:根据提供的用户名和密码判断是否存在于数据库 LoginController.java RestController Slf4j public class LoginController {Autowiredprivate UserService userService;PostMapping("/login")public Result login(RequestBody User user) {…...
【矩阵二分】力扣378. 有序矩阵中第 K 小的元素
给你一个 n x n 矩阵 matrix ,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。 请注意,它是 排序后 的第 k 小元素,而不是第 k 个 不同 的元素。 你必须找到一个内存复杂度优于 O(n2) 的解决方案。 示例 1࿱…...
C语言-构造数据类型
1、构造数据类型 结构体、共用体、枚举。 2、结构体 1、结构体的定义 结构体是一个自定义的复合数据类型,它允许将不同类型的数据组合在一起。 struct 结构体名 {数据类型1 成员变量1;数据类型2 成员变量2;数据类型3 成员变量3;数据类型4 成员变量4; } 2、结构体变…...
鸿蒙next 自定义日历组件
效果图预览 20250124-113957 使用说明 1.选择日期左右箭头,实现每月日历切换,示例中超出当前月份,禁止进入下一月,可在代码更改 2.日历中显示当前选择的日期,选中的日期颜色可自定义 3.日历中可展示历史记录作为数据…...
【express-generator】08-路由重定向
前言 通过前面两篇文章的讲解,我们已经介绍完第二阶段的前两点,本篇介绍第三点:路由重定向。 1. 路由重定向概述 路由重定向是指在服务器端将客户端的请求从一个 URL 重定向到另一个 URL 的过程。这通常通过 HTTP 状态码(如 30…...
搭建Spring Boot开发环境
JDK(1.8及以上版本) Apache Maven 3.6.0 修改settings.xml 设置本地仓库位置 <localRepository>D:/repository</localRepository> 设置远程仓库镜像 <mirror><id>alimaven</id><name>aliyun maven</name&…...
Spatial Group-wise Enhance (SGE) module
来源: [1905.09646] Spatial Group-wise Enhance: Improving Semantic Feature Learning in Convolutional Networks 相关工作: #GroupedFeatures #AttentionModels 创新点: 贡献: 提出了一种轻量级的SGE模块,能够…...
二叉搜索树中的搜索(力扣700)
首先介绍一下什么是二叉搜索树。 二叉搜索树是一个有序树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...
聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇
根据 QYResearch 发布的市场报告显示,全球市场规模预计在 2031 年达到 9848 万美元,2025 - 2031 年期间年复合增长率(CAGR)为 3.7%。在竞争格局上,市场集中度较高,2024 年全球前十强厂商占据约 74.0% 的市场…...
【题解-洛谷】P10480 可达性统计
题目:P10480 可达性统计 题目描述 给定一张 N N N 个点 M M M 条边的有向无环图,分别统计从每个点出发能够到达的点的数量。 输入格式 第一行两个整数 N , M N,M N,M,接下来 M M M 行每行两个整数 x , y x,y x,y,表示从 …...
