嵌入式面试笔试刷题(day7)

文章目录

  • 前言
  • 一、switch能不能用浮点数
  • 二、指针函数和函数指针
  • 三、如何防止重复引用头文件
  • 四、如何写一个函数可以在main之前执行
  • 五、栈和队列区别及应用场景
  • 六、linux上查看磁盘内存占用率的命令
  • 七、什么是磁盘碎片
  • 八、内存泄露是怎么产生的
  • 九、发生了coredump怎么解决
  • 总结


前言

本篇文章继续刷题!

一、switch能不能用浮点数

switch语句是不支持直接使用浮点型(即浮点数)作为判断条件的。switch语句通常用于基于离散的整数值或枚举类型进行条件判断。

二、指针函数和函数指针

指针函数(Pointer to a Function)和函数指针(Function Pointer)是两个不同的概念,尽管它们都涉及到指针和函数。

函数指针是一个指针变量,它存储了函数的地址。通过函数指针,可以像调用普通函数一样调用被指向的函数。函数指针的声明类似于函数原型,只是在函数名前加上了一个指针操作符(*)。例如,以下是一个函数指针的声明:

int (*funcPtr)(int, int);

指针函数是一种函数类型,它返回一个指针。与普通函数不同的是,指针函数的返回类型是一个指针类型,用于指向特定类型的数据。例如,以下是一个指针函数的声明:

int* myFunction(int);

三、如何防止重复引用头文件

1.使用条件编译指令:

在头文件的开头和结尾添加条件编译指令,可以防止头文件被重复引用。

#ifndef HEADER_FILE_NAME_H
#define HEADER_FILE_NAME_H// 头文件内容#endif  // HEADER_FILE_NAME_H

这种方式会在编译时检查是否已定义了HEADER_FILE_NAME_H宏,如果未定义则执行#define指令将其定义,然后执行头文件内容;如果已定义,则跳过头文件内容。这样可以确保同一个头文件只会被引用一次。

2.使用#pragma once指令:
#pragma once指令是一种非标准的方法,但被大多数编译器所支持。它可以在头文件的开头使用,用于确保头文件只会被引用一次。

#pragma once// 头文件内容

这种方式与条件编译指令类似,但更简洁,不需要显式定义和判断宏。

四、如何写一个函数可以在main之前执行

要在main函数执行之前调用某个函数,可以利用C/C++的特性——构造函数,以及全局对象的初始化过程来实现。

在C++中,全局变量和静态变量的初始化在main函数之前进行,而利用全局变量或静态变量的构造函数,可以在初始化阶段执行自定义的代码。

#include <iostream>void preMainFunction() {std::cout << "This function is called before main!" << std::endl;
}struct PreMainCaller {PreMainCaller() {preMainFunction();}
};PreMainCaller preMainCaller;  // 全局对象,构造函数会在main之前自动调用int main() {std::cout << "This is the main function." << std::endl;return 0;
}

五、栈和队列区别及应用场景

1.区别:

存储方式:栈是一种后进先出(LIFO,Last-In-First-Out)的数据结构,新的元素插入到栈的顶部,称为栈顶,而元素的删除也是从栈顶开始。队列是一种先进先出(FIFO,First-In-First-Out)的数据结构,新的元素插入到队列的末尾,称为队尾,而元素的删除是从队列的开头进行。

操作方式:栈支持两种基本操作,即压入(Push)和弹出(Pop)。压入将新元素放入栈顶,弹出将栈顶的元素移除。栈的访问是单一方向的,只能操作或访问栈顶元素。队列支持三种基本操作,即入队(Enqueue)、出队(Dequeue)和查看队头元素。入队将新元素放入队列的末尾,出队将队列开头的元素移除,而查看队头元素是获取队列开头元素的值而不移除。

2.应用场景:

栈的应用场景:

括号匹配:用栈可以检查表达式中的括号是否匹配,或者在编译器中判断代码的语法是否合法。

函数调用:函数的调用过程中使用栈来存储局部变量、参数等信息。

后缀表达式计算:使用栈可以实现后缀表达式(逆波兰表达式)的计算。

撤销操作:在软件应用中,可以使用栈来实现撤销(Undo)操作的功能。

队列的应用场景:

广度优先搜索:在图的遍历中,使用队列来实现广度优先搜索算法。

缓存管理:可以使用队列来实现缓存,按照先进先出的原则管理缓存数据。

多线程任务调度:使用队列可以实现任务队列,多个线程从队列中获取任务执行。

打印队列:打印机通常使用队列来管理打印任务,保证按顺序进行打印。

六、linux上查看磁盘内存占用率的命令

查看磁盘占用率:

1.使用 df 命令可以查看文件系统的磁盘占用情况。运行 df -h 可以以人类可读的格式显示磁盘空间使用情况,包括磁盘大小、已用空间、可用空间和挂载点。

在这里插入图片描述

2.使用 du 命令可以查看指定目录的磁盘使用情况。运行 du -sh <目录路径> 可以显示指定目录的总磁盘使用情况。

在这里插入图片描述

七、什么是磁盘碎片

磁盘碎片(Disk Fragmentation)是指磁盘上文件存储位置的不连续和不规则分布。
当文件被存储或删除时,操作系统将文件分成一系列的数据块(或称为簇、扇区),这些数据块会被分散地分配到磁盘的不同位置。随着文件的频繁操作,特别是文件的修改、增加和删除,磁盘上的文件数据会变得分散,导致出现磁盘碎片。

八、内存泄露是怎么产生的

内存泄露的产生通常是由以下原因导致:

1.动态内存分配未释放:在程序中使用动态内存分配的函数(如malloc()、new等)申请内存空间,但在后续的程序执行中忘记或错误地释放这些内存。这会导致这些内存空间无法被再次使用,从而造成内存泄露。

#include <iostream>void memoryLeak() {int* ptr = new int(5);  // 动态分配一个int类型的内存,赋值为5// 没有释放这块内存,造成内存泄漏
}int main() {memoryLeak();// 这里没有释放内存的机会,造成内存泄漏return 0;
}

2.引用计数错误:在使用引用计数内存管理机制时,如果存在引用计数计算错误或管理错误,就会导致某些内存块的引用计数无法正确减少到零,从而无法被回收。

#include <stdio.h>struct Object {int data;int ref_count;
};void add_reference(struct Object* obj) {obj->ref_count++;
}void remove_reference(struct Object* obj) {obj->ref_count--;if (obj->ref_count == 0) {// 错误的引用计数判断,没有释放内存// 错误示例:free(obj);}
}int main() {struct Object* obj = (struct Object*)malloc(sizeof(struct Object));obj->data = 10;obj->ref_count = 1;add_reference(obj);remove_reference(obj);// 这里没有正确释放内存,引用计数错误导致内存泄露return 0;
}

3.被遗漏的数据结构释放:如果程序中存在数据结构的操作不正确,比如删除一个数据结构元素时没有正确释放相关内存空间,就会导致这些内存空间无法被回收。

#include <stdio.h>
#include <stdlib.h>struct Node {int data;struct Node* next;
};void deleteNode(struct Node* node) {// 错误的删除操作,没有释放相关内存// 错误示例:free(node);
}int main() {struct Node* head = (struct Node*)malloc(sizeof(struct Node));struct Node* node1 = (struct Node*)malloc(sizeof(struct Node));struct Node* node2 = (struct Node*)malloc(sizeof(struct Node));head->next = node1;node1->next = node2;node2->next = NULL;// 删除node1节点,但没有释放其相关内存deleteNode(node1);free(head); // 释放头节点内存// 错误的释放操作,忽略了node1相关内存的释放return 0;
}

4.循环引用:当两个或多个对象之间形成相互引用,且没有外部引用指向它们时,这些对象就会形成循环引用。如果这些对象使用了动态内存分配,但无法被访问到,就会导致内存泄露。

#include <stdio.h>
#include <stdlib.h>struct Node {int data;struct Node* next;
};int main() {struct Node* node1 = (struct Node*)malloc(sizeof(struct Node));struct Node* node2 = (struct Node*)malloc(sizeof(struct Node));node1->data = 1;node1->next = node2;node2->data = 2;node2->next = node1; // 形成循环引用// 循环引用的节点无法被访问,导致内存泄露// 这里没有写释放内存的代码return 0;
}

九、发生了coredump怎么解决

1.使用GDB

2.使用核心分析工具:一些操作系统提供了专门的核心分析工具,如Linux的crash命令和Solaris的mdb命令。这些工具可以用于分析核心转储文件,提供有关崩溃时的堆栈跟踪、寄存器值和其他信息。您可以研究相应操作系统的文档以了解如何使用这些工具。

3.使用符号化堆栈跟踪服务:有一些在线服务可以接收核心转储文件并提供符号化的堆栈跟踪信息。您可以上传核心转储文件,并获得包含函数调用链的易读输出,以帮助您定位问题。一些常见的服务包括Backtrace、Sentry和Bugsnag。

4.代码审查和日志分析:如果您拥有程序的源代码和日志文件,您可以通过仔细审查代码和分析日志来定位问题。在崩溃发生之前和之后的日志中查找错误消息、异常或其他指示性信息,以了解可能的问题所在。

5.使用内存分析工具:一些工具可以帮助您分析程序的内存使用情况,以确定内存泄漏、越界访问或其他内存相关问题。常用的内存分析工具包括Valgrind、AddressSanitizer和Memory Analyzer(MAT)。

总结

本篇文章就讲解到这里。

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

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

相关文章

2.物联网LWIP网络

一。创建工程 1.Cubemx创建工程 &#xff08;1&#xff09;操作系统的时钟配置 &#xff08;2&#xff09;配置ETH 注意&#xff1a;根据底板原理图&#xff0c;不是核心板原理图 &#xff08;3&#xff09;配置USART1串口&#xff0c;配置为异步通信 注意&#xff1a;配置结…

SAP从入门到放弃系列之BOM组-Part1

目录 BOM组两种模式&#xff1a; 创建BOM的方式 方式一&#xff1a;直接在每个工厂分别创建BOM。 方式二&#xff1a;创建BOM组&#xff0c;然后每个工厂参考创建 方式三&#xff1a;创建BOM组&#xff0c;每个工厂参考创建&#xff0c;针对有特殊的工厂复制BOM组后进行调…

Pytest三种运行方式

Pytest 运行方式共有三种&#xff1a; 1、主函数模式 运行所有 pytest.main() 指定模块 pytest.main([-vs],,./testcase/test_day1.py) 只运行testcase 下的test_day1.py 文件 指定目录 pytest.main([-vs]),./testcase) 只运行testcase 目录下的文件 通过nodeid指定用例…

C++学习| MFC简单入门

前言&#xff1a;因为接手了CMFC的程序&#xff0c;所以需要对MFC编程方面有所了解。 C之MFC简单入门 MFC相关的概念MFCWIN32QT MFC项目基本操作MFC项目创建MFC项目文件解读界面和代码数据交互——加法器 MFC相关的概念 MFC MFC&#xff08;Microsoft Foundation Classes微软…

Java ThreadLocal是什么

文章目录 引子&#xff1a;SimpleDateFormat类ThreadLocal是什么ThreadLocal 的另一个用途**总结**ThreadLocal的两大用途ThreadLocal 的源代码ThreadLocalMapThreadLocalMap 的问题ThreadLocal的key为什么设置成弱引用&#xff1f;value为什么不是弱引用&#xff1f;Thread、T…

Spring MVC【一篇搞定】

Spring MVC 文章目录 Spring MVC一、什么是 Spring MVC二、介绍MVC2.1、Spring MVC 和 MVC 之间的关系 三、创建 Spring MVC四、掌握 Spring MVC 的核心 ☆☆☆☆4.1、Spring 热部署4.2、实现用户与程序的连接 ☆4.2.1、RequestMapping4.2.2、GetMapping/PostMapping 4.3、获取…

Mask RCNN网络结构以及整体流程的详细解读

文章目录 1、概述2、Backbone3、RPN网络3.1、anchor的生成3.2、anchor的标注/分配3.3、分类预测和bbox回归3.4、NMS生成最终的anchor 4、ROI Head4.1、ROI Align4.2、cls head和bbox head4.3、mask head 1、概述 Mask RCNN是在Faster RCNN的基础上增加了mask head用于实例分割…

国外问卷调查项目赚美刀,回答一个问题赚10美刀

科思创业汇 大家好&#xff0c;这里是科思创业汇&#xff0c;一个轻资产创业孵化平台。赚钱的方式有很多种&#xff0c;我希望在科思创业汇能够给你带来最快乐的那一种&#xff01; 不要胡说八道&#xff0c;只谈干货 专注于网络创业&#xff0c;赚钱实战项目&#xff0c;信…

CentOS 7 构建 LVS-DR 群集 nginx负载均衡

1、基于 CentOS 7 构建 LVS-DR 群集。 DS&#xff08;Director Server&#xff09;&#xff1a;DIP 192.168.231.132 & VIP 192.168.231.200 [root132 ~]# nmcli c show NAME UUID TYPE DEVICE ens33 c89f4a1a-d61b-4f24-a260…

gin的占位符:和通配符*

1、用法 在 Gin 路由中&#xff0c;可以使用一个通配符&#xff08;*&#xff09;或一个占位符&#xff08;:&#xff09;来捕获 URL 的一部分。 r.GET("/royal/:id", func(c *gin.Context) {id : c.Param("id")//fmt.Println("into :id")c.Str…