赞
踩
进程线程的基本概念
1.进程,线程概念,有什么区别
进程是计算机中运行的程序实例,它具有独立的内存空间、执行环境和系统资源。
线程是进程中的一个执行单元,多个线程共享同一进程的内存和资源。区别在于进程是资源分配的基本单位,而线程是处理器调度的基本单位
2.多进程、多线程的优缺点
多进程的优点是稳定性高,一个进程崩溃不会影响其他进程,缺点是进程切换开销大、资源消耗多。
多线程的优点是创建、切换开销小,可以共享进程的资源,缺点是线程之间共享资源需要进行同步保护,易出现竞态条件和死锁等问题
3.什么时候用进程,什么时候用线程
当需要独立的内存空间、资源隔离和稳定性时,选择使用进程。
当需要并发执行、资源共享和效率时,选择使用线程
4.多进程、多线程同步的方法
多进程同步的方法:
互斥锁(Mutex):使用互斥锁来保护临界区资源,一次只允许一个进程访问共享资源。当一个进程获取到互斥锁时,其他进程必须等待。
信号量(Semaphore):通过设置信号量的计数器来控制同时访问共享资源的进程数量。进程需要先获得信号量才能继续执行,否则会被阻塞。
条件变量(Condition Variable):用于进程间的条件同步,一个或多个进程可以等待特定条件的发生。当满足条件时,唤醒等待的进程继续执行。
文件锁(File Lock):使用文件锁机制来控制对共享文件的访问。进程在访问文件之前获取文件锁,其他进程必须等待释放锁后才能访问。
多线程同步的方法:
互斥锁(Mutex):在多线程环境中,互斥锁用于保护共享资源,确保一次只有一个线程可以访问临界区。
读写锁(Read-Write Lock):适用于读多写少的场景,允许多个线程同时读取共享资源,但只允许一个线程进行写操作。
条件变量(Condition Variable):用于线程间的条件同步。一个或多个线程可以等待特定条件的发生,并在条件满足时被唤醒继续执行。
屏障(Barrier):在多线程环境中,屏障用于同步多个线程的进度,使它们在特定点上等待,直到所有线程都到达后才一起继续执行。
5.进程线程的状态,什么时候阻塞,什么时候就绪
进程和线程的状态转换图中,阻塞状态发生在等待某个事件完成或资源可用时,就绪状态是指进程或线程已获取所有必需的资源,并等待被调度执行
6.父进程、子进程的关系以及区别
父进程与子进程是通过进程创建产生的关系。父进程通过 fork() 系统调用创建子进程,子进程是父进程的副本,包括代码、数据和资源。区别在于 fork() 返回值不同,对于父进程返回子进程的进程ID,对于子进程返回0
7.一个进程可以创建多少线程,和什么有关
一个进程可以创建多个线程,具体数量受限于操作系统对线程数量的限制以及进程所能分配的资源(如栈空间)
8.进程通信的方式和优缺点
进程通信的方式包括共享内存、消息传递、管道、套接字和信号量等。它们各自具有不同的优缺点:
共享内存:
优点:速度快,适合大量数据交换;不需要复制数据。
缺点:需要进行显示的同步操作以避免竞争条件和数据一致性问题;进程间隔离性较差。
消息传递:
优点:简单易用,避免了共享内存的同步问题;传递的是消息,而非直接访问内存。
缺点:在大量数据交换时性能可能较低;需要进行消息格式定义和解析。
管道:
优点:简单、易实现;适用于具有父子关系的进程间通信。
缺点:只能用于有血缘关系的进程间通信;单向通信,双向通信需要使用两个管道。
套接字:
优点:灵活,可用于不同主机间的进程通信;支持网络通信。
缺点:相对复杂一些;性能相对较低。
信号量:
优点:能够有效地解决资源竞争问题;提供同步机制。
缺点:需要注意处理死锁和饥饿等问题;使用较复杂。
不同的通信方式适用于不同的场景和需求。在选择进程通信方式时,需要综合考虑数据量、性能要求、进程间关系以及对隔离性和同步机制的需求,以满足具体应用的要求。
9.线程通信的方式和优缺点
线程通信的方式包括共享内存和消息传递。它们各自具有以下的优缺点:
共享内存:
优点:速度快,直接访问共享数据;不需要复制数据。
缺点:需要进行显示的同步操作以避免竞争条件和数据一致性问题;线程间隔离性较差。
消息传递:
优点:简单易用,避免了共享内存的同步问题;通过发送消息来传递数据。
缺点:在大量数据交换时性能可能较低;需要进行消息格式定义和解析。
对于线程通信,共享内存是常用的方式,尤其在同一个进程内的线程间通信。由于线程共享同一进程的内存空间,因此可以直接访问共享的变量或数据结构,实现高效的通信。但需要注意线程之间的同步机制,如互斥锁、条件变量等,以避免竞争条件和数据不一致性的问题。
消息传递适用于不同进程或跨网络的线程通信。通过发送和接收消息,线程可以彼此通信,并传递数据。这种方式相对独立,不受线程间共享内存的限制。但在大量数据交换时,由于需要进行消息的序列化和反序列化,可能会带来一定的性能开销。
在选择线程通信的方式时,需要根据具体的应用场景和需求综合考虑数据量、性能要求、线程间关系以及对隔离性和同步机制的需求,以满足应用程序的要求。
10.线程中锁的种类和作用
在线程中常见的锁包括互斥锁(Mutex)、读写锁(ReadWrite Lock)和条件变量(Condition Variable)。它们各自的作用如下:
互斥锁(Mutex):
作用:用于实现线程间的互斥访问,保护共享资源在同一时间只能被一个线程访问。
工作方式:当一个线程获得了互斥锁后,其他线程需要等待,直到该线程释放了锁。
读写锁(ReadWrite Lock):
作用:用于控制对共享资源的读写访问,提供并发读取和独占写入的机制。
工作方式:多个线程可以同时获取读锁进行读取操作,但只有一个线程可以获取写锁进行写入操作。当有线程持有写锁时,其他线程无法获取读锁或写锁。
条件变量(Condition Variable):
作用:用于线程间的等待和通知机制,允许线程在特定条件下等待,并在条件满足时通知其他线程。
工作方式:一个或多个线程可以在条件变量上等待,直到其他线程通过条件变量发出信号来唤醒等待的线程。
这些锁的使用可以保证线程之间的正确同步和协作,避免竞争条件和数据不一致的问题。通过合理地选择适当的锁类型和使用方式,可以实现线程安全的并发编程。需要根据具体的场景和需求选择合适的锁来保护共享资源,并避免死锁和饥饿等问题的出现。
11.什么是死锁,怎样避免死锁
死锁是指在并发系统中,两个或多个进程(线程)因为互相占用对方所需的资源而无法继续执行的状态。
要避免死锁,可以采取以下几种方法:
避免循环等待:按照统一的顺序申请资源,以避免不同进程之间形成循环依赖关系。
使用资源的有序分配:按照固定的顺序申请和释放资源,确保每个进程(线程)只能同时占用一个资源,减少死锁的可能性。
引入超时机制:在获取资源时设置超时时间,在一定时间内无法获得资源则放弃申请,并释放已经占有的资源。
资源剥夺策略:当某个进程(线程)无法获取所需资源时,可以主动抢占或回收其他进程(线程)占有的资源,以满足当前进程(线程)的需求。
死锁检测与恢复:实施死锁检测算法,及时发现死锁的存在,并进行相应的恢复操作,如终止部分进程(线程),回滚到安全状态。
合理规划资源使用:合理规划和管理系统中的资源,避免资源过度分配或浪费,确保资源的有效利用。
定期审查代码和设计:定期审查代码和系统设计,检查是否存在潜在的死锁问题,并进行相应的修复和优化。
通过以上方法,可以减少死锁产生的概率和影响,提高并发系统的稳定性和可靠性。
网络编程概念
1.TCP、UDP的区别
TCP 是面向连接的协议,提供可靠的数据传输和错误检测机制。它通过建立连接、数据传输和断开连接来确保数据的完整性和顺序。
UDP 是无连接的协议,提供了一种简单的数据传输机制。它不会建立连接,也没有流量控制和拥塞控制,因此速度较快,但传输不可靠。
2.TCP、UDP的优缺点
TCP 的缺点:
高延迟:由于需要建立连接和保证可靠性,TCP 在传输过程中引入了较大的延迟。
较复杂:TCP 的实现比 UDP 复杂,涉及连接管理、流量控制等机制,需要更多的计算和资源。
UDP 的优点:
低延迟:UDP 没有建立连接和保证可靠性的开销,传输速度较快,适用于实时数据传输。
简单轻量:UDP 的实现相对简单,占用较少的计算和资源。
UDP 的缺点:
不可靠性:UDP 不提供可靠的数据传输机制,不保证数据的完整性和顺序。
无流量控制:UDP 没有内置的流量控制机制,容易导致数据包丢失或丢弃。
TCP 适用场景:
文件传输:当需要确保文件传输的可靠性和完整性时,TCP 是首选协议。
长连接应用:对于需要长时间保持连接的应用,如网页浏览、电子邮件等,TCP 提供了稳定的连接和持久的数据传输。
需要有序性的应用:当数据需要按照特定顺序传输和接收时,TCP 可以确保数据的有序性。
3.TCP UDP适用场景
实时应用:对于实时性要求较高的应用,如音频和视频流媒体、语音通话等,UDP 的低延迟特性更合适。
广播和多播:UDP 支持广播和多播传输,适用于向多个主机同时发送数据的应用
4.TCP为什么是可靠连接
应答和超时重传:TCP 使用确认和超时重传机制来确保数据的可靠传输。发送方会等待接收方的确认,如果在一定时间内没有收到确认,则会重新发送数据。
顺序号和重组:TCP 使用顺序号对数据进行编号,并在接收端根据顺序号将乱序的数据包重组成正确的顺序。
滑动窗口和流量控制:TCP 使用滑动窗口机制来控制发送方发送数据的速率,避免过多数据导致接收方缓冲区溢出,实现流量控制。
5.OSI典型网络模型,简单说说有哪些
七个不同的层级,从底层到顶层依次为:
物理层(Physical Layer):负责传输比特流,处理物理连接、电压等物理特性。
数据链路层(Data Link Layer):在相邻节点之间传输数据帧,处理物理地址(MAC地址)和错误检测。
网络层(Network Layer):负责在不同网络中进行包传输,进行路由选择和逻辑地址(IP地址)寻址。
传输层(Transport Layer):提供端到端的可靠或不可靠的数据传输服务,主要有TCP和UDP协议。
会话层(Session Layer):建立、管理和终止会话(连接)以实现进程之间的通信。
表示层(Presentation Layer):数据格式的转换、加密解密、数据压缩等,确保不同系统能够正确解释和处理数据。
应用层(Application Layer):提供用户与网络应用程序之间的接口,例如HTTP、FTP、SMTP等。
6.三次握手、四次挥手
三次握手(Three-Way Handshake)和四次挥手(Four-Way Handshake)是TCP建立和终止连接的过程:
三次握手:
客户端发送一个带有SYN(同步序列号)标志的请求报文段给服务器,表示客户端准备建立连接。
服务器收到请求后,回复一个带有SYN/ACK(同步/确认序列号)标志的报文段给客户端,表示接受连接请求,并同时告知自己的初始序列号。
客户端收到服务器的回复后,再发送一个带有ACK(确认序列号)标志的报文段给服务器,表示已收到服务器的确认,连接建立成功。
四次挥手:
客户端发送一个带有FIN(结束标志)的报文段给服务器,表示客户端要关闭连接。
服务器收到客户端的关闭请求后,发送一个带有ACK标志的报文段给客户端,表示确认收到关闭请求。
服务器关闭与客户端的数据传输通道,发送一个带有FIN标志的报文段给客户端。
客户端收到服务器的关闭请求后,发送一个带有ACK标志的报文段给服务器,表示确认收到关闭请求,连接终止。
通过三次握手和四次挥手,TCP协议可以在两个通信实体之间建立可靠的连接并安全地终止连接
SMTP等。
7.MTU和粘包
MTU(Maximum Transmission Unit)是指在网络通信中可以传输的最大数据包大小。它是链路层的一个参数,表示在特定网络中能够通过的最大数据包的长度。
粘包是指发送方在发送数据时,多个小的数据包被黏在一起形成一个大的数据包,接收方在接收时无法正确地区分和处理这些小的数据包。
MTU的常见值为1500是因为在以太网(Ethernet)中,定义了一种常用的帧格式,称为以太网帧(Ethernet Frame),其中数据字段的最大长度为1500字节。
这个1500字节的数值包括数据部分和其他帧头(如目标MAC地址、源MAC地址、长度/类型等)所占用的字节数。以太网是一种广泛应用的局域网技术,因其高效性和可靠性而成为许多网络的基础。因此,在以太网中,通常将MTU设置为1500字节,以适应这种帧格式。
需要说明的是,MTU的实际值可以因网络设备、网络协议或特定需求而有所不同。在某些情况下,MTU可能会被调整为小于1500字节的值,以适应特殊网络环境或要求较低延迟的应用场景。
粘包问题常见于基于流式传输的协议(如TCP),由于数据的发送和接收没有固定的边界,导致多个数据包被一次性发送或接收,造成粘包现象。
解决粘包问题的方法有以下几种:
定长包:发送方在每个数据包的前面加上固定长度的标识,接收方按照该长度进行切割和处理。但是会浪费空间。
分隔符:发送方在数据包之间加入特定的分隔符,接收方根据分隔符进行拆分和处理。适用于内容不包含分隔符的情况。
包头+包体:发送方在每个数据包的开头加上包头信息,包头中包含了数据包的长度等信息,接收方首先读取包头来获取数据包的长度,然后根据长度读取对应长度的数据。
Linux操作系统概念
1.Linux内核的组成部分
Linux内核由以下几个主要组成部分构成:
进程管理:负责创建、调度和终止进程,以及处理进程间通信和同步。
内存管理:管理系统的物理内存和虚拟内存,包括分配、回收和页面调度等操作。
文件系统:提供对文件和目录的管理和访问,包括文件的创建、读写、删除等操作。
设备驱动程序:管理和控制硬件设备,通过与硬件交互来实现输入/输出功能。
网络协议栈:支持各种网络协议,如TCP/IP协议栈,用于实现网络通信功能。
系统调用接口:提供给用户空间的接口,允许用户程序请求内核执行特权操作。
2.用户空间与内核通信方式有哪些?
系统调用:用户通过调用特定的系统调用函数向内核发送请求,并将参数传递给内核。内核在执行完相应操作后返回结果给用户。
中断:硬件或软件中断可以触发内核的处理程序,从而与用户空间进行通信。
文件操作:用户可以通过读写特殊文件(如设备文件)与内核进行通信,通过读写这些文件完成特定的操作。
进程间通信(IPC)机制:例如管道、消息队列、共享内存等,允许进程在用户空间之间交换数据,进而实现与内核的通信。
3.系统调用read()/write(),内核具体做了哪些事情
系统调用read()和write()涉及以下主要操作:
用户空间程序调用read()/write()函数并传递相应参数。
内核接收到系统调用请求后,从用户提供的缓冲区中读取或写入数据。
内核对数据进行处理,包括检查权限、验证数据合法性等。如果需要,内核会将数据从内核空间复制到用户空间(read()),或者从用户空间复制到内核空间(write())。
内核返回操作结果给用户空间程序。
4.系统调用与普通函数调用的区别
系统调用与普通函数调用的区别在于执行的上下文和特权级别。系统调用是用户程序向内核请求执行特权操作的一种机制,因此会触发从用户态切换到内核态的过程,并且需要进行权限检查。普通函数调用则在同一个特权级别下执行,不涉及特权操作和切换。
5.内核态,用户态的区别
内核态:
内核态是操作系统内核运行的特权级别。在内核态下,程序可以访问和执行所有的系统资源和指令。内核态具有更高的权限和更大的访问权,可以直接操作硬件设备、修改系统状态和管理系统资源。
在内核态下运行的代码通常是操作系统内核或驱动程序,它们负责处理与系统底层硬件和资源相关的任务,如进程调度、设备驱动、内存管理等。
用户态:
用户态是一般应用程序运行的特权级别。在用户态下,程序只能访问受限的资源,并且受到操作系统的保护,无法直接访问底层硬件或执行特权指令。
在用户态下运行的代码通常是用户应用程序,如文本编辑器、浏览器、游戏等。这些应用程序通常通过操作系统提供的应用程序接口(API)来请求操作系统的服务和资源。
区别:
特权级别:内核态具有更高的特权级别,可以直接访问系统所有资源和指令。用户态下的程序受到操作系统的保护,无法直接访问底层硬件或执行特权指令。
资源访问:内核态下的程序可以直接操作系统资源和硬件设备。用户态下的程序只能通过系统调用等受限的方式来访问系统资源。
安全性:由于用户态受到操作系统的保护,内核态下运行的代码需要经过严格的验证和控制,以防止恶意或错误的操作对系统造成损害。
在正常情况下,大部分应用程序都在用户态下运行,而内核态主要由操作系统内核和驱动程序来执行。操作系统会管理和切换用户态和内核态之间的转换,以确保系统的稳定性、安全性和资源的合理利用。
6. Bootloader、内核和根文件系统之间的关系如下:
Bootloader(引导加载程序)是位于计算机硬件和操作系统之间的软件,用于初始化硬件设备、加载内核和根文件系统,并将控制权转交给内核启动。Bootloader通常存储在启动设备的引导扇区或其他特定位置。
内核(Kernel)是操作系统的核心部分,负责管理和控制计算机的硬件资源,提供各种系统服务和功能。内核是操作系统的基本组成部分,由开发者编写,以可执行文件的形式存在。
根文件系统(Root File System)是操作系统中的初始文件系统,包含操作系统所需的基本文件和目录结构。它提供了文件存储、目录管理等功能,是操作系统运行时的基础。根文件系统通常包含/bin、/sbin、/etc、/lib等目录。
在启动过程中,Bootloader的主要任务是将控制权从固件(如BIOS或UEFI)转交给操作系统。具体的Bootloader启动过程如下:
7. Bootloader启动过程:
计算机上电或重启后,固件(BIOS或UEFI)会进行自检和初始化,并加载Bootloader到内存中的指定位置。
Bootloader被执行,它首先进行硬件初始化,例如设置内存、存储等设备参数,并加载操作系统内核和根文件系统到内存中的指定位置。
一旦内核和根文件系统加载完毕,Bootloader会设置内核的启动参数(如命令行参数)并跳转到内核的入口点。
控制权转交给内核后,内核开始执行,在初始化阶段完成各种系统配置和资源管理。
内核会挂载根文件系统为系统的根目录,并根据配置加载其他必要的模块和驱动程序。
最后,内核启动第一个用户空间进程(通常是init进程),它负责系统初始化、服务启动和用户程序管理。
整个过程中,Bootloader起到了连接硬件和操作系统的桥梁作用,将控制权从固件传递给内核,并提供必要的参数和加载操作系统所需的文件。
8.大小端
1.大小端的区别以及各自的优点,哪种时候用。(判断大小端的三种方式)
大小端(Endianness)是指在多字节数据类型存储时,字节序(即字节的排列顺序)的不同方式。主要有两种形式:
大端字节序(Big Endian):将高位字节存储在低地址,低位字节存储在高地址。
小端字节序(Little Endian):将低位字节存储在低地址,高位字节存储在高地址。
选择使用哪种字节序取决于硬件架构和通信协议的要求。各种字节序各有优点:
大端序:易于阅读和理解,对网络通信的兼容性较好。
小端序:处理器直接访问最低有效字节,具有更高的效率,适用于大部分现代处理器架构。
判断大小端的三种方式:
内存中地址的比较:通过创建一个包含多字节数据的指针,并根据指针所指向的内存地址来判断字节序。
联合体(Union):创建一个联合体类型,其中包括一个多字节数据类型和对应的字节型数组。访问并比较字节数组的第一个元素即可判断字节序。
位操作:通过将数据类型强制转换为字节类型,然后检查字节的顺序来判断字节序。
9.一个程序从开始运行到结束的完整过程(四个过程)
编译(Compilation):将源代码文件转换为可执行的目标代码,通常通过编译器完成。
链接(Linking):将目标代码与所需的库函数进行链接,生成最终的可执行文件。链接器将各个模块之间的引用和符号解析为可执行代码。
加载(Loading):将可执行文件从存储介质加载到内存中,并为其分配必要的资源。加载器负责解析可执行文件的结构,创建进程并将代码和数据加载到适当的内存位置。
执行(Execution):处理器按照指令在内存中的顺序执行程序,执行各个操作,包括数据操作、控制流程和与外部环境的交互。
10.什么是堆,栈,内存泄漏和内存溢出?
堆(Heap)是用于动态分配内存的区域,用于存储程序运行时创建的对象和数据。堆的大小通常由操作系统管理,并通过特定的分配和释放方法(如malloc和free)来进行内存的分配和释放。
栈(Stack)是一种线程专用的内存区域,用于存储局部变量、函数调用、参数和返回地址等临时数据。栈的大小通常较小且有限,由编译器和运行时环境进行管理,自动分配和释放。
内存泄漏(Memory Leak)指的是程序在分配内存后未释放该内存,导致系统中出现无法访问或回收的内存块。内存泄漏会导致内存资源的浪费,并可能导致系统性能下降或崩溃。
内存溢出(Memory Overflow)是指程序尝试使用超过已分配内存空间的部分,可能导致数据覆盖、崩溃或安全漏洞。当程序向栈或堆写入超过其边界的数据时,就可能发生内存溢出。溢出可能导致程序不可预期的行为和安全隐患。
11.堆和栈的区别
堆(Heap)是动态分配内存的区域,用于存储程序运行时创建的对象和数据。堆的大小通常由操作系统管理,并通过特定的分配和释放方法(如malloc和free)来进行内存的分配和释放。堆上的内存分配是手动控制的,没有固定的分配顺序。
栈(Stack)是一种线程专用的内存区域,用于存储局部变量、函数调用、参数和返回地址等临时数据。栈的大小通常较小且有限,由编译器和运行时环境进行管理,自动分配和释放。栈上的内存分配是自动控制的,遵循后进先出(LIFO)原则
主要区别:
分配方式:堆上的内存分配是手动控制的,需要显式地申请和释放内存。栈上的内存分配是自动控制的,由编译器和运行时环境自动处理。
管理机制:堆的内存管理通常由操作系统负责,通过动态内存分配算法来管理堆上的内存。栈的内存管理由编译器和运行时环境负责,通过栈指针控制栈上的内存使用。
大小与生命周期:堆的大小通常较大且灵活,存储动态分配的对象和数据。栈的大小通常较小且有限,存储局部变量和临时数据。堆上的内存可以在程序运行期间一直存在,直到显式释放。栈上的内存随着函数的调用和返回而自动分配和释放。
12.硬链接与软链接的区别;
硬链接是指多个文件名指向同一个索引节点(Inode),它们共享相同的文件内容和属性。删除其中一个硬链接不会影响其他链接,只有当所有链接都被删除时,才会释放磁盘空间。硬链接不支持跨文件系统创建。
软链接是一个特殊的文件,它包含了指向另一个文件的路径。软链接类似于Windows系统中的快捷方式。软链接有自己的索引节点,删除原始文件或软链接都会导致文件不可访问。软链接可以跨越文件系统,并且可以链接目录。
13.虚拟内存,虚拟地址与物理地址的转换
虚拟内存(Virtual Memory)是计算机系统中的一种技术,将物理内存和磁盘之间的交换空间作为逻辑地址空间的延伸。虚拟内存允许程序使用连续的逻辑地址空间,而不需要连续的物理内存空间。虚拟地址是程序中使用的逻辑地址,而物理地址是实际对应于主存中的地址。
虚拟地址与物理地址的转换是通过操作系统的内存管理单元(Memory Management Unit,MMU)实现的。MMU使用页表或段表等数据结构来映射虚拟地址到物理地址。当程序访问虚拟地址时,MMU根据页表或段表的映射关系进行地址转换,将虚拟地址转换为对应的物理地址
14.中断和异常的区别
中断是由外部事件触发的信号,用于中断当前正在执行的程序流程,以处理紧急或优先级较高的任务。中断可以来自硬件设备(如键盘、鼠标、定时器)或其他外部源。中断通常会打断当前正在执行的程序,转而执行中断处理程序,然后返回到被中断的程序继续执行。
异常是指在程序执行过程中遇到的错误或异常情况,例如除零错误、内存访问错误等。异常通常由处理器检测到,并触发相应的异常处理机制。异常可以导致程序的终止或转到异常处理程序进行处理,具体处理方式取决于操作系统或编程语言的实现。
15.中断怎么发生,中断处理流程
发生:中断通常由硬件设备或其他外部源发出一个中断请求信号(IRQ),将控制权转移到中断向量表中对应的中断服务程序。
响应:处理器接收到中断请求信号后,暂停当前执行的指令,保存相关上下文信息(如寄存器状态),并跳转到中断向量表中对应的中断服务程序。
处理:中断服务程序执行与中断相关的处理逻辑,可能包括读取设备状态、处理数据、更新数据结构等。
恢复:中断服务程序执行完毕后,恢复之前保存的上下文信息,将控制权返回到被中断的程序继续执行。
16.Linux 操作系统挂起、休眠、关机相关命令
挂起(Suspend):用于将系统进入低功耗状态,暂停所有活动并保留当前状态。在绝大多数Linux发行版中,使用systemctl suspend或pm-suspend命令来挂起系统。
休眠(Hibernate):将系统当前的状态保存到硬盘,并关闭电源以实现完全的断电。休眠后系统可以恢复到之前的状态。在大多数Linux发行版中,使用systemctl hibernate或pm-hibernate命令来进行休眠操作。
关机(Shutdown):用于安全地关闭操作系统并关闭计算机。在绝大多数Linux发行版中,使用shutdown、poweroff或halt命令来进行关机操作。
ARM单片机常见面试题
1.ROM与RAM,SDRAM DDR Flash
ROM(Read-Only Memory)是一种只读存储器,用于存储固定的程序和数据。它的内容在制造过程中被写入,无法被普通用户修改。ROM常见的应用包括计算机的系统引导程序、固件、BIOS等。
RAM(Random Access Memory)是一种随机访问存储器,用于临时存储正在运行的程序和数据。RAM具有快速的读写速度,但断电后数据会丢失。RAM常见的应用包括计算机的运行内存、缓存等。
SDRAM(Synchronous Dynamic Random-Access Memory)是一种同步动态随机访问存储器,属于RAM的一种类型。SDRAM以固定的时钟信号同步数据传输,提供更高的带宽和性能。它广泛应用于计算机的主存储器。
DDR(Double Data Rate)是SDRAM的一种改进版本,通过在每个时钟周期内进行两次数据传输来提高数据传输速率。例如,DDR3和DDR4是当前常见的DDR技术标准,用于提高计算机内存的速度和性能。
Flash存储器是一种非易失性存储器,可以在断电后保持数据。Flash存储器使用特殊的电荷存储技术,可进行多次擦除和编程操作。它具有较高的存储密度和良好的耐久性,常见于可移动设备如USB闪存驱动器、固态硬盘(SSD)以及嵌入式系统中。
它们在计算机系统中的作用如下:
ROM存储器包含不可更改的固定程序和数据,用于引导计算机系统、存储固件和BIOS等核心功能。
RAM存储器用于暂时存储正在运行的程序、数据和操作过程中所需的临时信息。
SDRAM是主要的系统内存,提供高速的读写访问,用于存储当前活动的应用程序和数据。
DDR技术提高了SDRAM的数据传输速率,增加了内存带宽,从而提升了计算机的性能。
Flash存储器可作为可擦写存储介质,用于存储操作系统、应用程序、用户数据和固件等,并且可以在断电后保持数据。它广泛应用于各种可移动设备和嵌入式系统中。
这些存储器在计算机系统中相互配合,发挥重要的作用,支持系统的正常运行和存储数据。
2.常见的外围设备通信方式
下面是常见接口通信方式的优缺点:
UART:
优点:简单、成本低、易于实现,适用于较低速率的串行通信。
缺点:传输速率相对较慢,只能进行点对点的通信,不支持多设备连接。
I2C:
优点:使用两根线路进行数据传输,占用引脚少,可同时连接多个设备,具有简单的命令和寻址机制。
缺点:传输速率相对较低,适合短距离通信,对于长距离或高速通信的需求不适用。
SPI:
优点:传输速率快,支持全双工通信,适合高速数据传输,可构建简单的主从结构。
缺点:需要使用多个引脚进行连接,对于复杂系统的连接可能不够灵活,不支持多主机通信。
USB:
优点:高速、双向、热插拔的数据传输,支持多种设备类型和功能,广泛应用于计算机和外围设备之间的通信。
缺点:复杂性较高,需要专门的USB控制器和驱动程序,成本相对较高。
Ethernet:
优点:高速、可靠的局域网通信,适用于连接远程设备和数据传输,支持较大规模网络和复杂的通信协议。
缺点:相对复杂,需要使用专门的硬件和协议支持,对于嵌入式系统和一些资源受限的应用可能过于笨重。
每种接口通信方式都有其适用的场景和限制。选择合适的通信方式需要考虑数据传输速率、距离、设备复杂性、成本和系统要求等因素。在设计系统时,需要权衡各种因素,并根据具体需求做出决策。
不同的接口通信方式使用的线数是不同的:
UART(通常使用的是RS-232标准):UART使用两根线,一根用于数据传输(TX线),另一根用于接收数据(RX线)。
I2C:I2C使用两根线,一根为时钟线(SCL),用于同步数据传输的时序;另一根为数据线(SDA),用于实际的数据传输。
SPI:SPI通常使用四根线,包括一个主机输出从机输入的数据线(MOSI),一个主机输入从机输出的数据线(MISO),一个时钟线(SCK)用于同步数据传输时序,以及一个片选线(SS/CS)用于选择特定的从机。
USB:USB通常使用四根线,包括两根用于双向数据传输的差分信号线(D+和D-),一根用于提供电源(VCC),以及一根地线(GND)。
Ethernet:Ethernet使用至少四根线,包括一对差分信号线(TX+和TX-,或RX+和RX-),一根时钟线(CLK),以及一根地线(GND)。在千兆以太网中,还需要额外的四根线(RX+、RX-、TX+和TX-)来支持更高的带宽。
需要注意的是,某些通信方式可能还有其他辅助线或引脚,用于电源供应、地线连接和设备控制等。上述仅是常见通信方式的基本线数描述。
下面是常见接口通信方式的传输速率范围:
UART(通常使用的是RS-232标准):传输速率范围从几十位/秒到数百万位/秒,具体速率取决于UART芯片和实际应用。
I2C:标准模式下的传输速率为100 kbit/s,快速模式为400 kbit/s,高速模式为3.4 Mbit/s,超高速模式可达到更高速率,如5 Mbit/s或12.5 Mbit/s。
SPI:SPI的传输速率与硬件实现和设备规格有关。在理论上,SPI可以达到几十MHz甚至上百MHz的速率。具体速率取决于设备的支持能力、时钟频率和物理环境。
USB:USB有多个版本和速率等级。常见的USB 2.0标准提供最高传输速率480 Mbit/s(60 MB/s),USB 3.0和USB 3.1标准分别支持最高传输速率为5 Gbit/s(625 MB/s)和10 Gbit/s(1250 MB/s)。USB 4.0标准进一步提高了速率,可达20 Gbit/s(2500 MB/s)。
6.Ethernet:以太网的传输速率也有多个标准和变种。常见的以太网标准包括10 Mbps(10BASE-T)、100 Mbps(100BASE-TX)、1 Gbps(1000BASE-T)和10 Gbps(10GBASE-T)。此外,还存在更高速的以太网标准,如40 Gbps和100 Gbps。
7.
需要注意的是,上述传输速率是每种接口通信方式的最常见或典型速率,具体速率可能因实际应用、设备能力和配置而有所不同。此外,还存在一些定制协议或特殊设备,其传输速率可能超出上述范围。
杂项概念
new 和 malloc的区别:
new是 C++ 中的操作符,而malloc是 C 语言中的函数。
new在分配内存的同时会调用对象的构造函数进行初始化,而malloc只是简单地分配一块指定大小的内存空间。
new返回的是对象类型的指针,而malloc返回的是void*类型的指针,需要进行显式的类型转换。
new抛出异常(如 std::bad_alloc)来处理内存分配失败的情况,而malloc在内存分配失败时返回空指针(NULL)。
2.malloc的底层实现:
malloc函数的底层实现会根据具体的操作系统和编译器而有所不同。通常,它会使用操作系统提供的堆管理机制来分配所需的内存空间。一般情况下,malloc调用了系统调用(如 brk或 sbrk)来扩展进程的堆空间,然后将分配到的内存块返回给调用者。
3.指针与引用的相同和区别;如何相互转换?
相同点:
指针和引用都可以用于访问变量或对象。
指针和引用都可以作为函数参数传递,允许对传入的变量进行修改。
区别:
指针可以为空(NULL),但引用必须始终引用一个已存在的对象。
指针可以被重新赋值指向其他对象,而引用一旦绑定到一个对象后就无法改变其引用目标。
引用在声明时必须进行初始化,并且不能有空引用。
指针转换为引用:可以使用解引用操作符 *将指针转换为引用,例如 int& ref = ptr;。
引用转换为指针:可以使用取地址操作符 &将引用转换为指针,例如 int ptr = &ref;。
C 语言检索内存情况,内存分配的方式:
在 C 语言中,可以使用 malloc 和 free 函数进行动态内存分配和释放。此外,还可以使用栈上分配的局部变量(自动变量)和全局变量(静态变量)来进行内存分配。可以通过调试工具或编写代码来检查内存的使用情况和泄漏问题。
5.extern "C"的作用:
extern "C"是 C++ 中的语言特性,用于指定以 C 语言的方式进行函数名重载和链接。当 C++ 代码与 C 代码进行混合编译时,可以使用 extern “C” 来告诉编译器将某段代码按照 C 语言的规则进行处理,避免了 C++ 的名称修饰和函数重载导致的链接错误。
8.memcpy()函数需注意,strcat strncat strcmp strcpy哪些函数会导致内存溢出
确保源地址和目标地址的有效性,避免越界访问。
考虑内存重叠情况,确保拷贝的正确性。
strcat如果目标字符串的空间不足以容纳源字符串,可能导致缓冲区溢出。
strncat如果指定的拼接长度超过目标字符串的剩余空间,可能导致缓冲区溢出。
strcmp如果比较的字符串没有以空字符结尾,可能导致访问非法内存。
strcpy如果源字符串没有以空字符结尾,可能导致访问非法内存。
9.char和int之间的转换
在 C 语言中,可以使用字符型变量和整型变量之间的隐式类型转换。将一个字符赋值给整型变量时,会将字符的 ASCII 值作为整数赋给该变量。将一个整型值赋值给字符型变量时,会将整数的低位字节(如果符合字符范围)作为字符赋给该变量。
显式转换可以通过强制类型转换实现。例如,将字符型转换为整型:int num = (int)ch;,将整型转换为字符型:char ch = (char)num;
8.static的用法(定义和用途)static静态变量,只初始化一次
static关键字在 C 语言中有多种用法和含义:
定义静态变量:在函数内部使用 static关键字定义的变量称为静态局部变量,它会在程序运行期间保持其值不变,并且只初始化一次。
局部函数:在函数定义前加上 static关键字将函数声明为仅在当前文件可见的静态函数,不能被其他文件访问。
静态全局变量:在函数外部或模块内部使用 static关键字定义的全局变量,它的作用域限定在当前文件中,其他文件无法访问。
静态函数:在函数定义前加上 static关键字将函数声明为仅在当前文件可见的静态函数,不能被其他文件访问。
10.const的用法(定义和用途)
const 关键字在 C 语言中用于声明常量。它可以用来修饰变量、函数参数和函数返回值。
修饰变量:使用 const 关键字修饰的变量被称为常量,其值在初始化后不能被修改。
修饰函数参数:使用 const 关键字修饰函数参数表示该参数在函数体内不会被修改,提高代码的可读性和安全性。
修饰函数返回值:使用 const 关键字修饰函数返回值表示该返回值是只读的,不允许对其进行修改。
12.const常量和#define的区别(编译阶段、安全性、内存占用等)
编译阶段:const 常量在编译时进行类型检查,具有更强的类型安全性,而 #define 宏定义是简单的文本替换,在预处理阶段进行,没有类型检查。
安全性:const 常量具有作用域和命名空间,不会导致命名冲突,而宏定义没有作用域概念,可能引发命名冲突和意外的替换。
内存占用:const 常量在内存中分配了存储空间,每个变量只有一份内存;而宏定义仅仅是文本替换,没有内存占用。
调试信息:const 常量在调试过程中可以提供符号信息,而宏定义不存在符号信息
13.volatile作用和用法
volatile 关键字用于告诉编译器一个变量可能会被意外修改,从而禁止对该变量进行优化。主要用途包括:
用于多线程或并发编程中,标记共享变量,保证每次访问都是对内存的实际读写,避免编译器对变量的优化。
用于与硬件相关的地址或寄存器,因为这些值可能会被硬件或其他程序修改,需要确保每次读取都是实时的。
用于信号处理函数中,防止编译器将对变量的读写操作优化掉,保证正确处理信号。
13.有常量指针 指针常量 常量引用 没有 引用常量
常量指针:指针指向的地址不可修改,但指针本身可以修改,例如 int* const ptr;。
指针常量:指针本身不可修改,指向的地址可以修改,例如 const int* ptr; 或 int const* ptr;。
常量引用:指向的对象不可修改,例如 const int& ref;。引用本身不可修改。
14.变量的作用域(全局变量和局部变量)
全局变量:声明在函数外部、代码块外部的变量为全局变量,其作用域从声明处开始到文件末尾,可以被整个程序访问。
局部变量:声明在函数内部或代码块内部的变量为局部变量,其作用域仅限于所在的函数或代码块内部,在外部不可访问。
全局变量与局部变量同名时,局部变量会覆盖全局变量的值。
静态局部变量:在函数内部使用 static 关键字修饰的局部变量称为静态局部变量,其生命周期跨越多次函数调用,但作用域仍限于所在的函数内部。
15.sizeof 与strlen (字符串,数组)
sizeof 是 C 语言的运算符,用于获取数据类型或变量占用的内存大小(以字节为单位)。
strlen是 C 语言的库函数,用于计算字符串的长度(不包括结尾的空字符 ‘\0’),返回值为无符号整型。
16.经典的sizeof(struct)和内存对齐(一字节对齐)
sizeof(struct) 用于计算结构体的大小,包括结构体中所有成员的大小之和,可能会受到内存对齐的影响。
内存对齐是为了提高访问效率和处理器的要求,结构体中的成员在内存中按照特定规则对齐,通常以成员大小或者指定的对齐值为基准进行对齐。
一字节对齐指的是结构体中的每个成员都从结构体的起始地址开始,不考虑对齐规则,占用实际大小
17.const * char 与 const char *
const * char 是指向字符常量的指针,表示指针指向的字符内容不能通过指针修改。
const char *是指向字符的指针,表示指针指向的字符可以通过其他途径修改,但通过该指针本身不可修改。
18.inline函数
inline是 C 语言的关键字,用于声明内联函数。内联函数是一种编译器优化手段,将函数的代码直接插入调用处,避免了函数调用的开销,提高执行效率。使用 inline 关键字声明的函数ÿ
文章知识点与官方知识档案匹配
C技能树首页概览
204088 人正在系统学习中
最低0.47元/天 解锁文章
Linux C/C++ or 嵌入式面试之《C/C++笔面试系列》(15) 几种常用的排序算法C实现
文章目录1、冒泡排序法2、选择排序3、插入排序4、快速排序(快排)5、归并排序 1、冒泡排序法 算法思想 让数组中相邻两个数字进行比较,如果是升序排列,如果左边的大于右边,则交换,相当于将较大的数往后挪。第一趟有n个数据,需要比较n-1次,可以将最大的数挪到数组最末端,第二趟只有n-1个数据了,只需要比较n-2次… 每一趟可以决出一个数,n个数只要决出n-1个数的位置,剩下一个数也就定了,所以最多需要比较n-1趟。 总共需要比较1+ 2 + … + n-1 = n(n-1)/2, 所以算法复杂度是O(n^2
继续访问
嵌入式C语言笔试面试题
该文档是嵌入式C语言面试常见笔试面试题,包括C基础知识部分,数据结构部分,嵌入式部分等。
【程序】在STM32单片机上用1700行代码实现基于LwIP 2.1.2协议栈raw API和FatFs文件系统的FTP服务器(20200703版)
本程序在LwIP 2.1.2协议栈上用raw API实现了一个FTP服务器。文件存储在Winbond的W25Q128 SPI Flash中,通过FatFs读写文件,建立了FAT文件系统,容量为16MB。程序只有1700多行代码,由头文件ftp.h和源文件ftpd.c组成。 主要特点: 1. 采用lwip的raw API实现,可以在裸机环境下运行,支持IPv6 2. 兼容Windows文件管理器和FileZilla FTP客户端 3. 实现了文件浏览、上传、下载、重命名、新建文件夹、删除文件夹和文件等基本F
继续访问
win10搭FTP与单片机通信:配置+编程实现的完整流程
平台:迅为单片机SUM4412,PC(win 10系统); 软件:MobaXterm,tftpd64; 硬件:串口线,网线。
继续访问
嵌入式Linux C编程学习之路(五)——基础排序算法
在进行排序算法时经常用到交换两个数组元素的功能,将这个功能单独写成一个子函数,采用传引用调用的参数传递方式,对数组元素的地址直接进行操作,达到改变其位置的功能。代码如下: void swap(int*p,int*q) { int a; a=*p; *p=*q; *q=a; } 一:选择排序 将要排序的对象分作两部份,一个是已排序的,一个是未排序的,从后端未...
继续访问
常见linux 嵌入式开发C语言笔试面试题
常见linux 嵌入式开发C语言笔试面试题
嵌入式C语言笔试面试题txt文件
该文档是嵌入式C语言笔试面试题集锦, 包括C语言基础部分,数据结构部分,编程部分,嵌入式编程部分等
超全的嵌入式工程师笔试面试题汇总.zip
超全的嵌入式工程师笔试面试题汇总 单片机嵌入式应聘测试题(含答案).pdf 经典嵌入式面试题.pdf 嵌入式工程师笔试题带答案.pdf 嵌入式工程师经典面试题.pdf 嵌入式软件工程师笔试集锦.pdf 嵌入式软件工程师笔试题__...
嵌入式C语言面试题汇总
第一部分:基本概念及其它问答题 第二部分:程序代码评价或者找错 第三部分:编程题
超全的C语言嵌入式工程师笔试面试题汇总,C语言版嵌入式工程师笔试面试题
超全的C语言嵌入式工程师笔试面试题汇总,C语言版嵌入式工程师笔试面试题
热门推荐 基于ESP8266的阿里云远程实时温度监控
基于ESP8266的远程实时温度监控 基于ESP8266的远程实时温度监控系统,通过ESP8266开发板采集DHT11温湿度传感器的数据,在连接WIFI接入网络中,将实时采集到的温湿度数据通过MQTT通信协议上云,传送至阿里云网络平台中进行实时的网页显示。同时,网页可以通过开关控制网页上的警示灯的状态,并且利用MQTT通信协议下发指令控制ESP8266的LED灯亮灭;在本地端实现了温湿度数据上报,温度报警,即在温度超过设定的阈值(25℃)后,便开启警报(ESP8266上LED亮红灯、网页上警示灯亮红灯)。
继续访问
c语言多文件编程,即main文件调用其他.c文件的方法
首页 博客 学院 下载 论坛 问答 活动 专题 招聘 APP VIP会员 博客之星 写博客 5 c语言多文件编程,即main文件调用其他.c文件的方法 原创 天泉证道 最后发布于2018-11-14 14:46:32 阅读数 4047 收藏 展开 c语言多文件编程,即main文件调用其他.c文件的方法。 两种方法的区别就是,gcc编译时,是否加b.c文件,不加的话,就在a.c文件里面,加#in...
继续访问
【C/C++】嵌入式程序员应该知道的0X10个C语言问题
一、预处理器(Preprocessor) 1 . 用预处理指令#define 声明一个常数,用以表明 1 年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL View Code 想看到的几件事情: #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等) 懂得预处理器将为你计...
继续访问
最新发布 【嵌入式C语言开发】实战第080例 常用算法之-磁盘文件排序
if(i
继续访问
RT-Thread--Lwip之FTP
本说明基于在RTT下搭建完成网络通信功能基础上完成,具体网络实现参见另外一个教程。 https://blog.csdn.net/rou252051452/article/details/123084492https://blog.csdn.net/rou252051452/article/details/123084492 1、软件包使能 打开RT-ThreadSetting进行软件包安装,保存生效文件 2、FTP功能的初始化 主函数通过包含...
继续访问
嵌入式软件开发面试C语言笔试题 答案完整版.pdf
嵌入式软件开发面试C语言笔试题 答案完整版
嵌入式软件笔试面试题合集
其中包含了Linux系统开发的一下相关知识点的总结,还有常见面试题的应对方案 C语言和c++各个模块会问到的技术性问题及经验分析 适合人群:正在找工作的小伙伴,错过秋招正在等待秋招的小伙伴 能学到什么:①在软件...
嵌入式开发—C语言面试题(笔试部分)
嵌入式开发—C语言面试题(笔试部分)
嵌入式岗位笔试面试真题+讲解
lnux操作系统题目、网络编程题目、ARM裸机开发题目、进程与线程题目、基本的寄存器与存储器题目、C语言&数据结构与算法题目、ARM处理器与中断题目、数据结构与算法题目、内存管理&编程题题目、.预处理&关键字题目、...
嵌入式C语言面试题
最全C语言面试题。包含给类C语言基础题、嵌入式C语言编程题,华为等各大企业C语言笔试题!
linux
面试
C语言
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。