当前位置: 首页 > article >正文

嵌软面试一百问(持续更新中)

目录

c语言

1.关键字

static

extern

const

Volatile

2.指针/数组

在C中,传进一个数组之后,自定义一个函数,行参的使用和数组使用的注意事项 数据区放什么,有多大?

在C语言中什么时候用二级指针?

怎么定义一个整形5个元素的数据指针

strcopy strncopy有什么区别

malloc中有部分空间没有被覆掉怎么办?

指针数组和数组指针有什么区别?

如何在C语言中定义一个能够变长的数组空间?

3.预编译

if not define一般有啥用

包头文件“”和<>有啥区别?

文件IO

1.目录

目录操作流程及函数名字

目录的遍历怎么实现?

2.文件

知道哪几种IO模型?

怎么实现文件的拷贝?

复制文本文件怎么操作

fgets和fputs文件的拷贝是怎么实现的?

IO学了什么?

进程线程

1.线程进程区别

线程和进程的概念,区别,以及什么时候用线程什么时候用进程?

线程什么时候互斥,什么时候同步?

进程的目的?

线程有什么作用?

进程间为什么要通信?有几种方式?

进程状态的切换有哪几种?

父与子运行期间的关系是什么?

无名管道和有名管道的创建流程

创建管道-打开-读写管道-关闭管道-卸载管道

编译多任务程序时是首选进程还是线程

2.锁

线程间为什么要加锁?

你知道锁吗?讲下自旋锁和互斥锁的区别,你知道读写锁吗?

为什么多线程需要互斥,多进程不需要?

什么是阻塞?

互斥、同步的概念?

3.多路io

在少事件时,epoll和select那个好?

epoll和poll的区别

epoll和线程池的关系和区别?

epoll能否代替线程池?

线程池和多进程的区别?

网络通信

1.http

http的端口号是什么,代码是什么?

http是干什么的,中文名是什么,主要用在什么地方?

http的端口号是什么,端口号是干什么用的?

http请求报文的格式是什么?

http交互报文的格式?

描述一下http的交互过程?

2.tcp/udp

TCP、UDP的区别?

TCP的四层应用是什么?

TCP为啥安全可靠?

TCP/IP是那种模型的协议

TCP/IP分几层,每层的核心任务是什么?

3次握手的过程是怎么样的?

怎样能使UDP稳定?什么是同步?什么是异步?

设计一个点对点通信的软件,选择TCP还是UDP,为什么?

3.其他

应用层的协议是什么?

熟悉那些协议?下载用什么协议?

说一下wireshark,他有哪些功能

描述端口号的作用,概念,两边都有还是只有一边

应用层的协议有哪些?

数据结构

链表的作用?

数据结构的框架?

列表和数组的区别?

链表头插尾插那种效率高?

简单说一下链表查重,结束的条件是什么?

数组和列表的优缺点?

单链表和双链表的区别?为什么快指针不能走3不?

如果知道某个节点的值,想删除怎么操作?

数据结构、表、栈、队列之间的区别?

常用的数据结构有哪些?

栈、队列有什么相同点?

数列A、B、C输出A、C、B用栈的方式可以实现吗?

如何实现二叉树的层序遍历?

广度优先遍历,深度优先遍历的区别?

数据库

数据库的流程。

都了解那些数据库?

各个数据库的异同?

数据结构对之前的编程有什么帮助?

优先选择哪种链表用到编程中去?

用过哪些SQL的编程语言?

数据库的工作原理?

查数据库如何升序打印

编译程序如何选择数据库

基础知识

Linux当中栈默认有多大?

singal作用

栈区放什么?栈区有多大?

内存分布图?有那几个区?

进程中内存分布图描述及作用

声明和定义的区别

编译程序什么时候会用多任务

什么是内存泄露、内存碎片、内存溢出?

内存碎片、泄露、溢出有什么区别?

内存片的概念?

什么是mack地址?

什么是内存大小端?如何测试大端?

什么是原子操作?

算法

冒泡排序的思想?

知道那些排序算法?简单描述一下选择排序的思想。

什么是时间复杂度/常用的排序算法

冒泡排序和快速排序那种更好?

快速排序稳定吗?

不想遍历元素但是想找到某些特定元素怎么实现?

冒泡排序和快速排序那种更稳定?什么是稳定?

冒泡排序和快速排序的时间复杂度?

插入法排序的概念

命令

查看网络状态用什么命令?

查进程用什么命令?

用过哪些进程相关命令?

使用进程和网络相关的命令有哪些?

与文件相关的命令有哪些?

GDP常用的命令有哪些?

linux常用的命令功能?

熟悉那些进程命令?网络命令?查看网卡用什么命令?

列举5个操作进程的命令?

库函数用men1和men2查询有什么区别?

操作

是否可以快速定位段错误?

如何调试段错误?

在Linux操作系统中怎么获得内存的大小?

如何测试内存的大小?

你都用过哪些调试手段(方法)?你知道检测内存泄漏的原理

吗?踩内存是什么(关于越界访问)?越界访问你了解多少?当你

的程序发生越界访问,你怎么调试?

如何利用CPU占用率查看内存信息?

硬件

arm的移植、裁剪、中断处理机制

中断和信号的区别?你知道软中断吗?

那你知道中断上下文吗?那你知道信号吗?你如何使用信号,信

号的处理函数要注意哪些?如果我在信号处理函数中malloc空间

会怎么样?


注意:对于面试八股文我们要理性看待,先理解后记忆方为上策。

c语言

1.关键字

  • static

一、静态局部变量

延长局部变量的生命周期,当在函数内部声明一个局部变量为static时,这个变量的生命周期会从定义开始一直持续到程序结束,而不是仅在函数执行期间存在,且只会被初始化一次。

二、静态全局变量

  1. 限制变量的作用域,静态全局变量只能在定义它的源文件中被访问,其他源文件无法直接访问。
  2. 避免命名冲突   - 当多个源文件中可能有相同名称的全局变量时,使用静态全局变量可以避免命名冲突问题。

三、静态函数

1. 限制函数的作用域
   - 静态函数只能在定义它的源文件中被调用,其他源文件无法直接调用。

2. 封装内部实现 - 对于一些不希望被其他源文件访问的辅助函数,可以声明为静态函数,以提高代码的封装性和可维护性。

  • extern

在 C 语言中,extern关键字主要用于声明外部变量和函数,以便在一个文件中使用在其他文件中定义的变量和函数。以下是其具体用法:

一、声明外部变量

二、声明外部函数

  1. 跨文件调用函数
  2. 库函数的使用

  • const

一、修饰变量

 1. 定义常量

- 用`const`修饰的变量在程序运行过程中其值不能被改变,类似于常量。

- 例如: const int MAX_VALUE = 100; 

- 这里`MAX_VALUE`在整个程序中都保持为 100,不能被修改。

2. 增强程序的可读性和可维护性

- 通过使用`const`明确标识出某些不应该被修改的值,使其他程序员在阅读代码时能更容易理解这些变量的特殊性质。

3. 避免意外修改

- 可以防止由于错误的代码操作而导致变量被意外修改,提高程序的稳定性和可靠性。

二、修饰指针

 1. `const`修饰指针指向的内容

- 例如:“`const int *ptr`”表示指针`ptr`指向的内容是常量,不能通过`ptr`来修改其指向的整数的值。

- 但指针本身可以指向其他地址。

2. `const`修饰指针本身

- 例如:“`int * const ptr`”表示指针`ptr`本身是常量,一旦初始化后就不能再指向其他地址,但可以通过`ptr`修改其指向的内容。

3. `const`同时修饰指针和指向的内容

- 例如:“`const int * const ptr`”表示指针`ptr`本身和它指向的内容都是常量,既不能修改指向的内容,也不能让指针指向其他地址。

三、修饰函数参数

 1. 保护传入的参数不被函数内部修改

- 当函数参数是指针或引用类型时,使用`const`修饰可以确保函数内部不会意外修改传入的参数。 - 例如: void printValue(const int *ptr) { printf("%d\n", *ptr); // 这里不能修改 *ptr 的值 } 

2. 提高函数的通用性和可维护性

- 使函数能够接受常量和非常量的参数,同时明确表明函数不会修改传入的参数,增强了代码的可读性和可信赖性。

四、修饰函数返回值

 1. 返回常量值

- 当函数返回值被`const`修饰时,表示返回的是一个常量值,不能通过这个返回值来修改其指向的内容(如果是指针类型的返回值)。

- 例如:  const int *getAddress() { static int value = 10; return &value; } 

- 通过这种方式可以限制对函数返回的指针所指向内容的修改。

2. 增强函数返回值的安全性

- 防止意外修改函数返回的值,尤其是在返回指针或引用类型时,有助于提高程序的稳定性。

  • Volatile

1. 确保变量的可见性:

- 在多线程环境中,每个线程都有自己的工作内存(缓存),线程对变量的修改可能不会立即同步到主内存,其他线程也可能无法及时看到该修改。而使用`volatile`修饰的变量,当一个线程修改了该变量的值后,其他线程能够立即看到这个修改,保证了变量在多线程间的可见性。 - 例如,两个线程同时操作一个`volatile`修饰的共享变量,当一个线程修改了该变量的值,另一个线程能够及时获取到最新的值,而不是使用之前缓存中的旧值。

2. 防止编译器优化:

- 编译器为了提高程序的执行效率,可能会对代码进行优化。在一些情况下,这种优化可能会导致程序出现错误。如果一个变量被`volatile`修饰,编译器会严格按照代码的顺序对该变量进行读写操作,不会对其进行优化。

- 例如,在一个循环中不断读取某个变量的值,如果该变量没有被`volatile`修饰,编译器可能会认为变量的值在循环过程中不会改变,从而只读取一次变量的值并将其缓存起来,后续的循环中直接使用缓存的值。但如果该变量的值可能在循环过程中被其他线程或外部因素修改,那么这种优化就会导致程序出现错误。使用`volatile`修饰该变量后,编译器会在每次循环中都重新读取变量的值,保证程序的正确性。

3. 用于硬件相关的编程:

- 在与硬件交互的程序中,硬件寄存器的值可能会随时发生变化,例如在嵌入式系统中,硬件设备的状态可能会不断改变,对应的寄存器的值也会随之变化。使用`volatile`修饰这些与硬件寄存器相关的变量,可以确保程序能够正确地读取和写入硬件寄存器的值。

- 例如,当读取一个传感器的数据时,传感器的值可能会不断变化,使用`volatile`修饰对应的变量可以保证程序每次读取到的都是最新的值。

总之,`volatile`关键字在 C 语言中是一个非常重要的关键字,它可以保证程序在多线程环境、与硬件交互等情况下的正确性。但是,过度使用`volatile`关键字可能会降低程序的性能,因此应该根据实际情况谨慎使用。

2.指针/数组

  • 在C中,传进一个数组之后,自定义一个函数,行参的使用和数组使用的注意事项 数据区放什么,有多大?

一、行参的使用

 1. 数组作为参数的形式

- 可以直接使用数组名作为参数传递给函数,也可以使用指针来接收数组参数。

- 例如:  void function(int arr[], int size); void function(int *arr, int size);

 - 这两种形式在函数内部的使用方式是相同的。

2. 传递数组大小

- 由于在 C 语言中,数组作为参数传递时会退化为指针,所以函数无法直接知道数组的大小。通常需要额外传递一个参数来表示数组的大小。

- 例如:  void printArray(int arr[], int size) { for (int i = 0; i < size; i++) { printf("%d ", arr[i]); } printf("\n"); }  

二、数组使用的注意事项

 1. 不要越界访问

- 在函数内部使用数组时,要确保访问的下标在合法范围内,避免越界访问导致未定义行为。

- 例如:  void processArray(int arr[], int size) { for (int i = 0; i <= size; i++) { // 错误,可能越界访问 // 操作数组元素 } }

2. 注意数组的存储方式

- C 语言中的数组在内存中是连续存储的,这意味着可以通过指针算术来访问数组中的元素。

- 例如:  void accessArrayElements(int arr[], int size) { int *ptr = arr; for (int i = 0; i < size; i++) { printf("%d ", *(ptr + i)); } printf("\n"); }

三、数据区和大小

 1. 数据区的位置

- 局部数组通常存储在栈上,而全局数组和静态数组存储在数据段中。动态分配的数组(使用`malloc`等函数)存储在堆上。

- 例如:  // 全局数组 int globalArray[10]; int main() { // 局部数组 int localArray[5]; // 动态分配的数组 int *dynamicArray = (int *)malloc(8 * sizeof(int)); return 0; }

 2. 大小限制

- 栈的大小通常是有限的,不同的操作系统和编译器可能有不同的限制。如果局部数组过大,可能会导致栈溢出错误。

- 数据段的大小也有限制,但通常比栈的空间大一些。

- 堆的大小通常可以通过操作系统进行调整,但过度分配可能会导致内存耗尽。 总的来说,在 C 语言中使用数组作为函数参数时,要注意正确传递数组大小,避免越界访问,并了解数组在不同数据区的存储方式和大小限制,以确保程序的正确性和稳定性。

  • 在C语言中什么时候用二级指针?

一、作为函数参数传递指针的地址

 1. 修改指针的值

- 当需要在函数内部修改指针本身(而不是指针所指向的值)时,可以使用二级指针作为函数参数。

2. 动态分配多维数组

- 在动态分配二维或更高维数组时,通常需要使用二级指针或更高阶的指针。

二、处理复杂的数据结构

 1. 链表和树等数据结构

- 在链表中,每个节点通常包含一个指向下一个节点的指针。如果要修改链表的头指针,就需要传递头指针的地址,即二级指针。

 - 在二叉树等更复杂的数据结构中,也可能需要使用二级指针来修改树的根节点等关键指针。

2. 函数返回多个值

- 可以使用二级指针作为函数的参数,让函数通过修改二级指针所指向的指针来返回多个值。

总之,二级指针在 C 语言中主要用于需要修改指针本身、处理复杂数据结构以及实现一些特殊的编程需求的场景。使用二级指针时要小心内存管理,确保正确地分配和释放内存,以避免内存泄漏和悬空指针等问题。

  • 怎么定义一个整形5个元素的数据指针

在 C 语言中,可以使用以下方式定义一个指向包含 5 个整数元素的数组的指针: 

int (*ptr)[5];

这里`ptr`是一个指针,它指向一个包含 5 个整数的数组。

例如,可以这样使用这个指针:

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int (*ptr)[5] = &arr;

    for (int i = 0; i < 5; i++) {
        printf("%d ", (*ptr)[i]);
    }

    return 0;
}

在这个例子中,定义了一个包含 5 个整数的数组`arr`,然后定义了指针`ptr`并让它指向这个数组。通过`(*ptr)[i]`的方式可以访问数组中的元素。

  • strcopy strncopy有什么区别

一、函数原型及功能概述

 1. `strcpy`函数

- 原型:`char *strcpy(char *dest, const char *src)`。

- 功能:将源字符串`src`复制到目标字符串`dest`,直到遇到源字符串中的空字符'\0'为止,并且会在目标字符串的末尾自动添加一个空字符'\0'以确保目标字符串是一个以空字符结尾的字符串。

2. `strncpy`函数

- 原型:`char *strncpy(char *dest, const char *src, size_t n)`。

- 功能:将源字符串`src`中的最多`n`个字符复制到目标字符串`dest`。如果源字符串的长度小于`n`,则在目标字符串中填充空字符'\0'直到复制了`n`个字符为止。如果源字符串的长度大于或等于`n`,则目标字符串不会以空字符结尾。

二、使用场景差异

 1. `strcpy`

- 适用于需要完整复制一个以空字符结尾的字符串的情况,当确定源字符串是一个合法的以空字符结尾的字符串且目标字符串有足够的空间容纳源字符串时,可以安全使用。

2. `strncpy`

- 当需要控制复制的字符数量以防止缓冲区溢出时非常有用,特别是在处理可能包含不可预知长度的字符串或者需要截断字符串时。

三、安全性考量

 1. `strcpy`

- 由于不限制复制的字符数量,如果目标字符串的空间不足,可能会导致缓冲区溢出,这是一种非常危险的安全漏洞,可能被恶意利用来执行任意代码。

- 例如:如果目标字符串的长度小于源字符串的长度,`strcpy`会继续复制,超出目标字符串的边界,覆盖相邻的内存区域。

2. `strncpy`

- 虽然可以通过指定复制的字符数量来避免缓冲区溢出,但如果源字符串的长度大于或等于指定的长度`n`,目标字符串可能不会以空字符结尾,这可能会在后续对目标字符串的操作中导致问题,除非手动添加空字符。

- 例如:在使用`strncpy`后,如果没有正确检查目标字符串是否以空字符结尾,可能会导致在使用字符串函数(如`printf`等)时出现不可预期的行为。

总之,在使用这两个函数时,需要根据具体的需求谨慎选择,并注意确保目标字符串有足够的空间和正确的结束标志,以避免潜在的安全问题和错误。

  • malloc中有部分空间没有被覆掉怎么办?

一、确定未覆盖空间的影响

  1. 数据完整性考量
    • 如果未覆盖的空间中可能包含敏感信息,如密码、个人数据等,那么这可能会导致安全风险。例如,在一个处理用户数据的程序中,如果分配的内存区域未被完全覆盖,旧的数据可能会被意外泄露。
    • 如果未覆盖的空间不会影响程序的正常功能和数据完整性,可以暂时忽略。但在一些对内存使用要求严格的场景,如嵌入式系统或安全关键型应用中,即使是少量未覆盖的空间也可能需要被妥善处理。

二、处理未覆盖空间的方法

在使用malloc分配内存后,可以立即使用memset等函数对内存进行初始化,将所有字节设置为特定的值,通常是 0。

  • 指针数组和数组指针有什么区别?

指针数组是数组,数组指针是指针

  • 如何在C语言中定义一个能够变长的数组空间?

1.使用动态内存分配(malloc 和 free)

2.使用可变长度数组(VLA,C99 特性)

3.使用链表等数据结构

3.预编译

  • if not define一般有啥用

1.防止头文件重复包含

2.条件编译

  • 包头文件“”和<>有啥区别?

    1.尖括号(<>):当使用尖括号包含头文件时,编译器会首先在预定义的标准头文件搜索路径中查找头文件。这些搜索路径通常包括编译器安装目录下的包含文件目录等。

    2.引号(“”):当使用引号包含头文件时,编译器会首先在当前源文件所在的目录中查找头文件,如果没有找到,再按照预定义的搜索路径进行查找。

文件IO

1.目录

  • 目录操作流程及函数名字

1.mkdir  :  int mkdir(const char *pathname, mode_t mode);

2.rmdir  :    int rmdir(const char *pathname);

3.getcwd :    char *getcwd(char *buf, size_t size);

4.chdir  :  int chdir(const char *path);

  • 目录的遍历怎么实现?

opendir   :

DIR *opendir(const char *name);

readdir   :

struct dirent *readdir(DIR *dirp);

closedir  :

int closedir(DIR *dirp);

2.文件

  • 知道哪几种IO模型?

一、阻塞 I/O(Blocking I/O)

 1. 工作原理

- 当进程调用一个 I/O 操作时,如果数据尚未准备好,进程会被阻塞,进入等待状态,直到数据准备好并且 I/O 操作完成后,进程才会被唤醒继续执行。

- 例如,在进行文件读取操作时,如果文件中的数据还没有被操作系统加载到内存中,调用`read`函数的进程会被阻塞,直到数据可以被读取为止。

2. 特点

- 简单易懂,编程模型直观。

- 但是在 I/O 操作期间,进程无法进行其他任务,导致资源利用率低,特别是在处理大量并发 I/O 请求时性能较差。

二、非阻塞 I/O(Non-blocking I/O)

 1. 工作原理

- 当进程发起一个 I/O 操作时,如果数据尚未准备好,`read`、`write`等系统调用会立即返回一个错误码,表示数据不可用。进程不会被阻塞,而是可以继续执行其他任务,并不断地轮询检查 I/O 操作是否就绪。

- 例如,在网络编程中,使用非阻塞套接字时,如果没有数据可读,`recvfrom`函数会立即返回`EWOULDBLOCK`或`EAGAIN`错误,表示当前没有数据可读,但进程不会被阻塞,可以继续执行其他代码,并在稍后再次尝试读取数据。

2. 特点

- 进程不会因为 I/O 操作而长时间阻塞,可以在等待 I/O 完成的同时执行其他任务,提高了资源利用率。

- 但是需要不断地轮询检查 I/O 状态,会消耗较多的 CPU 资源,尤其是在 I/O 操作需要较长时间才能完成的情况下,轮询的效率会很低。

三、I/O 多路复用(I/O Multiplexing)

 1. 工作原理

- 使用一个线程或进程同时监视多个文件描述符(如套接字、文件等),当其中任何一个文件描述符就绪(可读、可写或有异常情况)时,就可以进行相应的 I/O 操作。

- 常见的 I/O 多路复用技术有`select`、`poll`和`epoll`(Linux 系统)等。例如,使用`select`函数时,进程将一组文件描述符传递给`select`,`select`会阻塞进程,直到其中至少一个文件描述符就绪,然后进程可以对就绪的文件描述符进行 I/O 操作。

2. 特点

- 可以同时处理多个 I/O 操作,减少了线程或进程的数量,提高了系统的资源利用率。

- 相比非阻塞 I/O 的轮询方式,I/O 多路复用在处理大量并发连接时更加高效,因为它只需要在一个线程或进程中进行阻塞等待,而不是每个连接都使用一个线程进行轮询。

四、信号驱动 I/O(Signal-Driven I/O)

 1. 工作原理

- 进程首先通过系统调用注册一个信号处理函数,然后发起一个 I/O 操作并立即返回。当数据准备好时,操作系统会发送一个信号给进程,进程在信号处理函数中进行 I/O 操作。

- 例如,在网络编程中,使用信号驱动 I/O 的套接字时,进程注册一个信号处理函数,当有数据可读时,操作系统会发送一个信号通知进程,进程在信号处理函数中调用`recvfrom`函数读取数据。 2. 特点

- 进程在等待 I/O 操作完成时不会被阻塞,可以继续执行其他任务。

- 但是信号处理函数的编写相对复杂,并且信号可能会出现丢失或重复的情况,需要额外的处理来确保 I/O 操作的正确性。

五、异步 I/O(Asynchronous I/O)

1. 工作原理

- 进程发起一个异步 I/O 操作后立即返回,操作系统在后台完成 I/O 操作,当 I/O 操作完成后,操作系统会通知进程。进程可以在等待 I/O 完成的同时执行其他任务,无需主动检查 I/O 状态。

- 例如,在支持异步 I/O 的操作系统中,使用异步文件读取操作时,进程发起一个读取请求后继续执行其他任务,当操作系统完成读取操作后,会通过回调函数、信号或其他方式通知进程,进程可以在回调函数中处理读取到的数据。

2. 特点

- 真正实现了 I/O 操作与进程的完全异步,最大限度地提高了系统的并发性能和资源利用率。

- 但是异步 I/O 的实现相对复杂,需要操作系统的支持,并且编程模型相对较难理解和掌握。

  • 怎么实现文件的拷贝?

标准io/文件io  都行,使用open read write close等

  • 复制文本文件怎么操作

标准io/文件io  都行,使用open read write close等

  • fgets和fputs文件的拷贝是怎么实现的?

一、包含头文件

 需要包含`<stdio.h>`头文件,因为会使用标准输入输出函数。 ```c #include <stdio.h> `

二、打开源文件和目标文件

 1. 使用`fopen`函数以适当的模式打开源文件和目标文件。源文件以只读模式("r")打开,目标文件以写模式("w")打开,如果目标文件不存在,会自动创建;如果存在,会被截断为零长度

三、使用`fgets`和`fputs`进行拷贝

 1. `fgets`函数用于从源文件中读取一行文本,它会读取最多`n - 1`个字符(其中`n`是指定的缓冲区大小),直到遇到换行符或文件结束标志。如果成功读取一行文本,`fgets`会返回指向缓冲区的指针;如果到达文件末尾或发生错误,返回`NULL`。

2. `fputs`函数用于将一行文本写入目标文件,它会将字符串写入文件,直到遇到空字符'\0'为止。如果写入成功,`fputs`会返回一个非负值;如果发生错误,返回`EOF`。 

四、关闭文件 完成拷贝后,使用`fclose`函数关闭源文件和目标文件,释放资源。 

 通过以上步骤,就可以使用`fgets`和`fputs`函数实现文件的拷贝。这种方法适用于文本文件的拷贝,对于二进制文件可能不太适用,因为`fgets`和`fputs`在处理二进制文件时可能会出现问题。在处理二进制文件时,可以使用`fread`和`fwrite`函数进行拷贝。

  • IO学了什么?

    一、文件操作

    文件的打开与关闭

    • 学会使用函数如 fopenopen(低级 I/O)等打开文件,并在操作完成后使用 fcloseclose 正确关闭文件,以确保资源的合理释放和数据的完整性。
    • 理解不同的打开模式,如只读、只写、读写等,以及如何处理文件不存在或已存在的情况。

    文件的读写

    • 掌握使用函数如 freadfwritefgetsfputs 等进行文件的读取和写入操作。了解如何读取不同类型的数据,如字符、字符串、结构体等,以及如何逐行读取文本文件。
    • 对于二进制文件和文本文件的读写有不同的处理方式,学会区分并正确使用相应的函数。

    文件的定位与随机访问

    • 了解如何使用 fseekftell 等函数在文件中进行定位,实现随机访问文件的特定位置。这对于处理大型文件或需要快速访问特定数据的情况非常有用。

    二、标准输入输出

  • stdio 库的使用


    熟悉标准输入(stdin)、标准输出(stdout)和标准错误输出(stderr)的概念和使用方法。学会使用 printfscanf 等函数进行格式化的输入输出操作。 理解缓冲区的概念以及如何刷新缓冲区,以确保数据及时输出或输入。

    重定向与管道

    了解如何在命令行中使用重定向(< 和 >)和管道(|)来改变标准输入输出的流向,实现不同程序之间的数据传递和处理。

    三、I/O 模型

    阻塞与非阻塞 I/O

    理解阻塞 I/O 中进程在进行输入输出操作时会被阻塞,直到操作完成;非阻塞 I/O 中进程不会被阻塞,可以继续执行其他任务,但需要不断检查 I/O 状态。 学会在不同的应用场景中选择合适的 I/O 模型,以提高程序的性能和响应性。

    异步 I/O

    了解异步 I/O 的概念和实现方式,即进程发起 I/O 操作后立即返回,操作系统在后台完成操作并通知进程。 认识到异步 I/O 在提高系统并发性能和资源利用率方面的潜力,但也意识到其实现的复杂性。
    • 理解 I/O 多路复用在处理大量并发连接时

http://www.kler.cn/news/359948.html

相关文章:

  • 二叉树遍历(前序、中序、后续)
  • OpenCV高级图形用户界面(14)交互式地选择一个或多个感兴趣区域函数selectROIs()的使用
  • 【大模型实战篇】大模型分词算法Unigram及代码示例
  • 【进阶OpenCV】 (11)--DNN板块--实现风格迁移
  • 电动汽车嵌入式软件开发过程中的难题有哪些?
  • JavaGuide(10)
  • commonjs和esmodule的导入导出细节
  • opencv实战项目(三十二):opencv汽车360全景影像制作
  • 【嵌入式软件-STM32】STM32外设
  • 常用数据库获取表,视图,列,索引信息
  • AndroidStudio移动开发:使用Service播放音乐【步骤】
  • 【分布式微服务云原生】《Redis RedLock 算法全解析:应对时钟漂移与网络分区挑战》
  • Python异常检测-3Sigma
  • exchange_proxy exchange 安全代理
  • SqlDbx连接oracle(可用)
  • PDF.js的使用及其跨域问题解决
  • 力扣244题详解:最短单词距离 II 的多种解法与模拟面试
  • 携手并进,智驭教育!和鲸科技与智谱 AI 签署“101 数智领航计划”战略合作协议
  • Apache Doris简介
  • Items View 项目视图