绿盟校招C++研发工程师一面复盘

绿盟校招C++研发工程师一面复盘

  1. 进程间通信方式中的共享内存为何比套接字快呢?共享内存的核心是让多个进程映射同一块物理内存到各自的虚拟地址空间,通信过程完全绕开内核的中转干预。而套接字会触发用户态到内核态的切换。用户态与内核态的切换,需要保存、恢复进程上下文,这是操作系统的核心开销之一,套接字的每一次send()/recv()都是系统调用,都要经历用户态->内核态->用户态的切换。共享内存无协议开销,数据是直接写入内存的原始字节流,无需封装任何协议头、无需计算校验和、无需处理拥塞控制,CPU开销极低。
  2. 线上CPU飙升如何排查?
    • 首先确认是哪个进程占用CPU过高,登录服务器利用top命令查看各个进程的资源占用情况
    • 确认CPU利用率很高的进程PID,假设1234为某个进程,则通过top -Hp 1234查看具体的线程
    • 假设得到的线程ID是5678,再将线程ID转化为十六进制,得到十六进制的tid162e,此时利用jstack 1234 | grep 162e -A 100查看具体的栈信息。jstack命令用于生成当前时刻的线程快照。线程快照是当前每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因。
    • 根据堆栈信息就可以定位到具体是哪行代码导致CPU飙升,对应修复即可。
  3. 高并发设计,如何做限流呢?说一说你知道的限流算法限流是限制到达系统的并发请求数,使系统能够正常的处理部分用户的请求,来保证系统的稳定性。限流的本质是因为后端处理能力有限,需要截掉超过处理能力之外的请求,亦或是为了负载均衡客户端对服务端资源的公平调用,防止一些客户端饿死。计数限流:每次请求到来时候对计数器进行计数,如果超过阈值就拒绝。固定窗口限流:每次请求来,计数器加一,超过阈值,拒绝访问。窗口时间到了,计数器清零。滑动窗口限流:主要解决固定窗口在临界时间时,重置计数器,导致下一次窗口涌入大量请求。为每个请求增加一个到达时间,其实就是把时间作为区间记录当前区间的请求数是否小于阈值。漏桶算法:水滴(请求)持续滴入漏桶中,底部定速流出(处理请求)。桶满拒绝。令牌桶算法:定速往桶里塞入令牌,请求只有拿到令牌才能通过,之后再被服务器处理。桶满丢令牌。

为什么拷贝构造函数使用引用传递而不是值传递?首先明确拷贝构造函数是C++中一种特殊的构造函数,作用是:用一个已存在的同类对象,初始化一个全新的同类对象。语法原型:

// 正确写法:const 引用传递A(const A& other);

在拷贝构造函数中使用值传递会触发无限递归,导致程序崩溃,这是最根本、最核心的原因。如果拷贝构造函数的参数写成值传递A(A other),程序编译运行阶段一定会触发无线递归,最终因栈溢出崩溃。为什么值传递会触发无限递归?先记住一个C++铁律

C++中,所有函数值传递参数,在函数被调用时,编译器都会自动为这个参数创建一个临时拷贝副本

在拷贝的过程中,不是简单的内存复制,而是严格调用对应类型的拷贝构造函数来完成的。假设我们把拷贝构造函数写成值传递版本

classA{public:// 错误写法:拷贝构造函数 采用 值传递A(A other){// 构造逻辑}};

当我们在代码中,尝试用一个已存在的A对象a1,创建新对象a2时:A a2(a1);,会触发如下无限循环的调用过程:

执行A a2(a1);,需要调用拷贝构造函数 A(A other); | V 该函数的参数是值传递,编译器必须为参数other创建临时拷贝副本,这个副本的数据源是a1, | V 要创建other这个A类型的副本,就必须再次调用A类型的拷贝构造函数 | V 新的拷贝构造函数调用,参数还是值传递,编译器又要为新的参数创建临时副本,再次调用拷贝构造函数 这个过程会无限循环下去,没有任何终止条件 每一次函数调用都会占用栈内存,最终栈内存耗尽,程序触发栈溢出错误并崩溃 

为什么引用传递可以完美解决这个问题呢?这是因为C++的引用本质上是原对象的一个别名,它不是一个独立的对象,也不占用新的内存空间,没有拷贝操作就不会触发额外的拷贝构造函数调用,彻底断了递归地源头。为什么要加const?多出来的const不是可有可无的,而是语法规范加逻辑严谨性的双重要求。如果参数只写A& other(非 const 引用),那么我们无法用「const 修饰的常量对象」 来创建新对象,编译器会直接报错。比如:

const A a1; A a2(a1);// 编译报错!非const引用 无法绑定到 const对象

const A& other常量引用,它的语法规则是:可以绑定到 普通对象、const 常量对象、临时匿名对象,兼容性拉满,不会有任何编译问题。拷贝构造函数的核心语义是:「复制原对象的内容,创建一个新对象」,这个过程中,原对象的状态绝对不应该被改变。加上const修饰后,编译器会做「语法强校验」:如果我们在拷贝构造函数内部,不小心写了修改other的代码(比如other.num = 10;),编译器会直接报错,从语法上杜绝了误修改原对象的可能,保证代码的健壮性。此外,值传递会存在内存开销数据拷贝开销两个问题。

Read more

【Linux】Linux 开发必备:信号处理时机 + 中断向量表 + 系统调用表,内核态切换核心知识点

【Linux】Linux 开发必备:信号处理时机 + 中断向量表 + 系统调用表,内核态切换核心知识点

前言:欢迎各位光临本博客,这里小编带你直接手撕**,文章并不复杂,愿诸君**耐其心性,忘却杂尘,道有所长!!!! IF’Maxue:个人主页  🔥 个人专栏: 《C语言》 《C++深度学习》 《Linux》 《数据结构》 《数学建模》 ⛺️生活是默默的坚持,毅力是永久的享受。不破不立! 文章目录 * Linux信号处理时机与内核态/用户态深度解析 * 一、信号处理的“合适时机”是什么? * 合适的实际? * 结合课件 * 1.1 信号处理的触发时机 * 1.2 信号检查与处理流程 * 1.3 不同处理动作的差异 * 1.4 自定义捕捉的身份切换细节 * 二、硬件中断:OS运行的“驱动力” * 2.1 硬件中断的基本原理 * 2.

By Ne0inhk
Flutter 三方库 df_generate_dart_models_core 的鸿蒙化适配指南 - 实现自动化的数据模型代码生成、支持 JSON 反序列化模板定义与工程化规范一致性

Flutter 三方库 df_generate_dart_models_core 的鸿蒙化适配指南 - 实现自动化的数据模型代码生成、支持 JSON 反序列化模板定义与工程化规范一致性

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 df_generate_dart_models_core 的鸿蒙化适配指南 - 实现自动化的数据模型代码生成、支持 JSON 反序列化模板定义与工程化规范一致性 前言 在进行 Flutter for OpenHarmony 的大规模业务逻辑开发时,手动编写海量的 Data Models(POJO/Entity)以及配套的 fromJson/toJson 方法不仅枯燥乏味,还极易引入手写错误。df_generate_dart_models_core 是一个强大的代码生成核心库,它能将原始 JSON 样本或 Schema 自动转化为符合 Dart 规范的数据类代码。本文将指导大家如何将该库集成到鸿蒙项目的工程化提效链路中。 一、原理解析

By Ne0inhk
Flutter 三方库 username_gen 的鸿蒙化适配指南 - 实现具备语义化特征的随机用户名自动化生成、支持端侧快速原型开发与测试数据模拟实战

Flutter 三方库 username_gen 的鸿蒙化适配指南 - 实现具备语义化特征的随机用户名自动化生成、支持端侧快速原型开发与测试数据模拟实战

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 username_gen 的鸿蒙化适配指南 - 实现具备语义化特征的随机用户名自动化生成、支持端侧快速原型开发与测试数据模拟实战 前言 在进行 Flutter for OpenHarmony 的社交原型开发、内部压力测试或注册流程的兜底模拟时,如何快速产生大量、易读且不重复的用户名?手动硬编码 "test_user_1" 显然过于僵硬且不具备真实感。username_gen 是一款专注于基于形容词与名词组合建立“有趣”用户名的轻量级库。本文将探讨如何在鸿蒙端构建极致、敏捷的模拟数据填充体系。 一、原直观解析 / 概念介绍 1.1 基础原理 该库内置了一套精选的英文形容词库与名词库。通过洗牌算法(Shuffle)与自定义后缀注入逻辑,能在毫秒级产出符合 "AdjectiveNPC"

By Ne0inhk
Linux网络 | 网络计算器客户端实现与Json的安装以及使用

Linux网络 | 网络计算器客户端实现与Json的安装以及使用

前言:本节讲述序列化和反序列化的相关内容。 这节的内容是博主前一篇博客的续章, 里面用到了很多知识点都是前一篇文章的。 友友们如果要学习序列化反序列化, 直接看本篇文章是看不懂的, 请看前一篇文章:linux网络 | 序列化反序列化的概念 与 结合网络计算器深度理解-ZEEKLOG博客         前一篇文章内容除了概念以外, 主要是利用序列化反序列化的知识点实现了一个网络计算器的服务端。 然后本节内容来实现以下客户端, 让服务端能够与客户端连接起来, 实现计算器的功能。 另外, 本节内容还会使用一下Json, 这是一个序列化反序列化解决方案,以后我们就不用自己手搓序列化反序列化了。          ps:本节内容友友们务必看完前上面的文章链接的文章哦!  目录 ClientCal实现 命令行参数 connect 准备工作  write  read  Json的使用 运行结果 ClientCal实现 命令行参数         客户端同样要有命令行参数: int main(int argc, char* argv[]) {

By Ne0inhk