linux ptrace 图文详解(六) gdb单步调试
目录
一、gdb单步调试介绍
二、单步调试原理
三、MDSCR_EL1对单步调试的支持、及起作用时机
四、代码实现
五、总结
(代码:linux 6.3.1,架构:arm64)
One look is worth a thousand words. —— Tess Flanders
相关链接:
linux ptrace 图文详解(一)基础介绍
linux ptrace 图文详解(二) PTRACE_TRACEME 跟踪程序
linux ptrace 图文详解(三) PTRACE_ATTACH 跟踪程序
linux ptrace 图文详解(四) gdb设置软断点
linux ptrace 图文详解(五) gdb设置硬断点、观察点
一、gdb单步调试介绍
单步调试是一种调试技术,它允许开发者逐行执行程序代码,以便观察程序的执行流程和变量状态。这种调试方式对于理解程序逻辑、定位错误和验证程序行为至关重要。通过单步调试,开发者可以:
-
逐行执行代码,观察每一行代码的执行结果。
-
检查程序中变量的值和状态。
-
观察程序的控制流,包括函数调用和返回。
-
设置断点,以便在特定条件下暂停程序执行。
单步调试主要包括两种模式:逐行调试(step)和逐指令调试(stepi)。逐行调试以源代码行为单位,适合高层次的逻辑分析;逐指令调试以机器指令为单位,适用于底层分析,如汇编代码或驱动开发。GDB通过与操作系统提供的调试接口(如ptrace)协作,控制目标进程的执行,捕获其状态,并在每个步骤后返回控制权给开发者。
二、单步调试原理
gdb 单步调试 主要依赖硬件debug寄存器,以下是gdb单步调试的实现原理:
1)gdb通过ptrace(PTRACE_SINGLESTEP)系统调用陷入内核;
2)ptrace系统调用在内核中找到被调试任务的task_struct对象,并设置TIF_SINGLESTEP标志,代表该任务返回用户态执行时需要使能单步调试功能,并设置该任务内核task_struct对象的寄存器上下文中的spsr,置位DBG_SPSR_SS;
3)接着,将被调试程序添加到内核的ready list中,等待被调度运行,然后ptrace系统调用返回;
4)当内核调度器选中被调试程序调度运行时,会判断其是否置位TIF_SINGLESTEP标志,若置位了话,就将MDSCR_EL1寄存器的SS位置1,使能硬件的单步调试功能;
5)当被调试程序返回用户态执行完第一条指令后,硬件会主动触发一次同步异常并陷入内核;
6)在内核中的异常处理流程中,判断异常类型(EC)为ESR_ELx_EC_SOFTSTP_LOW,于是调用相应处理函数,最终给被调试任务发送一个SIGTRAP信号;
7)被调试任务从异常处理流程中返回后,在返回用户态前夕,检查发现有SIGTRAP信号,于是调用ptrace_signal,给父进程gdb发送信号,并唤醒gdb,最后将自己挂起。
三、MDSCR_EL1对单步调试的支持、及起作用时机
MDSCR(Monitor Debug System Control Register)中的第0位,是Software step control bit,用于single step。
在每次进入内核(kernel_entry)的时候、以及从内核返回用户态(ret_to_user)的时候,检查任务的flag是否有TIF_SINGLESTEP,然后调用disable_step_tsk、enable_step_tsk去清除、设置MDSCR_EL1寄存器中的DBG_MDSCR_SS位。(详见:DDI0487J_a_a-profile_architecture_reference_manual.pdf D2.12 Software Step exceptions)
可见,单步异常触发的时机是被调试任务在用户态执行完第一条指令后,立刻触发一个单步异常陷入内核。
四、代码实现
1、ptrace(PTRACE_SINGLESTEP) 内核实现
ptrace(PTRACESINGLESTEP)在内核中的实现,主要就是为被调试任务的task_struct对象中存储的寄存器上下文中的pstate置上DBG_SPSR_SS标志,代表当前任务需要单步调试,后续该任务被调度时,设置对应debug寄存器去使能单步调试功能。
ptrace_requestswitch (request)case PTRACE_SINGLESTEP:ptrace_resume(child, request, data = 0) {clear_task_syscall_work(child, SYSCALL_TRACE)if (is_singlestep(request)) {user_enable_single_step(task = child) {struct thread_info *ti = task_thread_info(task)if (!test_and_set_ti_thread_flag(ti, TIF_SINGLESTEP)) /* 1) Set TIF_SINGLESTEP to tracee. 若该位已设置则返回1, 否则返回0 */set_regs_spsr_ss(task_pt_regs(task)) {set_user_regs_spsr_ss(&(r)->user_regs)regs->pstate |= DBG_SPSR_SS /* 2) Set DBG_SPSR_SS into child's pstate */}}} else { /* ### if request is not PTRACE_SINGLESTEP, and clear flag */user_disable_single_stepclear_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP)}child->exit_code = datawake_up_state(child, __TASK_TRACED) { /* 3) Change child's state to TASK_RUNNING and enqueue it into rq */try_to_wake_up // if child->state equal to __TASK_TRACED, then wake up itttwu_queuettwu_do_activate {activate_task {enqueue_task(rq, p, flags)p->on_rq = TASK_ON_RQ_QUEUED}ttwu_do_wakeup {WRITE_ONCE(p->__state, TASK_RUNNING)}}}}
2、被调试程序在内核中被调度器选中运行时,针对单步调试的处理
在内核schedule过程中,会检查被调试任务是否标记了需要单步调试。若被标记了话,会设置相应的debug寄存器(MDSCR_EL1.SS位),随后返回用户态执行被调试程序。
entry_handler {kernel_entry \el, \regsize {save hardware contextldr x19, [tsk, #TSK_TI_FLAGS]disable_step_tsk x19, x20 // 4) 进入内核保存现场的时候, 若Task有TIF_SINGLESTEP位,A.K.A // 则将mdscr_el1的DBG_MDSCR_SS位置0{.macro disable_step_tsk, flgs, tmptbz \flgs, #TIF_SINGLESTEP, 9990fmrs \tmp, mdscr_el1bic \tmp, \tmp, #DBG_MDSCR_SSmsr mdscr_el1, \tmpisb // Synchronise with enable_dbg9990:.endm}}mov x0, spbl el\el\ht\()_\regsize\()_\label\()_handlerA.K.Ael0t_64_irq_handler {__el0_irq_handler_commonel0_interruptexit_to_user_mode {prepare_exit_to_user_modeif (unlikely(flags & _TIF_WORK_MASK)) {do_notify_resumeif (thread_flags & _TIF_NEED_RESCHED) {local_daif_restore(DAIF_PROCCTX_NOIRQ)schedule() { /* 5) schedule tracee */}}}}}.if \el == 0b ret_to_userA.K.ASYM_CODE_START_LOCAL(ret_to_user) {ldr x19, [tsk, #TSK_TI_FLAGS] // re-check for single-stepenable_step_tsk x19, x2A.K.A{.macro enable_step_tsk, flgs, tmptbz \flgs, #TIF_SINGLESTEP, 9990fmrs \tmp, mdscr_el1orr \tmp, \tmp, #DBG_MDSCR_SS /* 6) If task has TIF_SINGLESTEP, then set DBG_MDSCR_SS to MDSCR_EL1 */msr mdscr_el1, \tmp}kernel_exit 0 // It will restore general-purpose register}
}
3、单步调试异常触发后,内核中的处理
当被调试程序在用户态执行完第一条指令后,硬件就会主动触发同步异常陷入内核,异常类型为ESR_ELx_EC_SOFTSTP_LOW。在内核中的处理跟前几篇文章断点触发时的处理流程大体相似:将自身挂起,并发送信号给gdb。
entry_handler {kernel_entry \el, \regsize {}mov x0, spbl el\el\ht\()_\regsize\()_\label\()_handlerA.K.Ael0t_64_sync_handler {unsigned long esr = read_sysreg(esr_el1)switch (ESR_ELx_EC(esr)) // #define ESR_ELx_EC(esr) (((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT) 获取ESR中的EC所对应的6位内容case ESR_ELx_EC_SOFTSTP_LOW: // #define ESR_ELx_EC_SOFTSTP_LOW (0x32, aka: 0b110010)el0_dbg {unsigned long far = read_sysreg(far_el1)enter_from_user_mode(regs)do_debug_exception(unsigned long addr_if_watchpoint = far,unsigned int esr = esr,struct pt_regs *regs = regs) {const struct fault_info *inf = esr_to_debug_fault_info(esr)return debug_fault_info + DBG_ESR_EVT(esr) // #define DBG_ESR_EVT(x) (((x) >> 27) & 0x7)inf->fn(addr_if_watchpoint, esr, regs)A.K.Asingle_step_handler {send_user_sigtrap(si_code = TRAP_TRACE) /* 7) Send SIG_TRAP with siginfo to tracee itself */arm64_force_sig_fault(SIGTRAP, si_code, instruction_pointer(regs), "User debug trap") {force_sig_fault(signo = SIGTRAP, code = TRAP_TRACE, (void __user *)far = instruction_pointer(regs))force_sig_fault_to_task(sig, code, addr, current) {struct kernel_siginfo infoinfo.si_signo = sig // SIGTRAPinfo.si_errno = 0info.si_code = code // TRAP_TRACEinfo.si_addr = addr // instruction_pointer(regs)force_sig_info_to_task(&info, t, HANDLER_CURRENT)}}if (!handler_found && user_mode(regs)) {user_rewind_single_step(current) /* 8) Re-enable single step for syscall restarting. */if (test_tsk_thread_flag(task, TIF_SINGLESTEP))set_regs_spsr_ss(task_pt_regs(task))set_user_regs_spsr_ss(&(r)->user_regs)regs->pstate |= DBG_SPSR_SS /* 9) Set DBG_SPSR_SS into pstate */}}}exit_to_user_mode(regs) {prepare_exit_to_user_modelocal_daif_maskdo_notify_resume {if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))do_signal {get_signalptrace_signalptrace_stop(exit_code = signo, why = CLD_TRAPPED, 0, info) /* Stop tracee itself, and notify parent tracer */{current->last_siginfo = infocurrent->exit_code = exit_codedo_notify_parent_cldstop(current, true, why)info.si_signo = SIGCHLDinfo.si_code = why // A.K.A: CLD_TRAPPEDinfo.si_status = tsk->exit_code & 0x7f__group_send_sig_info(SIGCHLD, &info, parent)}}}}}}
}
五、总结
gdb的单步调试,主要依赖硬件debug寄存器(MDSCR_EL1),ptrace(PTRACE_SINGLESTEP) 的作用主要是给task置上需要单步调试的标志,后续被调试任务被调度运行时,会根据是否置位“单步调试”的位,去设置MDSCR_EL1中的SS位,使能单步调试。当程序返回用户态执行完第一条指令后,硬件会主动触发一个单步异常陷入内核。
相关文章:
linux ptrace 图文详解(六) gdb单步调试
目录 一、gdb单步调试介绍 二、单步调试原理 三、MDSCR_EL1对单步调试的支持、及起作用时机 四、代码实现 五、总结 (代码:linux 6.3.1,架构:arm64) One look is worth a thousand words. —— Tess Flanders …...
51、项⽬中的权限管理怎么实现的
答:权限管理有三个很重要的模块; (1)⽤⼾模块:可以给⽤⼾分配不同的⻆⾊ (2)⻆⾊模块:可以授于⽤⼾不同的⻆⾊,不同的⻆⾊有不同权限 (3)权限模块:⽤于管理系统中的权限接⼝,为⻆⾊提供对…...
第五章 SQLite数据库:4、SQLite 进阶用法:常见的约束、PRAGMA 配置、数据操作
SQLite PRAGMA PRAGMA 命令用于查询和设置 SQLite 数据库的环境配置,可以帮助管理数据库的行为和性能。 语法 查询 PRAGMA 值: PRAGMA pragma_name;设置 PRAGMA 值: PRAGMA pragma_name value;常见 PRAGMA 示例 1. auto_vacuum Pragma…...
Windows系统安装Boost库
安装Boost库 下载Boost库源码 Boost Downloads 从Boost官方网站下载源码。请访问Boost官网,选择适合您系统的版本进行下载。下载完成后,解压源文件到您选择的目录。 使用Bootstrap脚本准备编译 在Boost源码的根目录下,找到bootstrap.bat文件…...
2025年03月中国电子学会青少年软件编程(Python)等级考试试卷(三级)答案 + 解析
青少年软件编程(Python)等级考试试卷(三级) 分数:100 题数:38 一、单选题(共25题,共50分) 1. 学校进行体育跳远期末考试,每人有三次机会,取最远的一次作为最后成绩,1班的成绩如下,CLASS1=[[‘李明’,150,152,147],[‘王红’,146,143,146],[‘刘岩’,148,152,150],[…...
Git 解决“Filename too long”问题
在 Windows 系统中使用 Git 时,遇到 Filename too long 错误通常是由于系统默认的路径长度限制(260 字符)导致的。以下是综合多种场景的解决方案: 一、快速解决方法 启用 Git 长路径支持 通过 Git 配置命令允许处理超长文件名&am…...
DeepSeek 助力 Vue3 开发:打造丝滑的日历(Calendar),日历_自定义单元格大小示例(CalendarView01_07)
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...
麦科信汽车诊断示波器在机车维修领域中的应用实例
麦科信汽车诊断示波器在机车维修领域中的应用实例 “Micsig SATO1004的错误帧统计功能与历史波形存储,让我们在诊断间歇性CAN故障时有了决定性武器。这不仅是工具升级,更是维修理念的革新。” — Ian Coffey, Mototek技术总监(欧洲ECU诊…...
Zookeeper 概述
Zookeeper 概述 Zookeeper 概述与使用指南什么是Zookeeper?Zookeeper的主要作用使用Zookeeper的框架典型使用场景1. 配置管理2. 分布式锁3. 服务注册与发现 Zookeeper的缺陷与其他协调服务的比较实际案例:Kafka使用Zookeeper最佳实践 Zookeeper 概述与使…...
leetcode 188. Best Time to Buy and Sell Stock IV
目录 题目描述 第一步,明确并理解dp数组及下标的含义 第二步,分析明确并理解递推公式 1.求dp[i][j].holding 2.求dp[i][j].sold 第三步,理解dp数组如何初始化 第四步,理解遍历顺序 代码 题目描述 这道题把第123题推广为一…...
Kubernetes》》k8s》》Namespace
Namespace 概述 Namespace(命名空间) 是 Kubernetes 中用于逻辑隔离集群资源的机制,可将同一集群划分为多个虚拟环境,适用于多团队、多项目或多环境(如开发、测试、生产)的场景。 核心作用: 资…...
如何在米尔-STM32MP257开发板上部署环境监测系统
本文将介绍基于米尔电子MYD-LD25X开发板(米尔基于STM35MP257开发板)的环境监测系统方案测试。 摘自优秀创作者-lugl4313820 一、前言 环境监测是当前很多场景需要的项目,刚好我正在论坛参与的一个项目:Thingy:91X 蜂窝物联网原型…...
解决jupyter notebook修改路径下没有c.NotebookApp.notebook_dir【建议收藏】
文章目录 一、检查并解决问题二、重新设置默认路径创作不易,感谢未来首富们的支持与关注! 最近在用jupyter notebook编写代码时,更新了一下Scikit-learn的版本,然后重新打开jupyter notebook的时候,我傻眼了࿰…...
lottie深入玩法
A、json文件和图片资源分开 delete 是json资源名字 /res/lottie/delete_anim_images是图片资源文件夹路径 JSON 中引用的图片名,必须与实际图片文件名一致 B、json文件和图片资源分开,并且图片加载不固定 比如我有7张图片,分别命名1~7&…...
o3和o4-mini的升级有哪些亮点?
ChatGPT是基于OpenAI GPT系列的高性能对话生成AI,经过多代迭代不断提升自然语言理解和生成能力。 在过去的一年中,OpenAI先后发布了GPT-4、GPT‑4.1及多种mini版本,为不同使用场景提供灵活选择。 随着用户需求向更高效、更精准的推理和视觉…...
Spring Boot 3 + SpringDoc:打造接口文档
1、背景公司 新项目使用SpringBoot3.0以上构建,其中需要对外输出接口文档。接口文档一方面给到前端调试,另一方面给到测试使用。 2、SpringDoc 是什么? SpringDoc 是一个基于 Spring Boot 项目的库,能够自动根据项目中的配置、…...
ApiHug 前端解决方案 - M1 内侧
背景 ApiHug UI 解决方案 - ApiHug前后端语义化设计,节约80%以上时间https://apihug.github.io/zhCN-docs/ui 现代前端框架日趋SPA(Single Page Application)化,给前后协同都带来了挑战,ApiHug试图减少多人在前后协同带来的理解难度&#x…...
vue2.6.12 安装babel 以使用 可选链 ?. 和空值合并 ??
package.json文件 {"name": "ruoyi","version": "3.6.4","description": "若依管理系统","author": "若依","license": "MIT","scripts": {"dev":…...
AI数字人如何深度赋能政务场景?魔珐科技政务应用全景解读
在数字中国建设的进程中,政务传播与公共服务正面临效率提升、质量优化与体验改善的多重需求。以魔珐科技所打造的AI数字人为代表,正在逐步融入政务体系,成为推动工作提效和服务创新的重要工具。从国家安全宣讲到政策解读,从反诈防…...
SpringAI+DeepSeek大模型应用开发——5 ChatPDF
ChatPDF 知识库 RAG检索增强 由于训练大模型非常耗时,再加上训练语料本身比较滞后,所以大模型存在知识限制问题: 知识数据比较落后,往往是几个月之前的;不包含太过专业领域或者企业私有的数据; 为了解决…...
音视频之H.265/HEVC变换编码
H.265/HEVC系列文章: 1、音视频之H.265/HEVC编码框架及编码视频格式 2、音视频之H.265码流分析及解析 3、音视频之H.265/HEVC预测编码 4、音视频之H.265/HEVC变换编码 目录 一、离散余弦变换: DCT原理及特点: 一维DCT解析例子࿱…...
网工_FTP协议
2025.04.18:网工老姜&小猿网学习笔记 第27节 FTP协议 7.1 FTP概述7.2 FTP工作原理7.2.1 FTP主动模式7.2.2 FTP被动模式 7.3 FTP客户端常用命令7.4 本章小结 7.1 FTP概述 文件传输协议file transfer protocol 常见用途是从FTP服务器批量下载文件,另一…...
Vue2+Vue3 130~180集学习笔记
Vue2Vue3 130~180集(Vue3)学习笔记 一、create-vue搭建vue3项目 create-vue是vue官方新的脚手架工具,底层切换到了vite 步骤: 查看环境条件 node -v版本需要在16.0及以上创建一个vue应用 npm init vuelatest 这一指令会安装并执…...
前端融合图片mask
之前实现了tif文件的融合,现在实现图片的融合,效果如下 第一张是融合右边两张图的结果 我的思路是: 初始使用canvas加载原图,此时未显示标注点击显示标注后,将原图和mask图传给workerworker接受数据后,转…...
什么是单元测试的“覆盖率”
1. 先搞清楚“覆盖率”是啥? 打个比方,你写完作业(代码),老师(测试)要检查是不是每道题都做对了。覆盖率就是说老师检查了多少题。比如: 行覆盖率:老师看了你作…...
SpringAI入门:对话机器人
SpringAI入门:对话机器人 1.引入依赖 创建一个新的SpringBoot工程,勾选Web、MySQL驱动、Ollama: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xm…...
[Java · 初窥门径] Java 语言初识
🌟 想系统化学习 Java 编程?看看这个:[编程基础] Java 学习手册 0x01:Java 编程语言简介 Java 是一种高级计算机编程语言,它是由 Sun Microsystems 公司(已被 Oracle 公司收购)于 1995 年 5 …...
大语言模型智能体:安全挑战与应对之道
在当今科技飞速发展的时代,大语言模型驱动的智能体正逐渐融入我们生活和工作的方方面面,给我们带来了诸多便利。但与此同时,它们的安全问题也引起了广泛的关注。今天,咱们就一起来深入了解一下可信大语言模型智能体所面临的安全挑…...
IHC肿瘤标志物 | 常见乳腺癌诊断——助力守护生命之花
乳腺癌作为一种常见的恶性肿瘤,严重威胁着女性健康。然而,随着医学技术的不断发展,我们有了更为精准和有效的检测方法,为及早发现和治疗乳腺癌提供了强有力的支持。 在这篇文章中,我们将深入了解乳腺癌的IHC检测技术&a…...
利用deepseek+Mermaid画流程图
你是一个产品经理,请绘制一个流程图,要求生成符合Mermaid语法的代码,要求如下: 用户下载文件、上传文件、删除文件的流程过程符合安全规范细节具体到每一步要做什么 graph LRclassDef startend fill:#F5EBFF,stroke:#BE8FED,str…...
Vue3 实战:打造多功能旅游攻略选项卡页面
在旅游类应用开发中,为用户提供全面、直观的信息展示界面至关重要。本文将分享如何基于 Vue3 Axios 技术栈,实现一个包含攻略、游记、问答三大板块的旅游攻略选项卡页面,从样式设计到交互逻辑,带你深入了解整个开发过程。 项目背…...
如何提高单元测试的覆盖率
一、定位未覆盖的代码 利用 IDEA 的覆盖率工具: 右键测试类 → Run with Coverage,或使用 AltShiftF10(Windows)打开运行菜单选择覆盖率。查看高亮标记: 绿色:已覆盖代码行。红色&#x…...
水位传感器详解(STM32)
目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 三、程序设计 main.c文件 water.h文件 water.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 Water Sensor水位传感器是一款简单易用、性价比较高的水位/水滴识别检测传感器,其是通过具有一系列…...
linux服务器命令行获取nvidia显卡SN的方法
机房需要变更机器的GPU显卡配置,入库、出库几块显卡,库管让我去获取显卡序列号。 去现场拆机器的事情毕竟很麻烦,而且也没干过拆装服务器,即使拆下来显卡也不一定找到SN。 于是乎搜索:命令行怎么获取linux服务器上的…...
大模型微服务架构模块实现方案,基于LLaMA Factory和Nebius Cloud实现模型精调的标准流程及代码
以下是基于LLaMA Factory和Nebius Cloud实现模型精调的标准流程及代码示例,结合最新技术动态和行业实践整理: 一、LLaMA Factory本地部署方案 1. 环境配置 # 创建Python环境并安装依赖 conda create -n llama_factory python3.10 conda activate llam…...
每天学一个 Linux 命令(20):find
可访问网站查看,视觉品味拉满: http://www.616vip.cn/20/index.html find 是 Linux 系统中最强大的文件搜索工具之一,支持按名称、类型、时间、大小、权限等多种条件查找文件,并支持对搜索结果执行操作(如删除、复制、执行命令等)。掌握 find 可大幅提升文件管理效率…...
Kubernetes Pod 调度策略:从基础到进阶
文章目录 环境Kubernetes 部署Kubernetes Pod 调度策略Kubernetes Pod 调度策略对照表调度流程经历阶段案例展示生成yaml文件默认调度节点选择器为节点添加标签编写 Deployment 配置文件应用资源并查看调度结果 Node Affinity(节点亲和性)为节点添加标签…...
4.18学习总结
完成一道算法题 学习了序列化 敲代码卡bug了...
用于数学定理和逻辑推理的符号系统
当前用于数学定理和逻辑推理的前沿符号系统主要基于依赖类型论(Dependent Type Theory),其中Lean 4和**Metamath Zero (MM0)**是最具代表性的新兴系统。以下从技术特性、使用方法和应用实例三个维度展开说明: 一、前沿符号系统解…...
HTTP:九.WEB机器人
概念 Web机器人是能够在无需人类干预的情况下自动进行一系列Web事务处理的软件程序。人们根据这些机器人探查web站点的方式,形象的给它们取了一个饱含特色的名字,比如“爬虫”、“蜘蛛”、“蠕虫”以及“机器人”等!爬虫概述 网络爬虫(英语:web crawler),也叫网络蜘蛛(…...
代码学习总结(五)
代码学习总结(五) 这个系列的博客是记录下自己学习代码的历程,有来自平台上的,有来自笔试题回忆的,主要基于 C++ 语言,包括题目内容,代码实现,思路,并会注明题目难度,保证代码运行结果 1 小红的好数 简单 非退化三角形 快速匹配 小红定义一个数对 { x , y } \{x…...
在 Vue 3 项目中引入 js-cookie 库
1. 安装 js-cookie 你可以通过 npm 或者 yarn 来安装 js-cookie: npm install js-cookie # 或者 yarn add js-cookie2. 在组件里引入并使用 js-cookie 以下给出两种使用方式: 全局引入 在 main.js 中全局引入 js-cookie,这样在所有组件里…...
HarmonyOs学习 环境配置后 实验1:创建项目Hello World
HarmonyOS开发入门:环境配置与Hello World实验 实验目标 掌握HarmonyOS开发环境配置,创建首个HarmonyOS应用并实现"Hello World"界面展示 实验准备 已安装DevEco Studio开发环境已配置HarmonyOS开发依赖项熟悉基本TypeScript/ArkTS语法&am…...
Spark on K8s 在 vivo 大数据平台的混部实战与优化
一、Spark on K8s 简介 (一)定义与架构 Spark on K8s 是一种将 Spark 运行在 Kubernetes(K8s)集群上的架构,由 K8s 直接创建 Driver 和 Executor 的 Pod 来运行 Spark 作业。其架构如下。 Driver Pod:相当于 Spark 集群中的 Driver,负责作业的调度和管理,它会根据作业…...
《软件设计师》复习笔记(13)——结构化开发方法
目录 1. 结构化开发方法 1.1 系统分析过程 1.2 系统设计基本原理 (1)内聚性(模块内部关联程度) (2)耦合性(模块间依赖程度) 真题示例: 1.3 系统总体结构设计&…...
Android创建测试配置和生产配置
Android测试与生产环境配置指南 在Android开发中,创建不同的构建配置来适应测试和生产环境是至关重要的。这样的配置能让我们在不同的开发阶段有效管理代码、资源和环境变量。本文将详细介绍如何在Android中创建和管理测试配置以及生产配置的整个过程。 环境准备 …...
DBeaver连接hive
DBeaver是一个非常好用的数据库管理工具,支持多种不同的数据库类型。 dbeaver 要连接hive时,数据库驱动是无法下载,但在hive 的安装配置包中,有一个目录:jdbc里面有一个专门提供外部程序连接hive的jar。将这个jar下载…...
数据结构初阶:二叉树(二)
本篇博客主要讲解二叉树---堆的相关知识。 1.实现顺序结构二叉树 一般堆使用顺序结构的数组来存储数据,堆是一种特殊的二叉树,具有二叉树的特性的同时,还具备其他的特性。 1.1 堆的概念和结构 堆具有以下性质: 堆中某个结点的值…...
React 列表渲染基础示例
React 中最常见的一个需求就是「把一组数据渲染成一组 DOM 元素」,比如一个列表。下面是我写的一个最小示例,目的是搞清楚它到底是怎么工作的。 示例代码 // 定义一个静态数组,模拟后续要渲染的数据源 // 每个对象代表一个前端框架…...
android PackageName ClassName
目录 系统应用: 设置 蓝牙 时钟 计算机 录音机 图库 视频 文件管理 FM 日历 谷歌浏览器 谷歌商店 热门商店 国外应用: amazon spotify deezer pandora audible applemusic omnia mxtech youtubemusic facebook familylink tidal tiktok kindle 系统应用: 设置 …...