golang test
1. Go 测试基础概念 Go 的测试系统内置在 go test 命令中,支持三种主要类型: 单元测试(Unit Tests):函数名以 Test 开头 示例测试(Example Tests):函数名以 Example 开头 基准测试(Benchmarks):函数名以 Benchmark 开头 模糊测试(Fuzz Tests):函数名以 Fuzz 开头(Go 1.18+) 所有测试文件必须以 _test.go 结尾,放在与被测代码相同的包中。 2. 单元测试(Unit Tests) 编写规则 func TestXxx(t *testing.T) { // 测试逻辑 if got := Foo(); got != want { t.Errorf("Foo() = %v, want %v", got, want) } // 或者使用 t.Fatalf 直接失败退出 } 常用方法 t.Error / t.Errorf:记录错误,继续执行 t.Fatal / t.Fatalf:记录错误,立即停止...
Golang GMP调度模型
Go语言(Golang)的并发能力是其核心优势之一,主要依赖于goroutine(协程)和调度器。Go的调度器采用GMP模型(G-M-P模型),这是从Go 1.1版本开始引入的成熟调度机制,能够高效地将大量goroutine映射到少量的操作系统线程上,实现高并发和多核利用。 1. GMP模型的演变背景 早期的Go(1.0版本)使用GM模型: G:Goroutine(协程)。 M:Machine(操作系统线程)。 所有G放在一个全局队列中,所有M从全局队列获取G执行。 问题: 全局队列需要锁保护,导致锁竞争激烈,影响并发性能。 当G发生系统调用(syscall)阻塞时,整个M阻塞,无法执行其他G,导致资源浪费。 不支持多核并行,无法充分利用CPU。 为了解决这些问题,Go 1.1引入P(Processor,逻辑处理器),形成当前的GMP模型。P的引入实现了**工作窃取(Work Stealing)**机制,极大提升了调度效率和公平性。 2. GMP模型的核心组件 G(Goroutine): Go的轻量级协程,用户态线程。 创建开销极小(初始栈仅2KB,可动态增长到G...
boost中好用的算法
基于 boost 1.82… timer 计时器 过去老的 boost/timer.hpp 已经废弃了,目前推荐使用的是 boost/timer/timer.hpp, 主要包括下面了2个类 class detail boost::timer::cpu_timer 计时器 boost::timer::auto_cpu_timer 计时器,基于cpu_timer实现,在析构的时候输出耗时 struct cpu_times { nanosecond_type wall; // 挂钟时间 nanosecond_type user; // 用户时间 nanosecond_type system; // 系统时间 void clear() {wall = user = system = 0LL; } }; 默认的输出格式为下: “%w s wall, %u s user + %s s system = %t s CPU (%p%)\n” format meaning ...
Useful Boost Libraries
基于 boost 1.82… timer 计时器 过去老的 boost/timer.hpp 已经废弃了,目前推荐使用的是 boost/timer/timer.hpp, 主要包括下面了2个类 class detail boost::timer::cpu_timer 计时器 boost::timer::auto_cpu_timer 计时器,基于cpu_timer实现,在析构的时候输出耗时 struct cpu_times { nanosecond_type wall; // 挂钟时间 nanosecond_type user; // 用户时间 nanosecond_type system; // 系统时间 void clear() {wall = user = system = 0LL; } }; 默认的输出格式为下: “%w s wall, %u s user + %s s system = %t s CPU (%p%)\n” format meaning ...
cpp中的rvo
c++11 以后支持了nrvo(命名的rvo),先来一张图 直接贴代码 #include <iostream> #include <string> #include <vector> using namespace std; class BigObject { public: BigObject() { cout << "Constructor\n"; } ~BigObject() { cout << "Destructor\n"; } BigObject(BigObject const&) { cout << "Copy Constructor\n"; } BigObject& operator=(BigObject const&) { cout << "Assignment Operator\n"; return *this; ...
C++ 中的 RVO 与 NRVO
1. 什么是 RVO? RVO(Return Value Optimization,返回值优化)是 C++ 编译器的一种优化技术,通过消除不必要的临时对象拷贝来提升性能。NRVO(Named RVO)是 RVO 的变体,针对已命名的局部变量。 关键时间点: C++11 之前:RVO/NRVO 作为编译器优化选项存在 C++17:强制要求对 prvalue(纯右值)执行 RVO C++20:进一步扩展了强制 RVO 的场景 先来看一张图直观理解: 2. 代码示例 #include <iostream> #include <string> #include <utility> class BigObject { public: BigObject() { std::cout << "Constructor\n"; } ~BigObject() { std::cout << "Destructor\n"; } BigObject(BigObject const&a...
C++ 类型擦除详解
类型擦除让 C++ 处理运行时未知类型。核心:隐藏具体类型,只暴露接口。标准库如 std::function, std::any, std::variant 都依赖它。 类型擦除是什么? 定义:运行时统一处理多种类型,编译时忘掉具体类型。只剩接口。 解决痛点: 模板太静态,无法动态类型(插件、网络数据)。 容器存异构类型。 API 解耦:接受任意 callable。 核心机制:动态多态 + vtable。 实现原理 三件套: 接口:纯虚基类。 Holder:模板派生,持值。 包装器:持 Base*,转发调用。 vs 模板:运行时开销(虚调用、heap),但灵活。 vs variant:variant 是静态类型擦除,编译期已知所有类型,无 heap 分配。 标准库示例 std::any (C++17) 简化实现(核心:vtable 类型擦除): // 简化版 std::any:使用 vtable 实现类型擦除 class Any { // VTable: 存储类型相关的操作函数指针 struct VTable { voi...
cpp字符串
c++ string 的allocate和cow string 可以说是c++ stl 中最常用的容器了,首先弄明白 cpp 中的string 到底是在哪里存储的,下面的代码我们重载了全局的new和delete #include <string> #include <iostream> #include <cstdlib> #include <vector> using namespace std; // 重载全局 new void* operator new(std::size_t size) { cout << "[Allocating " << size << " bytes]\n"; return malloc(size); } // 重载全局的 delete // void operator delete(void* ptr) noexcept { // cout << "[Deallocating]\n"; // return fr...
C++ 字符串
C++ std::string 的内存分配与 SSO std::string 是 C++ STL 最常用容器。先搞清它在哪里存数据。 重载全局 new/delete 观察: #include <string> #include <iostream> #include <cstdlib> using namespace std; void* operator new(std::size_t size) { cout << "[Allocating " << size << " bytes]\n"; return malloc(size); } int main() { for (int i = 1; i <= 17; ++i) { cout << i << ":" << string(i, '*') << "\n"; } string(16, '*').append(...
cpp的lambda和bind
基本表达式 [capture](parameters) -> return-type {body} 当没有返回类型时, 可以省略 -> return-type 变量捕获与lambda闭包实现 [] 不截取任何变 [&] 截取外部作用域中所有变量,并作为引用在函数体中使用 [=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用 [=, &foo] 截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用 [bar] 截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量 [x, &y] x按值传递,y按引用传递 [this] 截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。 lambda 的底层实现 lambda 其实是c++的语法糖,是通过c++编译器生成class来实现的,看一个简单的例子。 #include <functional> using namespace std; int main(int argc, char* argv[]) { ...






