brpc源码之bthread原理及调度
源码分析:https://github.com/moyin1004/brpc-learn bthread结构 btreahd数据结构 bthread可以理解为用户态线程,调度无需系统调用 TaskMeta实际由brpc中对象池ReourcePool分配 实际上每个bthread都是一个任务,bthread的调度就是对任务的调度,如果了解golang的GMP模型,就会发现两者非常相似,都是任务+任务队列的形式,bthread或者goroutine的和普通任务的区别就是可以中途挂起 bthread对应的数据结构如下: struct TaskMeta { // [Not Reset] butil::atomic<ButexWaiter*> current_waiter{NULL}; uint64_t current_sleep{TimerThread::INVALID_TASK_ID}; // A flag to mark if the...
面经-Golang
内存分配/内存逃逸/GC 内存管理原理:https://draven.co/golang/docs/part3-runtime/ch07-memory/golang-memory-allocator 分配 Golang内存管理—内存分配器 图解Go语言内存分配器 原理来源于google的tcmalloc 内存逃逸 https://juejin.cn/post/7155815911755087908 GC Golang 垃圾回收:一次 GC 周期的详细过程 GMP调度 GMP 原理与调度 看完brpc的bthread之后再看go的协程调度,发现基本原理大致相同 协程+队列+系统线程池 协程可以视为任务 每个队列绑定一个系统线程,当本队列空时,可以从其他队列偷取任务 参考资料 https://draven.co/golang/
面经-MongoDB
分片原理 https://juejin.cn/post/6969431144462974984 分片核心概念 分片(Shard):每个分片是存储数据子集的独立 MongoDB 实例(通常以副本集形式部署,保证高可用性)。所有分片共同存储整个数据集 分片键(Shard Key):集合中用于划分数据的字段(如 user_id 或 timestamp)。分片键的选择直接影响数据分布的均衡性和查询性能 块(Chunk):分片内数据的逻辑划分单位,默认大小为 64MB/128MB。块是数据在分片间迁移的最小单位 配置服务器(Config Server):储分片集群的元数据(如分片键范围、块分布信息),通常以副本集形式部署,保证元数据高可用 查询路由器(mongos):轻量级进程,作为客户端与分片集群的入口,负责将请求路由到正确的分片 分片工作原理 数据分片流程 写入流程:当客户端写入数据时,mongos 根据分片键计算数据应归属的块,检查该块当前所属的分片,并将数据写入对应的分片 读取流程:mongos...
Office文件内容解析
微软官方文档: doc格式:https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-doc xls格式:https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-xls ppt格式:https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-ppt OLE复合文件格式:https://docs.microsoft.com/en-us/openspecs/windows_protocols/MS-CFB doc、xls、ppt文件都属于OLE复合文件,在OLE基础上存储 OLE格式解析 以xls为例:复合文件以一个Header+多个Sector形式进行存储。 Header为512B,保存文件的基础信息,前8各字节一定是0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A,...
C++11智能指针标准库简化实现及enable_shared_from_this解析
参考libc++ 7.0.1实现 简单实现源码:https://github.com/moyin1004/learning/blob/master/cpp/SharedPtr.cc shared_ptr数据定义 shared_ptr使用引用计数管理一个对象资源,简单定义如下: template <typename T> class SharedPtr { private: T* _ptr; atomic<int>* _cntrl; } 以上实现简化了标准库控制块,只有计数,缺少了弱引用计数(weak_ptr使用) 实际使用中,引用计数为0时,并没有释放控制块资源,但是资源已经不可用了,当弱引用计数计数也为0时,才会释放控制块资源 标准库控制块实现: class __shared_count { protected: long __shared_owners_; // 用于shared_ptr 引用计数 }; class __shared_weak_count :...
内存对齐
内存对齐 #include <cstdio> #include <cstdlib> #include <atomic> // g++ mem_align.cpp -Wall -O2 struct TestAlign { int64_t a; char b; int64_t c; }; int main() { // glibc 的实现(Linux 默认 C 库): malloc 在 64 位系统上默认对齐到 16 字节 TestAlign ta1{1, 'a', 2}; int8_t *p1 = (int8_t *)&ta1; printf("data: %c\n", *(char *)(p1 + 8)); // 应该是a printf("data: %ld\n", *(int64_t...
C++ attribute语法
GNU 和 IBM 语言扩展 __attribute__((...)) 、Microsoft扩展 __declspec() 标准库格式:[[attribute-list]] GUN __thread TaskGroup *tls_task_group = __null; static __attribute__((noinline, unused)) TaskGroup *get_tls_task_group(void) { asm volatile(""); return tls_task_group; } static __attribute__((noinline, unused)) TaskGroup **get_ptr_tls_task_group(void) { TaskGroup **ptr = &tls_task_group; asm volatile("" : "+rm"(ptr)); return...
面经-Redis
lua脚本和pipline的区别 https://blog.csdn.net/qq_37080455/article/details/140443791 批量发送命令,lua脚本是原子性的,pipeline按顺序处理操作不保证原子性的 pileline的作用和优势 Redis Pipeline 的主要作用是将多个命令批量发送到服务器执行,减少客户端与服务器之间的网络往返次数(Round-Trip Time, RTT),从而显著提升批量操作的性能。 核心作用 批量执行命令客户端将多个命令一次性发送到 Redis 服务器,服务器依次执行这些命令,并将结果一次性返回给客户端。避免了传统的“发送命令→等待响应→再发送下一个命令”的串行模式。 减少网络开销合并多个命令的通信过程,降低网络延迟对性能的影响(尤其在物理距离较远的场景中效果更明显)。 核心优势 大幅降低延迟假设网络往返时间为 100ms,执行 100 个命令时:传统模式:总耗时 = 100 命令 × 100ms = 10,000ms(10 秒)。 Pipeline:总耗时 ≈ 1 次往返时间(100ms) +...
面经-C++
C++运行时多态机制 虚函数机制(如何实现的):当一个类中定义了虚函数之后,其对象存储布局之中会生成一个虚函数指针,该虚函数指针指向了一张虚函数表, 虚函数表里面存放的是虚函数的入口地址 虚函数机制被激活的条件: 1.基类要定义虚函数 2.派生类要重定义(覆盖)基类虚函数 3.创建派生类对象 4.基类指针指向派生类对象(基类引用绑定到派生类对象) 5.通过基类指针(引用)调用虚函数 为什么构造函数不能设为虚函数? 答: 根据虚函数被激活的条件,先要创建对象,才会生成虚函数指针, 之后才能使用虚函数 类中定义虚函数后,内存中有一个指针大小的数据,即虚函数指针 虚指针的生成条件 类中声明了虚函数(包括继承的虚函数) 虚函数的存在会导致所有该类的对象(包括派生类对象)携带 vptr 补充C++静态多态 静态成员函数可不可以是虚函数 static静态成员函数不能定义为虚函数。 static成员不属于任何类对象或类实例,静态成员函数没有this指针。...
[译]C10M并发连接的秘密
The Secret To 10 Million Concurrent Connections -The Kernel Is The Problem, Not The Solution 现在我们已经攻克了C10K问题,那么我们如何升级并支持1000万并发连接?你会说这是不可能的。不是这样的,现在的系统正在使用一些他们可能不熟悉的激进技术来提供 1000 万个并发连接。为了了解它是如何完成的,我们求助于 Errata Security 首席执行官 Robert Graham,以及他在 Shmoocon 2013 上题为C10M Defending The Internet At Scale的精彩演讲。 Robert以一种巧妙的方式来阐述我以前从未听说过的问题。他从一些历史开始,讲述了 Unix...
个人服务器Ubuntu2404部署hexo博客
创建git裸仓库 git init --bare hexo.git 修改git push之后的钩子操作 修改hooks/post-receive 文件 #!/bin/bash GIT_WORK_TREE=/var/www/hexo git checkout -f 参考资料 https://cloud.tencent.com/developer/article/2308870?areaId=106001 https://cloud.tencent.com/developer/article/1662792