资讯动态

全面复习1

发布时间:2026/10/3 7:11:12 来源:尧图企业网站定制
http和https的区别是什么HTTP 和 HTTPS 的核心区别是安全性。HTTP 是明文传输HTTPS 是 HTTP 加上 TLS主要有以下区别安全性HTTPS 提供数据加密、完整性校验和服务器身份认证防止数据被窃听、篡改以及服务器被冒充。默认端口HTTP 使用 80HTTPS 使用 443。连接过程HTTPS 需要CA机构的数字证书并进行 TLS 握手因此会增加一定的连接开销。.http也要保证安全的话要怎么设计只能仿照https在应用层做加密和签名并解决安全的密钥分发问题但这仍不能保护全部 HTTP 元信息。”这只能加密业务层数据但 URL 路径、请求方法以及未加密的 Cookie、Token 等请求头仍然可见。仍然可能被他们冒充身份。消息队列了解吗有哪些“了解。消息队列让生产者发送消息、消费者异步处理主要用于异步处理、系统解耦、削峰填谷。比如下单后把发短信的任务放入队列避免阻塞下单流程。常见的消息队列中间件有业务需要灵活的路由分发和低延迟投递消息量不算特别巨大 →RabbitMQ消息量大追求极致吞吐Kafka核心是交易/订单类业务需要保证可靠性 →RocketMQ如果面试官问的是Linux 进程间通信的消息队列则主要有System V 消息队列和 POSIX 消息队列。mysql的like模糊查询能不能走索引“**能但要看有没有固定前缀。**对于普通 B 树索引LIKE abc%有固定前缀可以利用索引做范围扫描LIKE %abc或LIKE %abc%没有固定前缀无法通过这个条件确定索引范围。”“不过后两种也不能说绝对不走索引覆盖索引时可能进行全索引扫描。最终要用EXPLAIN看执行计划range表示范围扫描index表示全索引扫描两者效率不同。除了mysql其他的数据库有没有了解“有一些了解主要是Redis 和 SQLite。Redis 是内存型键值数据库支持多种数据结构也支持持久化常用于缓存、计数器等场景。SQLite 是轻量级的嵌入式关系型数据库不需要单独部署数据库服务比较适合 C 客户端的本地数据存储。目前我主要了解它们的基本用法和适用场景底层实现还没有深入研究。”mysql的隔离级别了解吗有哪些可能出现的问题MySQL 事务隔离级别有 4 种从低到高分别是Read Uncommitted读未提交可能出现脏读、不可重复读、幻读。Read Committed读已提交解决脏读但可能出现不可重复读、幻读。Repeatable Read可重复读MySQL InnoDB 的默认隔离级别。解决脏读和不可重复读InnoDB 大部分场景下也能解决幻读问题。Serializable串行化隔离级别最高事务基本串行执行可以避免前面这些并发问题但并发性能最差。这里几个问题的含义是脏读读到了其他事务还没提交的数据。不可重复读同一个事务里两次查询同一条记录结果不一样。幻读同一个事务里相同条件查询第二次发现多了或少了几条记录。内存级缓存有了解吗了解以CPU 的多级缓存为例主要有 L1、L2、L3越靠近 CPU速度越快、容量越小主要用来减少访问主内存的开销。它利用时间局部性和空间局部性以缓存行为单位加载数据常见缓存行大小是 64 字节。在 C 中连续存储、顺序访问通常更有利于缓存命中比如遍历vector。多线程还要注意伪共享不同核上线程修改同一缓存行里的不同变量也会触发缓存一致性开销影响性能。AI写的代码和你自己写的代码的比例是多少按代码量粗略估计第一个项目AI生成的占30%自己写的占70%。AI主要帮我写测试用例和一提供一些项目优化的想法第二个项目除了前端网页全是我自己实现的。AI生成的代码也必须经过我的理解、审查最终由我负责。对于AI的上下文问题你在使用AI的时候是怎么让AI知道你们之前的聊天的同一个会话里我一般接着原来的对话聊。如果聊天比较长或者要换新会话我会把项目背景、已确定的方案、当前进度和待解决的问题整理成简短摘要连同必要的代码一起提供给AI。摘要可以让AI先生成但我会核对后续有新结论就更新关键约束也会重新强调减少上下文丢失和理解偏差。AI的查找方向有误你是怎么解决的我会先核对AI的判断依据一般结合报错、日志就能知道它哪个部分出现了问题。然后跟ai说你上一步的结果怎么出错我认为咋样让ai重新思考如果仍然分析出错我会自己对应报错审查代码进一步缩小到模块范围让AI辅助检查。简单讲讲线程池线程池就是创建一组可以复用的工作线程统一执行提交的任务避免每来一个任务就创建、销毁线程降低开销同时控制并发数量。核心是任务队列和工作线程提交方把任务放入队列工作线程取出任务执行没有任务时就阻塞等待有新任务再被唤醒。C 中通常用std::thread管理线程用互斥锁保护队列用条件变量实现等待和唤醒。实现时还要注意任务异常处理以及关闭线程池时是执行完剩余任务还是直接取消。. 多线程访问遇到过什么问题是怎么解决的我在服务器项目里遇到过连接对象被多个线程同时操作的问题比如业务线程发送数据时另一个 线程正在关闭连接容易产生数据竞争甚至访问已经释放的对象。我的解决办法是每个连接固定I/O 线程其他线程把发送、关闭等操作投递到任务队列由所属线程串行执行。定时器回调使用weak_ptr因为定时器不应该拖延整个连接的生命周期所以使用weakptr执行前通过lock()获取对象并检查连接状态避免任务线程释放了我这个链接造成悬空访问。在使用这个锁的过程中还有什么需要注意的问题使用std::mutex时我主要注意四点自动释放锁用std::lock_guard管理避免提前返回或抛异常时忘记解锁。缩小临界区只锁必要的共享数据操作避免持锁做耗时操作减少线程等待。避免死锁锁内部不要再次调用锁。同步规则一致同一共享数据的并发读写都要遵守同一套锁保护规则不能有的地方加锁、有的地方漏锁。从C代码到一个可执行文件会经历什么过程从 C 源代码到可执行文件主要经历四个阶段预处理、编译、汇编、链接。预处理展开头文件和宏处理条件编译删除注释生成预处理后的代码。编译进行语法分析检查类型等错误并进行优化生成汇编代码。汇编把汇编代码转换成机器指令生成目标.o文件。此时外部符号的地址可能还没确定。链接把目标文件和所需的库组合起来完成符号解析和地址重定位最终生成可执行文件。define 和 const 的区别处理阶段#define在预处理阶段进行文本替换const由编译器处理。类型检查宏没有类型不做类型检查const定义的对象有类型编译器会进行类型检查。作用域宏不遵守 C 的作用域规则从定义处生效直到#undef或文件结束const遵守正常的作用域规则。因此定义常量时通常优先使用const更安全、便于调试。指针和引用有什么区别指针是指向变量的地址引用是对象的别名。主要有四个区别初始化和空值指针可以为空引用定义时必须绑定对象。能否重新绑定指针可以改变指向引用绑定后不能再绑定其他对象。访问方式指针通过*解引用访问对象引用可以像普通变量一样直接使用。sizeof的含义对指针使用sizeof得到指针本身的大小对引用使用得到被引用对象类型的大小。new 和 malloc 有什么区别new是 C 运算符malloc是 C 标准库函数。主要有四个区别对象初始化new分配内存后会初始化对象对类对象会调用构造函数malloc只分配内存不调用构造函数。大小和类型new根据类型计算所需大小返回对应类型的指针malloc需要指定字节数返回void*在 C 中需要显式转换。分配失败普通new失败时抛出std::bad_allocmalloc失败时返回空指针。释放方式new配合deletenew[]配合delete[]会执行相应的析构malloc配合free不会调用析构函数。对智能指针的了解能指针是对裸指针的封装利用 RAII 自动管理资源在合适的时机释放对象减少手动delete和内存泄漏的风险。现代 C 常用三种unique_ptr独占所有权不能复制但可以通过移动转移所有权。shared_ptr共享所有权通过引用计数管理生命周期最后一个拥有者释放时销毁对象。但相互持有shared_ptr可能造成循环引用导致内存泄漏。weak_ptr不拥有对象不增加强引用计数常用于打破循环引用。使用时通过lock()获取shared_ptr对象已经销毁则返回空指针。weak_ptr 的实现的了解它是怎么解决循环引用的weak_ptr解决循环引用的关键是它观察对象但不拥有对象不增加强引用计数。实现上它通常与shared_ptr共用一个控制块里面维护强、弱引用计数。强引用计数归零时销毁对象控制块会继续保留直到弱引用也全部释放。比如A 和 B 相互用shared_ptr持有即使外部指针都释放了两者仍互相维持引用计数无法析构。把B 对 A 的引用改成weak_ptr就不会阻止 A 销毁A 销毁时释放对 B 的持有B 也就能正常销毁。访问对象时调用lock()对象还存活就得到一个共享所有权的shared_ptr对象已销毁就得到空指针。讲一下你知道的类型转换C 的类型转换分为隐式转换和显式转换。隐式转换由编译器自动完成比如int转double。显式转换主要有四种static_cast常用于数值转换、继承关系中的转换。向下转型时不做运行时类型检查需要自己保证对象类型正确。dynamic_cast用于多态继承体系中的安全向下转型或交叉转换需要基类有虚函数。失败时指针转换返回nullptr引用转换抛出std::bad_cast。const_cast用于添加或去除const、volatile属性。如果对象本来就是const去掉属性后修改它属于未定义行为。reinterpret_cast用于底层类型重解释比如不同指针类型之间的转换但不保证转换后可以安全访问对象。动态转换dynamic_cast是怎么判断这个类型能不能转换为派生类的动态转换dynamic_cast是怎么判断这个类型能不能转换为派生类的对于多态类也就是基类里至少有一个virtual函数对象会关联运行时类型信息。执行dynamic_cast时会根据对象的实际类型以及继承关系判断目标派生类是不是这个对象合法的派生类路径。多态具体表现在哪里C 的多态主要体现在同一个接口不同对象有不同的行为。主要分两种编译时多态函数重载、运算符重载、模板编译阶段就确定调用哪个函数。运行时多态通过继承 虚函数 父类指针/引用指向子类对象实现运行时根据对象的实际类型决定调用哪个函数。对虚函数的了解虚函数主要是用来实现 C 运行时多态的。每 一个含虚函数的类编译器会为它生成一张静态的函数指针数组虚函数表 vtable和虚表指针 vptr实现。同类所有对象共享同一张表派生类会复制基类的表并把自己重写的函数地址替换进去虚表指针指向虚函数表多态调用就是根据虚表指针找到虚函数表调用相应的函数指针纯虚函数有什么好处纯虚函数主要有几个好处定义统一接口基类规定“必须有哪些功能”但不关心具体怎么实现。强制子类实现派生类必须实现纯虚函数否则它本身也是抽象类。支持多态可以通过基类指针或引用调用不同子类的实现实现运行时多态。降低耦合调用方依赖抽象接口不依赖具体实现方便后续扩展和替换。防止基类被直接实例化含纯虚函数的类是抽象类更适合作为接口或基类。对纯虚接口类的了解对纯虚接口类的了解虚接口类就是一个主要由纯虚函数组成的抽象类用来定义统一接口不提供具体业务实现。它的特点是不能直接实例化只能作为基类使用。派生类必须实现纯虚函数否则派生类仍然是抽象类。主要用于实现多态和接口隔离调用方只依赖接口不依赖具体实现。一般会提供一个虚析构函数防止通过基类指针删除派生类对象时出现资源释放问题。使用这种类的过程有没有什么需要注意的地方析构函数必须是虚函数否则通过基类指针释放派生类对象可能出问题。派生类实现接口时建议加override检查是否是多态尽量通过指针或引用使用接口对象避免对象切片。不要在基类构造/析构函数里调用纯虚函数因为这时派生类部分可能还没构造好或已经销毁。内存对齐的理解内存对齐就是数据在内存中的起始地址要满足一定的整数倍规则。主要目的是提高 CPU 访问内存的效率因为 CPU 访问内存时不一定是“想读几个字节就精确读几个字节”底层通常会按一定粒度去访问内存。如果数据是对齐的比如一个 4 字节int正好放在合适的地址上CPU 往往一次内存访问就能拿到。如果没有对齐这个int可能跨两个内存访问边界CPU 可能需要访问两次再把结果拼起来所以效率更低。我理解内存对齐主要有三点成员自身要对齐取数据对齐数和编译器最大对齐数的最小值的倍数的位置。结构体整体也要对齐结构体大小通常是其最大对齐要求的整数倍。成员顺序会影响结构体大小合理调整成员顺序可以减少 padding、节省内存。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑