【嵌入式】嵌入式面试题 36 问

1. volatile 是否可以修饰 const

是的,volatile 可以修饰 constconst 表示变量的值不能被修改,而 volatile 表示变量的值可能在程序之外被修改(例如,由硬件修改)。 将 volatile 用于 const 变量意味着该变量的值虽然不能被程序修改,但其值可能会被外部因素改变,编译器需要每次都从内存中读取该变量的值,而不是将其优化为缓存中的值。

2. 如何快速一行代码操作硬件寄存器

这取决于你的硬件架构和编程语言。 假设使用 C 语言,并且已经定义了寄存器的内存地址,可以使用指针进行操作:

*(volatile unsigned int *)0x12345678 = 0xABCD; // 将 0xABCD 写入地址为 0x12345678 的寄存器

volatile 关键字至关重要,它确保每次访问都直接访问内存,而不是使用缓存中的值。 0x12345678 需要替换为实际的寄存器地址。 unsigned int 应该根据寄存器的位宽进行调整。

3. 如何最快比较两组寄存器里有多少位不同

最快的办法是使用位运算:

int diffBits(unsigned int reg1, unsigned int reg2) {return __builtin_popcount(reg1 ^ reg2); // GCC 内置函数,计算二进制数中 1 的个数
}

^ 运算符进行异或操作,得到两个寄存器中不同的位。__builtin_popcount 是一个 GCC 内置函数,高效地计算结果中 1 的个数,也就是不同的位数。 其他编译器可能提供类似的内置函数(例如,在 Clang 中是 __builtin_popcount,在某些 ARM 编译器中可能是 __builtin_ctz 或类似的指令)。如果没有内置函数,需要自己实现位计数算法,但效率会降低。

4. 如何降低功耗

降低功耗的方法有很多,取决于具体的硬件和软件:

  • 使用低功耗器件: 选择功耗低的处理器、外设和内存。
  • 降低 CPU 频率和电压: 在允许的情况下降低 CPU 的工作频率和电压。
  • 使用低功耗模式: 利用处理器提供的低功耗模式,例如休眠、睡眠等。
  • 优化代码: 减少 CPU 的计算量和内存访问次数。
  • 关闭不必要的模块和外设: 在不需要的时候关闭不必要的模块和外设。
  • 使用更有效的算法: 选择更节能的算法。
  • 使用电源管理单元 (PMU): 利用 PMU 来管理电源和功耗。

5. 什么时候会用到 do...while(0)

do...while(0) 主要用于宏定义中,确保宏体无论如何都会被执行,并且可以避免在宏展开后产生语法错误。 例如:

#define MY_MACRO() do { \/* ... some code ... */ \
} while (0)

这样,即使在 MY_MACRO() 后面加了分号,也不会导致语法错误。

6. GPIO 有几种状态

GPIO 通常有两种主要状态:输入和输出。 此外,还有一些中间状态,例如:

  • 高阻抗: 输入引脚不连接任何东西,处于高阻抗状态。
  • 开漏输出: 输出引脚需要外部上拉电阻。
  • 推挽输出: 输出引脚可以驱动高低电平。
  • 模拟输入/输出: 一些 GPIO 可以配置为模拟输入或输出。

7. 如何用软件处理硬件管脚抖动

软件处理硬件管脚抖动的方法通常是使用软件去抖动:

  • 延时法: 读取 GPIO 状态后,等待一段时间再读取一次,如果两次读取的结果相同,则认为是有效状态。
  • 计数法: 连续读取 GPIO 状态多次,如果连续多次状态相同,则认为是有效状态。
  • 状态机法: 使用状态机来处理 GPIO 状态变化,避免抖动带来的误判。

8. 如何高效处理中断

  • 中断服务程序 (ISR) 尽量短小: ISR 应该尽可能短小,快速处理中断请求,避免阻塞其他任务。
  • 使用中断优先级: 根据中断的重要性设置不同的优先级,确保重要中断得到优先处理。
  • 中断共享: 多个中断可以共享同一个中断向量,提高中断效率。
  • 中断屏蔽: 在处理中断时,可以屏蔽其他中断,避免中断嵌套。
  • 使用中断队列: 将中断请求放入队列中,然后按顺序处理。

9. delaysleep 的区别

  • delay 通常指简单的延时函数,它会占用 CPU 时间,在延时期间 CPU 处于忙等待状态。
  • sleep 通常指休眠函数,它会让 CPU 进入低功耗状态,在休眠期间 CPU 不占用 CPU 时间。

10. 中断时可否睡眠

不可以。 在中断服务程序 (ISR) 中不能调用 sleep 或其他会使进程阻塞的函数,因为这会阻止中断的处理,导致系统不稳定。 ISR 应该快速执行并返回。

11. 如何设计 RAM 和 Flash 的验证工具

RAM 和 Flash 的验证工具通常需要执行以下步骤:

  • 读写测试: 写入数据到 RAM 或 Flash 中,然后读取数据,验证数据是否一致。
  • 循环读写测试: 反复进行读写测试,验证 RAM 或 Flash 的可靠性。
  • 压力测试: 进行大量数据的读写测试,验证 RAM 或 Flash 的性能。
  • 错误注入测试: 人为地注入错误,验证 RAM 或 Flash 的错误检测和纠正能力。
  • 边界测试: 测试 RAM 或 Flash 的边界条件,例如访问超出范围的地址。

12. 如何合理高效静态分配内存

静态内存分配在编译时完成,优点是速度快,缺点是缺乏灵活性。合理高效的静态内存分配需要:

  • 准确估计内存需求: 在编译前准确估计程序所需的内存大小。
  • 避免内存浪费: 只分配程序真正需要的内存。
  • 使用结构体或数组: 使用结构体或数组来组织数据,提高内存利用率。

13. 如何跟踪内存泄漏

  • 使用内存调试器: 使用内存调试器(例如 Valgrind)来检测内存泄漏。
  • 手动检查代码: 仔细检查代码,查找可能导致内存泄漏的地方。
  • 使用内存泄漏检测工具: 使用专门的内存泄漏检测工具,例如 LeakCanary (Android)。
  • 记录内存分配和释放: 记录每次内存分配和释放操作,方便查找内存泄漏。

14. 如何实现一个 ring buffer 以及用途

Ring buffer 是一种循环缓冲区,可以高效地存储和检索数据。 实现方法:

#include <stdio.h>#define BUFFER_SIZE 10typedef struct {int buffer[BUFFER_SIZE];int head;int tail;int count;
} RingBuffer;void initRingBuffer(RingBuffer *rb) {rb->head = 0;rb->tail = 0;rb->count = 0;
}int enqueue(RingBuffer *rb, int data) {if (rb->count == BUFFER_SIZE) return 0; // Buffer fullrb->buffer[rb->tail] = data;rb->tail = (rb->tail + 1) % BUFFER_SIZE;rb->count++;return 1;
}int dequeue(RingBuffer *rb, int *data) {if (rb->count == 0) return 0; // Buffer empty*data = rb->buffer[rb->head];rb->head = (rb->head + 1) % BUFFER_SIZE;rb->count--;return 1;
}int main() {RingBuffer rb;initRingBuffer(&rb);enqueue(&rb, 10);enqueue(&rb, 20);int data;dequeue(&rb, &data);printf("Dequeued: %d\n", data);return 0;
}

用途: 处理实时数据流、缓冲 I/O 操作、音频/视频处理等。

15. DMA 和 FIFO 的区别

  • DMA (Direct Memory Access): 直接内存访问,允许外设直接访问内存,而无需 CPU 的干预。 速度快,效率高,但需要硬件支持。
  • FIFO (First-In, First-Out): 先进先出缓冲区,是一种简单的内存缓冲区,数据按照先进先出的顺序进行存储和检索。 实现简单,但速度相对较慢,容量有限。

16. 如何做到统一 API 对接不同外设驱动

使用抽象层。 定义一个通用的 API 接口,然后为不同的外设驱动实现这个接口。 应用程序通过统一的 API 接口与外设进行交互,而无需关心底层驱动实现的细节。

17. 如何合理设计 Flash 分区表

Flash 分区表的设计需要考虑以下因素:

  • 分区大小: 根据不同的应用需求划分不同大小的分区。
  • 分区数量: 根据实际需求确定分区数量。
  • 分区类型: 例如,代码区、数据区、文件系统区等。
  • 分区对齐: 分区地址应该对齐到 Flash 的扇区大小,提高擦写效率。
  • 冗余和备份: 考虑添加冗余分区,用于备份重要的数据。

18. 正常非掉电重启是否要释放内存

不需要。 操作系统会在重启过程中自动释放内存。

19. 正常掉电关机流程是否要释放内存

不需要。 在正常掉电关机过程中,操作系统通常会执行一些清理操作,但不需要显式释放内存,因为电源关闭后内存中的数据会丢失。

20. 非掉电异常如何处理

非掉电异常处理需要:

  • 异常检测: 检测到异常后,需要立即停止程序的运行。
  • 保存现场: 保存程序运行的现场信息,例如寄存器值、堆栈指针等。
  • 错误处理: 根据异常类型进行相应的错误处理。
  • 重启或恢复: 根据情况决定是重启系统还是尝试恢复系统。
  • 记录日志: 记录异常信息,方便后续分析。

21. 如何实现异常后的 dump

异常后的 dump 通常需要:

  • 硬件支持: 需要硬件支持,例如 JTAG 接口。
  • 调试器: 使用调试器来读取内存中的数据。
  • 内存镜像: 将内存中的数据保存到文件中。
  • 分析工具: 使用分析工具来分析 dump 文件,确定异常的原因。

让我们逐一解答这些嵌入式系统开发中的常见问题:

22. 非正常掉电如何保护

非正常掉电会造成数据丢失和系统崩溃。保护措施主要集中在数据持久化和状态保存上:

  • 使用非易失性存储器 (NVM): 将关键数据存储在 EEPROM、Flash 等非易失性存储器中。在系统运行过程中,定期将数据写入 NVM。掉电时数据得以保存。
  • 数据校验: 在写入 NVM 之前,对数据进行校验,例如 CRC 校验,确保数据完整性。掉电重启后,可以校验数据的完整性。
  • 写保护机制: 对于重要的 NVM 数据区域,可以设置写保护,防止意外写入导致数据损坏。
  • 状态机和上下文保存: 使用状态机记录系统当前状态,并在掉电前将状态信息保存到 NVM。重启后,系统可以根据保存的状态恢复运行。 这需要仔细设计,确保状态信息足够完整,能够恢复系统到一致的状态。
  • 文件系统: 使用支持原子操作的文件系统(例如,一些嵌入式文件系统支持事务性操作),确保文件写入的完整性。

23. 如何设计一个简单的 profiling 工具

一个简单的 profiling 工具可以测量代码的执行时间。 方法包括:

  • 基于时间的采样: 周期性地中断程序执行,记录当前运行的函数。 这种方法简单易实现,但精度受采样频率影响。
  • 基于指令计数器的采样: 使用硬件指令计数器,统计每个函数执行的指令数。 这需要硬件支持。
  • 插入计时代码: 在需要测量的代码段前后插入计时代码,记录执行时间。 这种方法精度高,但需要修改代码,工作量较大。

一个简单的例子(基于插入计时代码):

#include <stdio.h>
#include <time.h>void function_to_profile() {clock_t start = clock();// 代码段clock_t end = clock();double cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;printf("Function execution time: %f seconds\n", cpu_time_used);
}int main() {function_to_profile();return 0;
}

24. 低功耗深睡眠如何唤醒后继续之前工作

唤醒后继续之前工作需要保存上下文信息:

  • 保存寄存器状态: 在进入深睡眠前,保存 CPU 寄存器、中断向量表等关键信息。
  • 保存内存状态: 如果需要,保存关键内存数据到 NVM。
  • 使用 RTC (实时时钟): RTC 可以提供时间信息,用于计算休眠时间或其他时间相关的任务。
  • 唤醒中断: 使用外部中断(例如,定时器中断、按键中断)唤醒系统。
  • 唤醒后恢复上下文: 唤醒后,恢复保存的寄存器状态和内存数据,继续执行之前的任务。

25. RTOS 不能断点和打印的时候如何调试

RTOS 调试的挑战在于其多线程和实时性。解决方法:

  • 使用 RTOS 提供的调试接口: 许多 RTOS 提供了调试接口,例如,任务状态查看、消息队列监控、信号量监控等。
  • 使用逻辑分析仪: 观察总线上的数据传输,分析程序的运行情况。
  • 使用 JTAG 调试器: JTAG 调试器可以单步执行代码,查看寄存器和内存内容。
  • 打印日志: 在关键位置打印日志信息,记录程序的运行状态。 注意避免过度打印影响系统性能。
  • 使用串口输出: 通过串口输出调试信息,实时监控程序运行。

26. 什么是交叉编译

交叉编译是指在一个平台上编译另一个平台的代码。例如,在 x86 架构的电脑上编译 ARM 架构的嵌入式设备代码。

27. 如何保证 Makefile 的增量编译

Makefile 的增量编译依赖于文件的依赖关系和时间戳。 make 命令会比较目标文件和依赖文件的时间戳,只有当依赖文件更新后,才会重新编译目标文件。 确保 Makefile 正确定义了依赖关系是关键。

28. 如何用一套代码支持不同硬件

  • 抽象硬件层: 将硬件相关的代码封装到抽象层中,提供统一的接口。 不同的硬件平台实现不同的抽象层,但上层代码无需修改。
  • 条件编译: 使用预处理器指令(例如 #ifdef, #ifndef, #endif)根据不同的硬件平台编译不同的代码。
  • 配置参数: 使用配置文件或命令行参数指定硬件平台,程序根据配置参数选择不同的硬件驱动程序。

29. 如何用一版软件支持不同硬件 (与 28 类似)

这个问题与问题 28 重复,解决方法相同。

30. 不同代码编译后的存放区域有何不同

这取决于编译器和链接器,但通常包括:

  • 代码段 (.text): 存放程序的指令代码。
  • 数据段 (.data): 存放已初始化的全局变量和静态变量。
  • BSS 段 (.bss): 存放未初始化的全局变量和静态变量。
  • 堆 (heap): 动态内存分配区域。
  • 栈 (stack): 函数调用和局部变量的存储区域。

31. release 和 debug 编译的区别

  • 优化级别: Release 版本通常进行优化,以提高程序的执行效率和减小代码大小。Debug 版本通常不进行优化,以方便调试。
  • 调试信息: Debug 版本包含调试信息,方便调试器进行调试。Release 版本通常不包含调试信息。
  • 运行速度和大小: Release 版本运行速度更快,代码大小更小。Debug 版本运行速度较慢,代码大小较大。

32. ARM 多核之间有多少通讯机制及优缺点

ARM 多核之间的通讯机制包括:

  • 共享内存: 多个核访问同一块内存区域。优点:简单高效;缺点:需要加锁机制避免数据竞争,容易出现死锁。
  • 中断: 一个核通过中断请求另一个核。优点:响应快;缺点:需要仔细设计中断处理程序,容易出现中断风暴。
  • Mailbox: 类似于消息队列,用于核间通信。优点:避免数据竞争;缺点:效率相对较低。
  • 锁机制: 互斥锁、自旋锁等,用于保护共享资源。
  • 缓存一致性协议: 保证多个核对共享内存的访问一致性。

33. 两个线程之间不同锁的区别是什么

常见的锁包括:

  • 互斥锁 (Mutex): 一次只能被一个线程持有。 防止多个线程同时访问共享资源。
  • 自旋锁 (Spinlock): 线程获取锁失败时,会一直循环尝试获取锁,直到获取成功。 适用于锁持有时间短的情况,避免线程上下文切换开销。
  • 读写锁 (RWLock): 允许多个线程同时读取共享资源,但只有一个线程可以写入共享资源。

34. 如何理解收益边界

收益边界是指优化代码所能带来的性能提升的极限。 超过收益边界,继续优化代码并不会带来显著的性能提升,反而可能增加代码复杂度和维护成本。 需要权衡优化带来的收益和成本。

35. 介绍一下自己关于代码优化的经验

代码优化需要根据具体情况选择合适的策略,我的经验包括:

  • 选择合适的算法和数据结构: 这是优化性能的关键。
  • 减少不必要的计算和内存访问: 避免重复计算,使用缓存等技术提高效率。
  • 使用编译器优化: 利用编译器的优化选项,例如,内联函数、循环展开等。
  • 代码审查和性能测试: 通过代码审查发现潜在的性能问题,并使用性能测试工具评估优化的效果。
  • 关注热点代码: 将优化重点放在程序中执行次数最多的代码段。
  • 使用合适的工具: 例如,性能分析工具,帮助定位性能瓶颈。

36. 关于代码移植有什么经验分享

代码移植的关键在于抽象和隔离:

  • 硬件抽象层 (HAL): 将硬件相关的代码封装到 HAL 中,方便移植到不同的硬件平台。
  • 操作系统抽象层 (OSAL): 将操作系统相关的代码封装到 OSAL 中,方便移植到不同的操作系统。
  • 模块化设计: 将代码分解成独立的模块,方便移植和维护。
  • 良好的代码风格和注释: 方便理解和修改代码。
  • 测试: 在移植后进行充分的测试,确保代码的正确性。

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

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

相关文章

java基础概念49-数据结构2

一、树 1-1、树的基本概念 1、树的节点 2、二叉树 3、树的高度 1-2、二叉查找树 普通二叉树没有规律&#xff0c;不方便查找&#xff0c;没什么作用。 1、基本概念 2、添加节点 此时&#xff0c;该方式添加形成的二叉查找树&#xff0c;根节点就是第一个节点。 3、查找节点 4…

GhatGPT缺陷不足和商业应用

1. 引言 ChatGPT的兴起&#xff1a; 2022年末推出&#xff0c;迅速在自然语言处理和人工智能领域引起广泛关注。数亿用户体验其强大智能&#xff0c;感叹机器智能的飞速发展。 存在的缺陷&#xff1a; 事实性错误&#xff1a;生成的文本中包含错误信息。无法实时更新&#xff1…

【Linux】Macvlan介绍及LInux下例子实现

Macvlan Macvlan 是一种网络虚拟化技术&#xff0c;允许在同一物理网络接口上创建多个虚拟网络接口&#xff0c;每个虚拟接口都有自己独立的 MAC 地址。这对于需要在同一物理主机上运行多个网络隔离的应用程序或容器时非常有用。 Macvlan 的特点和用途 独立的 MAC 地址 每个 …

Jackson @JsonInclude 注解

1. 概述 Jackson 是一个著名的Java库&#xff0c;以转换Java对象为JSON格式以及从JSON反序列化回Java对象而闻名。有时候&#xff0c;我们可能希望仅在某些字段满足特定条件时才将其包含在JSON输出中&#xff0c;而Jackson的JsonInclude注解正是为此目的量身定制的。 JsonInc…

12.12 枚举 共用体 数据结构 创建顺序表

1.思维导图 2. 创建顺序表 1>头文件 test.h #ifndef __TEST_H__ #define __TEST_H__#include<stdlib.h> #include<stdio.h> #include<string.h>#define MAX 30 //typedef int datatype;typedef struct sequence {int data[MAX];int len;}seqlist,*se…

next.js 存在缓存中毒漏洞(CVE-2024-46982)

免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…

如何对小型固定翼无人机进行最优的路径跟随控制?

控制架构 文章继续采用的是 ULTRA-Extra无人机&#xff0c;相关参数如下&#xff1a; 这里用于guidance law的无人机运动学模型为&#xff1a; { x ˙ p V a cos ⁡ γ cos ⁡ χ V w cos ⁡ γ w cos ⁡ χ w y ˙ p V a cos ⁡ γ sin ⁡ χ V w cos ⁡ γ w sin ⁡ χ…

【Flink-scala】DataStream编程模型之延迟数据处理

DataStream API编程模型 1.【Flink-Scala】DataStream编程模型之数据源、数据转换、数据输出 2.【Flink-scala】DataStream编程模型之 窗口的划分-时间概念-窗口计算程序 3.【Flink-scala】DataStream编程模型之水位线 4.【Flink-scala】DataStream编程模型之窗口计算-触发器-…

react useRef、useContext、useReducer使用中遇到的问题及解决办法

在 React 中&#xff0c;useRef、useContext 和 useReducer 是三个非常有用的 Hook&#xff0c;它们可以帮助我们更好地管理组件的状态和行为。然而&#xff0c;在使用这些 Hook 时&#xff0c;可能会遇到一些问题和困惑。本文将详细解释这三个 Hook 的工作原理&#xff0c;并提…

2024告别培训班 数通、安全、云计算、云服务、存储、软考等1000G资源分享

大类有&#xff1a;软考初级 软考中级 软考高级 华为认证 华三认证&#xff1a; 软考初级&#xff1a; 信息处理技术员 程序员 网络管理员 软考中级&#xff1a; 信息安全工程师 信息系统监理师 信息系统管理工程师 嵌入式系统设计时 数据库系统工程师 电子商务设…

《操作系统 - 清华大学》8 -1:进程的组成

文章目录 1. 进程的组成2. 进程与程序的联系3. 进程与程序的区别4. 进程与程序关系 1. 进程的组成 进程具体包含哪些东西&#xff1a; 首先要执行相应的代码&#xff0c;所以执行代码需要放到内存中代码执行需要处理数据&#xff0c;数据需要放到内存中需要知道现在要执行哪条…

【Java】String类API

创建字符串 字符串字面量"Hello"高效&#xff0c;常量池复用常见、简单的字符串创建 new 关键字new String("Hello")每次创建新对象&#xff0c;性能开销较高显式创建新对象 字符数组new String(char[])转换字符数组字符数组转字符串 StringBuilder/St…

数据结构初阶---二叉树---堆

一、树 1.树的概念 树是一种非线性的数据结构&#xff0c;由n(n≥0)个有限结点组成的一个有层次关系的集合。形状类似一棵倒挂的树&#xff0c;根朝上&#xff0c;分支向下。 根结点没有前驱结点&#xff0c;可以有n(n≥0)个后继结点。 其余结点被分为M个互不相交的集合&am…

CocosCreator对配置文件加密

一、加密 1.首先假设你已经将Excel表格数据导出为了json数据 2.然后可以通关nodejs对其进行xor加密 const fs require(fs);// 读取配置文件 const path "hero_info.json"; const data fs.readFileSync(path, utf-8); const jsonObject JSON.parse(data);// XO…

学习 Dockerfile 常用指令

学习 Dockerfile 常用指令 在构建 Docker 镜像时&#xff0c;Dockerfile 文件是一份至关重要的配置文件&#xff0c;它定义了构建镜像的所有步骤。通过在 Dockerfile 中使用不同的指令&#xff08;命令&#xff09;&#xff0c;我们可以控制镜像的构建过程、设置环境、指定执行…

D95【python 接口自动化学习】- pytest进阶之fixture用法

day95 pytest的fixture详解&#xff08;二&#xff09; 学习日期&#xff1a;20241210 学习目标&#xff1a;pytest基础用法 -- pytest的fixture详解&#xff08;二&#xff09; 学习笔记&#xff1a; fixture(autouseTrue) func的autouse是TRUE时&#xff0c;所有函数方法…

C语言 字符串输入输出函数、scanf(“%[^\n]“,)可输入空格 、fgets删除换行符

字符串输入函数&#xff1a; scanf&#xff08;"%s"&#xff0c;数组名&#xff09; gets&#xff08;数组名&#xff09; fgets&#xff08;&#xff09; --- 文件流输入函数 函数原型&#xff1a; int scanf( const char *format, ...…

深度学习camp-第J4周:ResNet与DenseNet结合探索

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 本周任务&#xff1a; 探索ResNet和DenseNet的结合可能性本周任务较难&#xff0c;我们在chatGPT的帮助下完成 一、网络的构建 设计一种结合 ResNet 和 Den…

「iOS」通过CoreLocation Framework深入了解MVC架构

「iOS」通过CoreLocation Framework重新了解多界面传值以及MVC架构 文章目录 「iOS」通过CoreLocation Framework重新了解多界面传值以及MVC架构前言CoreLocation了解根据需求建模设计属性方法设计协议传值Block传值KVONotification通知方式 总结参考文章 前言 在这个学期的前…

Debezium系列之:使用Debezium采集oceanbase数据库

Debezium系列之:使用Debezium采集oceanbase数据库 一、oceanbase数据库二、安装OceanBase三、安装oblogproxy四、基于Docker的简单采集案例五、生产实际应用案例Debezium 是一个开源的分布式平台,用于监控数据库变化和捕捉数据变动事件,并以事件流的形式导出到各种消费者。D…