嵌入式八股文面试题(二)C语言算法
相关概念请查看文章:C语言概念。
1. 如何实现一个简单的内存池?
简单实现:
#include <stdio.h> #include <stdlib.h>//内存块 typedef struct MemoryBlock {void *data; // 内存块起始地址struct MemoryBlock *next; // 下一个内存块的地址 } MemoryBlock;//内存池 typedef struct MemoryPool {MemoryBlock *freeList; // 空闲内存块链表MemoryBlock *usedList; // 占用内存块链表int freeCount; // 空闲内存块数量int usedCount; // 占用内存块数量int blockCount; // 内存块总数量 } MemoryPool; //初始化内存池 MemoryPool *InitMemoryPool(int blockSize, int blockCount) {MemoryPool *pool = (MemoryPool *)malloc(sizeof(MemoryPool)); // 为内存池分配空间if (pool == NULL) {printf("Failed to allocate memory pool!\n");return NULL;}pool->freeList = NULL;pool->usedList = NULL;pool->freeCount = 0;pool->usedCount = 0;pool->blockCount = blockCount;for (int i = 0; i < blockCount; i++) {// 创建内存块节点,插入到空闲链表MemoryBlock *block = (MemoryBlock *)malloc(sizeof(MemoryBlock));block->data = malloc(blockSize);block->next = pool->freeList;pool->freeList = block;pool->freeCount++;}return pool; } //分配内存块 void *AllocateBlock(MemoryPool *pool) {if (pool->freeList == NULL || pool->freeCount == 0) {printf("No free blocks available!\n");return NULL;}MemoryBlock *node = pool->freeList;// 将该内存块从空闲链表删除pool->freeList = node->next;// 将该内存块插入到占用链表node->next = pool->usedList;pool->usedList = node;// 更新空闲和占用状态pool->usedCount++;pool->freeCount--;return node->data; } //释放内存块 void FreeBlock(MemoryPool *pool, void *data) {MemoryBlock *cur = pool->usedList;MemoryBlock *pre = NULL;// 寻找该内存块的节点while (cur != NULL && cur->data != data) {pre = cur;cur = cur->next;}if (cur == NULL) {printf("Error: Data not found!\n");return;}// 将该内存块从占用链表删除if (pre != NULL)pre->next = cur->next;elsepool->usedList = cur->next;// 将该内存块插入到空闲链表cur->next = pool->freeList;pool->freeList = cur;pool->freeCount++;pool->usedCount--; } //销毁内存块 void DestroyMemoryPool(MemoryPool *pool) {if (pool == NULL) return;MemoryBlock *cur = NULL;// 释放所有空闲内存块空间while (pool->freeList != NULL) {cur = pool->freeList;pool->freeList = pool->freeList->next;free(cur->data);free(cur);}// 释放所有占用内存块空间while (pool->usedList != NULL) {cur = pool->usedList;pool->usedList = pool->usedList->next;free(cur->data);free(cur);}// 释放内存池空间free(pool); } int main(void) {MemoryPool *pool;pool = InitMemoryPool(10, 5); // 初始化内存池int *str = (int *)AllocateBlock(pool); //申请内存块1*str = 2;int *ptr = (int *)AllocateBlock(pool); //申请内存块2*ptr = 3;printf("free block : %d, used block : %d\n", pool->freeCount, pool->usedCount);FreeBlock(pool, ptr); //释放内存块2printf("free block : %d, used block : %d\n", pool->freeCount, pool->usedCount);DestroyMemoryPool(pool); return 0; }打印结果:
2. 实现一个双向链表。
双向链表是一种每个节点都有两个指针,一个指向下一个节点,一个指向前一个节点的数据结构。可以在任意位置进行快速插入和删除。
#include <stdio.h> #include <stdlib.h>// 双向链表节点 typedef struct Node {int data;struct Node *prev; //连接前一个节点的指针struct Node *next; //连接下一个节点的指针 } Node;// 创建新节点 Node* createNode(int data) {Node *newNode = (Node *)malloc(sizeof(Node));newNode->data = data;newNode->next = NULL;newNode->prev = NULL;return newNode; }// 插入节点到链表的尾部 void append(Node **head, int data) {Node *newNode = createNode(data);if (*head == NULL) {*head = newNode;} else {Node *temp = *head;while (temp->next != NULL) {temp = temp->next;}temp->next = newNode;newNode->prev = temp;} } //删除一个节点 void delete_node(Node **head, int data) {if (*head == NULL){ // 如果链表为空printf("链表为空,没有要删除的元素\n");return;}Node *temp = *head;// 如果删除的是头节点if (temp->data == data) {*head = temp->next; // 更新头节点if (*head != NULL) { // 如果不是空链表(*head)->prev = NULL;}free(temp);return;}// 找到要删除的节点while (temp != NULL && temp->data != data) {temp = temp->next;}// 如果没有找到该节点if (temp == NULL) {printf("未找到数据为 %d 的节点\n", data);return;}// 删除的是中间或尾部节点if (temp->next != NULL) {temp->next->prev = temp->prev; // 更新下一个节点的prev指针}if (temp->prev != NULL) {temp->prev->next = temp->next; // 更新前一个节点的next指针}free(temp); } // 打印双向链表 void printList(Node *head) {Node *temp = head;while (temp != NULL) {printf("%d <-> ", temp->data);temp = temp->next;}printf("NULL\n"); }int main() {Node *head = NULL;append(&head, 10);append(&head, 20);append(&head, 30);printList(head);delete_node(&head, 30);printList(head);return 0; }打印结果:
3. 实现一个线程池。
相关文章:
嵌入式八股文面试题(二)C语言算法
相关概念请查看文章:C语言概念。 1. 如何实现一个简单的内存池? 简单实现: #include <stdio.h> #include <stdlib.h>//内存块 typedef struct MemoryBlock {void *data; // 内存块起始地址struct MemoryBlock *next; // 下一个内…...
#渗透测试#批量漏洞挖掘#LiveBos UploadFile 任意文件上传漏洞
免责声明 本教程仅为合法的教学目的而准备,严禁用于任何形式的违法犯罪活动及其他商业行为,在使用本教程前,您应确保该行为符合当地的法律法规,继续阅读即表示您需自行承担所有操作的后果,如有异议,请立即停止本文章读。 目录 漏洞背景 漏洞成因 影响评估 检测方案 …...
ds-download-link 插件:以独特图标选择,打造文章下载链接
源码介绍 “ds-download-link”插件为 WordPress 网站提供了在文章编辑器中添加下载链接的功能,每个下载链接都支持图标选择,并能将这些链接以美观的样式展示在文章前端页面。以下是该插件的主要特性和功能: 后台功能 在文章编辑器下方添加…...
介绍下SpringBoot在分布式架构中,如何实现读写分离
在分布式架构中,Spring Boot 可以通过多种方式实现读写分离,以提升系统性能和扩展性。以下是常见的实现方法: 1. 使用多数据源 通过配置多个数据源,将读操作和写操作分别路由到不同的数据库实例。 实现步骤: 配置多…...
判断函数是否为react组件或lazy包裹的组件
function Modal(){return <p>123</p> } 实参里填入函数名,是false 实参里填入标签形式的函数,是true isValidElement(Modal)//false isValidElement(<Modal></Modal>)//true 官方说明 isValidElement – React 中文文档 但是官方并不建议用isValidE…...
【大数据安全分析】大数据安全分析技术框架与关键技术
在数字化时代,网络安全面临着前所未有的挑战。传统的网络安全防护模式呈现出烟囱式的特点,各个安全防护措施和数据相互孤立,形成了防护孤岛和数据孤岛,难以有效应对日益复杂多变的安全威胁。而大数据分析技术的出现,为解决这些问题带来了新的曙光。 大数据分析在网络安全…...
PHP 中的除以零错误
除以零错误(Division by zero)是指数字除以零的情况, 这在数学上是未定义的。在 PHP 中,处理这种错误的方式取决于 PHP 版本: PHP 7: 使用 / 运算符会产生一个警告 (E_WARNING) 并返回 false。 使用 intd…...
【QT】控件 -- 多元素类 | 容器类 | 布局类
🔥 目录 一、多元素类1. List Widget -- 列表2. Table Widget -- 表格3. Tree Widget -- 树形 二、容器类1. Group Box -- 分组框2. Tab Widget -- 标签页 三、布局类1. 垂直布局【使用 QVBoxLayout 管理多个控件】【创建两个 QVBoxLayout】 2. 水平布局【使用 QHBo…...
数据结构——【二叉树模版】
#思路 1、二叉树不同于数的构建,在树节点类中,有数据,左子结点,右子节点三个属性,在树类的构造函数中,添加了变量maxNodes,用于后续列表索引的判断 2.GetTreeNode()函数是常用方法,…...
centos7 curl#6 - Could not resolve host mirrorlist.centos.org; 未知的错误 解决方案
问题描述 centos7系统安装完成后,yum安装软件时报错“curl#6 - “Could not resolve host: mirrorlist.centos.org; 未知的错误”” [root192 ~]# yum install vim -y 已加载插件:fastestmirror Determining fastest mirrors Could not retrieve mirro…...
【前端发展路径】技术成长路径、职业方向分支、行业趋势与建议、学习资源推荐
前端开发是一个快速发展的领域,技术栈和职业路径也在不断演进。以下是前端开发的典型发展路径,分为技术成长和职业方向两个维度,供参考: 一、技术成长路径 1. 初级阶段(入门) 核心技能: HTML/CSS:语义化标签、布局(Flex/Grid)、响应式设计、CSS 预处理器(Sass/Less…...
NO.15十六届蓝桥杯备战|while循环|六道练习(C++)
while循环 while语法形式 while 语句的语法结构和 if 语句⾮常相似,但不同的是 while 是⽤来实现循环的, if 是⽆法实现循环的。 下⾯是 while 循环的语法形式: //形式1 while ( 表达式 )语句; //形式2 //如果循环体想包含更多的语句&a…...
kotlin标准库里面也有很多java类
Kotlin 标准库中确实存在许多与 Java 类直接关联或基于 Java 类封装的结构,但这并不是“问题”,而是 Kotlin 与 JVM 生态深度兼容和互操作性的体现。以下从技术原理和设计哲学的角度详细解释: 一、Kotlin 与 JVM 的底层关系 Kotlin 代码最终…...
Flutter 双屏双引擎通信插件加入 GitCode:解锁双屏开发新潜能
在双屏设备应用场景日益丰富的当下,移动应用开发领域迎来了新的机遇与挑战。如何高效利用双屏设备优势,为用户打造更优质的交互体验,成为开发者们关注的焦点。近日,一款名为 Flutter 双屏双引擎通信插件的创新项目正式入驻 GitCod…...
01、单片机上电后没有正常运行怎么办
单片机上电后没有运转, 首先要检查什么? 1、单片机供电是否正常? &电路焊接检查 如果连最基本的供电都没有,其它都是空谈啊!检查电路断路了没有?短路了没有?电源合适吗?有没有虚焊? 拿起万用表之前,预想一下测量哪里?供电电压应该是多少?对PCB上电压测量点要…...
使用 EMQX 接入 LwM2M 协议设备
LwM2M 协议介绍 LwM2M 是一种轻量级的物联网设备管理协议,由 OMA(Open Mobile Alliance)组织制定。它基于 CoAP (Constrained Application Protocol)协议,专门针对资源受限的物联网设备设计,例…...
【Elasticsearch】bool查询
Elasticsearch 的bool查询是构建复杂查询条件的核心工具之一。它允许通过布尔逻辑组合多个查询子句,以实现精确的搜索需求。bool查询支持四种主要的子句类型:must、should、filter和must_not。每种子句类型都有其特定的作用和行为。 1.bool查询的基本结构…...
Redis 常见面试题汇总(持续更新)
文章目录 01、Redis 支持哪些数据类型?02、谈谈对 Redis 的 AOF 机制的 rewrite 模式的理解?03、请列举几个 Redis 常见性能问题和解决方案04、Redis 使用的最大内存是多少?内存数据淘汰策略有哪些?05、请谈谈 Redis 的同步机制。…...
蓝桥杯备赛 Day13.1走出迷宫
链接:走出迷宫 题目描述 小明现在在玩一个游戏,游戏来到了教学关卡,迷宫是一个N*M的矩阵。 小明的起点在地图中用“S”来表示,终点用“E”来表示,障碍物用“#”来表示,空地用“.”来表示。 障碍物不能通…...
全面解析鸿蒙(HarmonyOS)开发:从入门到实战,构建万物互联新时代
文章目录 引言 一、鸿蒙操作系统概述二、鸿蒙开发环境搭建三、鸿蒙核心开发技术1. **ArkUI框架**2. **分布式能力开发**3. **原子化服务与元服务** 四、实战案例:构建分布式音乐播放器五、鸿蒙开发工具与调试技巧六、鸿蒙生态与未来展望结语 引言 随着万物互联时代…...
使用 mkcert 本地部署启动了 TLS/SSL 加密通讯的 MongoDB 副本集和分片集群
MongoDB 是支持客户端与 MongoDB 服务器之间启用 TLS/SSL 进行加密通讯的, 对于 MongoDB 副本集和分片集群内部的通讯, 也可以开启 TLS/SSL 认证. 本文会使用 mkcert 创建 TLS/SSL 证书, 基于创建的证书, 介绍 MongoDB 副本集、分片集群中启动 TLS/SSL 通讯的方法. 我们将会在…...
P3372 【模板】线段树 1【题解2】
本题题解分两篇 此篇为第贰篇,用树状数组做 第壹篇:P3372 【模板】线段树 1【题解1】 本文讲解树状数组解决区间修改区间查询 其它树状数组相关文章: 树状数组讲解单点修改/查询树状数组解决区间修改单点查询 P3372 【模板】线段树 1 题…...
使用 EDOT 监测由 OpenAI 提供支持的 Python、Node.js 和 Java 应用程序
作者:来自 Elastic Adrian Cole Elastic 很自豪地在我们的 Python、Node.js 和 Java EDOT SDK 中引入了 OpenAI 支持。它们为使用 OpenAI 兼容服务的应用程序添加日志、指标和跟踪,而无需任何代码更改。 介绍 去年,我们宣布了 OpenTelemetry…...
kotlin中expect和actual关键字修饰的函数作用
在 Kotlin 多平台编程中,expect 和 actual 关键字用于定义跨平台的抽象和具体实现。这种机制允许开发者声明一个平台无关的接口或函数签名(使用 expect),然后在每个目标平台上提供具体的实现(使用 actual)。…...
CNN-BiGRU卷积神经网络双向门控循环单元多变量多步预测,光伏功率预测
CNN-BiGRU卷积神经网络双向门控循环单元多变量多步预测,光伏功率预测 代码下载:CNN-BiGRU卷积神经网络双向门控循环单元多变量多步预测,光伏功率预测 一、引言 1.1、研究背景及意义 随着全球能源危机和环境问题的日益严重,可再…...
mysql8.0使用MGR实现高可用与利用MySQL Router构建读写分离MGR集群
MGR是MySQL Group Replication的缩写,即MySQL组复制。 在以往,我们一般是利用MySQL的主从复制或半同步复制来提供高可用解决方案,但这存在以下几个比较严重的问题: 主从复制间容易发生复制延迟,尤其是在5.6以前的版本…...
保研考研机试攻略:python笔记(4)
🐨🐨🐨15各类查找 🐼🐼二分法 在我们写程序之前,我们要定义好边界,主要是考虑区间边界的闭开问题。 🐶1、左闭右闭 # 左闭右闭 def search(li, target): h = len(li) - 1l = 0#因为都是闭区间,h和l都可以取到并且相等while h >= l:mid = l + (h - l) // 2…...
如何保证缓存和数据库一致性
保证缓存和数据库一致性是分布式系统中的一个常见挑战。以下是几种常用的策略和方法,用于解决缓存与数据库之间的数据一致性问题: 1. 基础同步策略 基础同步策略包括以下几种常见的操作顺序: 先更新缓存再更新数据库:这种方法可能导致缓存中的数据成为脏数据,因为如果数…...
关于conda换镜像源,pip换源
目录 1. 查看当前下载源2. 添加镜像源2.1清华大学开源软件镜像站2.2上海交通大学开源镜像站2.3中国科学技术大学 3.删除镜像源4.删除所有镜像源,恢复默认5.什么是conda-forge6.pip换源 1. 查看当前下载源 conda config --show channels 如果发现多个 可以只保留1个…...
分布式服务框架 如何设计一个更合理的协议
1、概述 前面我们聊了如何设计一款分布式服务框架的问题,并且编码实现了一个简单的分布式服务框架 cheese, 目前 cheese 基本具备分布式服务框架的基本功能。后面我们又引入了缓存机制,以及使用Socket替代了最开始的 RestTemplate。并且还学习了网络相关…...
