
简介
该用户还未填写简介
擅长的技术栈
可提供的服务
暂无可提供的服务
Wireshark是网络工程中最核心的抓包与协议分析工具。本文建立系统的抓包方法论——从抓包点的拓扑选取原则开始,确保捕获的流量包含必要的路径信息。系统讲解BPF捕获过滤器与Wireshark显示过滤器的语法差异及适用场景,前者决定哪些包进入捕获文件,后者对已捕获的包进行视图筛选。在此基础上,实践TCP流重组以还原应用层会话,运用IO Graph进行时序吞吐量分析以定位性能瓶颈,将抓包从零散的包查
从这篇开始,我们正式进入数据结构的世界。第一个登场的是顺序表,也就是动态数组。它把数据存在连续的内存空间里,像数组一样支持随机访问。但插入和删除要移动大量元素,这是它的特点也是局限。我们会手写增删改查,重点讲清楚插入和删除时数据是怎么移动的,以及动态扩容的realloc策略该怎么设计。
多线程环境下,共享变量的修改可能对其它线程不可见——这不是JVM的bug,而是Java内存模型为追求性能而赋予每条线程的缓存自由。本文从JMM的Happens-Before规则出发,论证volatile如何通过内存屏障保证写操作的即时可见性,同时揭示其不保证原子性的根本局限。深入synchronized在JDK 6之后的锁升级路径——偏向锁、轻量级锁、重量级锁如何在对象头Mark Word中逐级切
上一篇我们定义了类,但每个对象创建后还要手动调用setXxx()来初始化,对象销毁前也没机会做清理。构造函数和析构函数解决了这两个问题——它们是被自动调用的特殊函数。构造函数在对象诞生时执行,适合做初始化(分配内存、设置初值);析构函数在对象消亡前执行,适合做清理(释放资源、关闭文件)。理解它们的调用时机和规则,是写出健壮C++代码的基础。
现实世界中的对象往往由更小的部件组成:汽车有发动机,电脑有CPU,人有一双手。在C++中,这种“整体-部分”(has-a)的关系通过类的组合来实现——把一个类的对象作为另一个类的成员变量。本篇讲清楚如何正确初始化这些成员对象、构造和析构的顺序是什么,以及为什么初始化列表是组合类的好朋友。
每个对象都有自己的成员变量,比如每个学生有自己的姓名和学号。但有些东西应该是全类共享的,比如学生总数、配置参数、全局计数器。static成员变量就是为此设计的——它不属于任何具体对象,而是属于类本身。static成员函数也一样,可以不通过对象直接调用。本篇讲清楚静态成员的存储方式、初始化规则、访问方法,最后用一个简单的单例模式展示它的实际用途。
如果派生类定义了一个和基类同名的成员(变量或函数),基类的那个成员会被“隐藏”——这不是重载,不是重写,而是作用域的覆盖。这是C++继承中一个容易混淆的规则。本篇讲清楚同名隐藏的发生条件、与函数重载/重写的区别,以及如何通过作用域运算符::强行访问被隐藏的基类成员
继承是面向对象实现代码复用的核心机制,也是建立“is-a”(是一种)关系的基础。C++提供了三种继承方式:公有继承(public)、保护继承(protected)、私有继承(private)。它们控制基类成员在派生类中的可见性——哪些成员能被派生类访问,哪些成员能被外界通过派生类访问。本篇用一张表讲清楚三者的区别,并重点解释为什么公有继承才是真正的“is-a”关系。
前几篇我们讲了虚函数和多态。但有一个至关重要的细节:如果基类的析构函数不是虚函数,删除基类指针时只会调用基类的析构函数,派生类的析构函数不会被调用——这意味着派生类中分配的资源永远不会被释放。这是C++中最隐蔽、最常见的内存泄漏来源之一。本篇讲清楚虚析构函数的必要性、实现原理,以及为什么几乎所有带虚函数的类都应该有虚析构函数。
上篇介绍了虚拟继承如何解决菱形继承的二义性问题。但虚拟继承并非“免费午餐”——它引入了更复杂的内存布局和运行时的访问开销。本篇深入虚拟继承的内部实现:虚基类表(vbtable)如何工作、对象布局是怎样的、构造/析构顺序的特殊规则。更重要的是,我们会讨论:为什么C++社区普遍“不推荐”常规多继承,以及什么时候才真正需要它。







