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

C/C++ 面试复习笔记(2)

C语言如何实现快速排序算法?

  • 答案:快排是一种分治算法,选择一个基准元素,将数据划分成两部分,然后递归排序

  • 补充:

void quick_sort(int arr[], int start, int end)
{//判断是否需要排序if (start >= end){return;}
​int left = start;int right = end;int pivot = arr[left];  //基准值while (left < right){//实现大于基准值的数字放到左边while ((arr[right] > pivot) && (left < right)){right--;}if (left < right){arr[left] = arr[right]; //将基准值填入left++;}//实现小于基准值的数字放到右while ((arr[left] < pivot) && (left < right)){left++;}if (left < right){arr[right] = arr[left]; //将基准值填入right--;}arr[left] = pivot;}//递归排序quick_sort(arr, start, left - 1);quick_sort(arr, right+1, end);
}

C语言中的setvbuf函数作用是什么?

  • 答案:setvbuf 用于设置文件流的缓冲区模式和大小,优化文件读写的性能。

  • 解析:setvbuf 可以设置缓冲区类型(如全缓冲、无缓冲、行缓冲),并定义缓冲区的大小, 适用于文件流的优化。

  • 补充:

缓冲区的类型

缓冲区分为三种类型:全缓冲、行缓冲和不缓冲。

1、全缓冲

在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写。

2、行缓冲

在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是键盘输入数据。

3、不缓冲

也就是不进行缓冲,标准出错情况stderr是典型代表,这使得出错信息可以直接尽快地显示出来。

缓冲区的刷新

下列情况会引发缓冲区的刷新:

  1. 缓冲区满时;

  2. 执行fflush函数;

  3. 正常关闭文件。

  4. 正常退出程序或进程。

  5. 行缓冲遇到 \n刷新。

如何改变缓存类型

//与缓冲区相关的一些函数
#include <stdio.h>
void setbuf(FILE *stream, char *buf);
void setbuffer(FILE *stream, char *buf, size_t size);
void setlinebuf(FILE *stream);
​
​
int setvbuf(FILE *stream, char *buf, int mode , size_t size);
参数:
stream:这是指向 FILE 对象的指针,该 FILE 对象标识了一个打开的流。
buffer:这是分配给用户的缓冲。如果设置为 NULL,该函数会自动分配一个指定大小的缓冲。
mode: 这指定了文件缓冲的模式:_IOFBF、_IOLBF、_IONBF。
size:这是缓冲的大小,以字节为单位。
返回值:
如果成功,则该函数返回 0,否则返回非零值。

VScode中的stdout属于无缓冲类型

Ubuntu中的stdout属于行缓冲类型(行缓冲遇到换行符会清空缓冲区,而全缓冲不会)

解释C语言中的volatile关键字并给出应用场景。

  • 答案:volatile 告诉编译器,该变量的值可能随时被外部因素改变,因此禁止优化该变量的读取和写入。

  • 解析:volatile 常用于多线程或硬件寄存器操作等场景,确保每次读取变量时都从内存中获取最新值,避免编译器优化。

  • 补充:

  1. volatile 的作用

    • 禁止优化:编译器通常会对变量进行优化,以提高程序的运行效率。例如,如果某个变量在代码中多次赋值,但是值没有改变,编译器可能会认为这个变量不再被使用,从而优化掉一些访问该变量的代码。但是,当变量是 volatile 类型时,编译器不会做这种优化,确保每次访问变量时都进行实际的读取或写入操作。

    • 外部改变volatile 修饰的变量通常表示该变量的值可以在程序的执行过程中被外部因素(如硬件设备或其他线程)改变。

  2. 常见的应用场景

    • 硬件寄存器:在嵌入式系统编程中,硬件设备的寄存器可能会随时被硬件更改。为了保证对这些寄存器的访问不会被优化掉,通常会用 volatile 修饰寄存器变量。

    • 多线程编程:在多线程程序中,如果一个线程在修改某个变量,而其他线程正在读取该变量,使用 volatile 修饰该变量可以确保每个线程读取到变量的最新值。

如何判断一个链表是否有环?

bool has_cycle(struct ListNode *head) { struct ListNode *slow = head, *fast = head; while (fast && fast->next) { slow = slow->next; fast = fast->next->next; if (slow == fast) return true; } return false; 
} 

如何实现一个 LRU 缓存(Least Recently Used Cache)?

  • 答案:使用双向链表和哈希表结合来实现。哈希表提供快速的访问,双向链表维护访问顺序,当缓存满时,删除最久未使用的元素。

  • 解析:使用双向链表存储数据,哈希表存储键和节点的映射。每次访问数据时,将对应节点移到链表的头部。若缓存满了,删除链表尾部节点。

如何实现一个线程安全的计数器?

  • 答案:使用互斥锁(mutex) 或原子操作来确保多个线程同时访问时不会产生竞态条件。

  • 解析:使用pthread mutex_ t来加锁计数器的修改操作,确保线程安全。也可以使用原子操作(如atomic)来避免锁的开销。

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 
int counter = 0; 
void increment() { pthread_mutex_lock(&lock); counter++; pthread_mutex_unlock(&lock); 
} 
  • 补充:

std::atomic 是 C++ 提供的一种用于多线程编程的同步原语,保证对数据类型的操作是原子的,即不会被中断或与其他线程产生冲突。它适用于需要在线程之间共享数据而不需要加锁的场景,提供比传统的锁(如 std::mutex)更好的性能。

常用场景 std::atomic 通常用于以下情况:

共享资源的安全访问:在多线程程序中,多个线程需要访问和修改同一变量。 避免锁机制的开销:锁会带来性能上的开销,而 std::atomic 提供了更轻量的原子操作。 简单的同步:当仅需要单个变量的同步时,使用 std::atomic 是非常高效的。

std::atomic 支持的类型 内置基础类型:如 int, bool, char, float, double 等。 自定义类型:可以将自定义结构体/类声明为 std::atomic<T>,但必须保证其满足 "trivially copyable"(平凡可拷贝)要求,即没有自定义构造、析构、拷贝构造和赋值运算符等。

#include <iostream>
#include <atomic>
#include <thread>
​
std::atomic<int> counter(0); // 初始化原子计数器
​
void increment() {for (int i = 0; i < 10000; ++i) {counter.fetch_add(1, std::memory_order_relaxed); // 原子增加}
}
​
int main() {std::thread t1(increment);std::thread t2(increment);
​t1.join();t2.join();
​std::cout << "Final counter value: " << counter << std::endl; // 输出最终的计数器值
​return 0;
}

http://www.xdnf.cn/news/10065.html

相关文章:

  • 漫画Android:事件分发的过程是怎样的?
  • JS数组 concat() 与扩展运算符的深度解析与最佳实践
  • MySQL + CloudCanal + Iceberg + StarRocks 构建全栈数据服务
  • 单元测试报错
  • 由反汇编代码确定结构体的完整声明
  • 调试技巧总结
  • SAP 生产订单收货数量超额报错问题研究
  • 《java创世手记》---java基础篇(上)
  • 【Linux基础知识系列】第五篇-软件包管理
  • Ubuntu本地文件上传github(版本控制)
  • 常见压缩算法性能和压缩率对比 LZ4 LZO ZSTD SNAPPY
  • Haproxy搭建web群集
  • WWW22-可解释推荐|用于推荐的神经符号描述性规则学习
  • 【免费的高清录屏软件】OBS Studio
  • 架构加速-深度学习教程
  • A类地址中最小网络号(0.x.x.x) 默认路由 / 无效/未指定地址
  • Qt中使用正则表达式来提取字符串
  • 第100+41步 ChatGPT学习:R语言实现误判病例分析
  • Windows 权限提升 | TryHackMe | Windows Privilege Escalation
  • html中使用nginx ssi插入html
  • 全志科技携飞凌嵌入式T527核心板亮相OpenHarmony开发者大会
  • 智能守护电网安全:探秘输电线路测温装置的科技力量
  • MySQL高可用集群
  • 《Linux C编程实战》笔记:套接字编程
  • day41 python图像识别任务
  • 【多线程初阶】线程状态 线程安全
  • 进阶智能体实战九、图文需求分析助手(ChatGpt多模态版)(帮你生成 模块划分+页面+表设计、状态机、工作流、ER模型)
  • Ubuntu 安装 FSL 及多模态脑MRI的去颅骨处理(含 HD-BET 深度学习方法)
  • 区域未停留检测算法AI智能分析网关V4打造铁道/工厂/机场等场景应用方案
  • mysql隐式转换会造成索引失效的原因