introduction
Q1: 硬件便宜了,为什么还需要软件更快?答案是为了降低功耗(尤其是在大规模集群或移动设备中)。
Q2: 能否发明一种像 C 语言一样快,但没有 C 语言那么多“坑”(内存安全问题等)的语言?
Rust
- 起源与支持: 最初由 Mozilla 研究院开发 (2010),后成立 Rust 基金会 (2021)。受到微软、谷歌、亚马逊、华为等大厂支持。
- 核心口号: Safe (安全), Concurrent (并发), Practical (实用)。
- 主要特性:
- 内存安全: 无垃圾回收 (No GC),通过编译机制杜绝空指针和数据竞争。
- 并发安全: 在编译器级别防止数据竞争。
- 现代特性: 支持模式匹配、类型推导、闭包和 Trait。
- 面临的挑战 (缺点): 借用检查器(Borrow Checker)导致开发迭代变慢(学习曲线陡峭),Unsafe 模块增加了复杂性,遗留系统的维护成本高等。
Go
- 起源与大佬: Google 出品 (2007-2009)。由计算机界的泰斗级人物创造,包括 Rob Pike (Unix, UTF-8 发明者)、Ken Thompson (B语言, C语言, Unix 之父) 等。
- 核心哲学: Less is more (少即是多)。
- 解决的问题: 旨在解决大规模分布式系统中的开发效率问题(如编译慢、依赖复杂)。
- 主要特性:
- 内存管理: 有垃圾回收 (GC)。
- 并发模型: Goroutine + Channel (基于 CSP 模型),非常轻量级。
- 语法: 简单,无继承(组合优于继承),无运算符重载。编译速度极快。
- 应用领域: Web 后端、云原生(Cloud Native)。
运行效率 vs. 开发效率:
- Rust 更侧重于 运行效率 和 安全性(硬件级控制),但牺牲了一定的易用性和开发速度。
- Go 更侧重于 开发效率 和 易用性,但在极致性能和控制力上略逊于 Rust。
关键词: 安全性 VS 易用性,历史代码复用,硬件级控制。
C++为什么仍然重要
占据独特的“生态位” (Ecological Niche)
C++ 在编程生态系统中占据了一个不可替代的位置。
- 定位: 它专门用于那些既需要直接操作硬件(高效),又需要管理极高复杂度的应用程序。
- 解释: 简单的脚本(如 Python)管理不了太复杂的底层逻辑;纯底层语言(如 C)在面对超大规模软件架构时又太累人。C++ 刚好卡在中间:既能像 C 一样控制底层,又能像 Java 一样用面向对象等高级特性管理复杂的架构。
核心哲学:零开销抽象 (Zero-overhead abstraction)
关于“零开销”的两条铁律:
- What you don’t use, you don’t pay for (你不用就不需要付费):
- 如果你不使用某个高级特性(比如虚函数、异常处理),编译器绝对不会在你的代码里塞进任何额外的垃圾代码或性能损耗。
- What you do use, you couldn’t hand-code any better (你用的东西,你自己手写也不会更好):
- 如果你使用了某个高级抽象(比如
std::sort排序算法),它的性能已经优化到了极致。哪怕你用汇编语言手写一个,大概率也只能达到一样的速度,而不会更快。
- 如果你使用了某个高级抽象(比如
C 与 C++ 的关系 (C vs C++)
C++ 是 C 的 超集 (Superset):
- 兼容性: C++ 支持 C 语言所有的编程技巧。
- 性能对等: 任何 C 语言程序都可以用 C++ 写出来,并且在时间(运行速度)和空间(内存占用)上的开销是完全一样的。
- 潜台词: 这意味着从 C 迁移到 C++ 没有性能损失,你获得了更高级的工具,却不需要付出性能代价。
C++ 的三个主要发展阶段:
- 诞生与初期 (1979–1991)
- 论文年份: 1993 (HOPL-II)
- 标题: A history of C++: 1979–1991
- 阶段特征: 这是 C++ 从 “C with Classes”(带类的 C)发展为独立语言的时期。它确立了面向对象的核心机制。
- 标准化与工业化 (1991–2006)
- 论文年份: 2007 (HOPL-III)
- 标题: Evolving a language in and for the real world (在现实世界中演进语言)
- 阶段特征: 这一时期 C++ 被广泛应用于工业界(”Real World”)。这也是 C++98 标准确立及后续修补的时期,语言变得成熟但也变得复杂。
- 现代化与竞争 (2006–2020)
- 论文年份: 2021 (HOPL-IV)
- 标题: Thriving in a crowded and changing world (在拥挤和变化的世界中繁荣)
- 阶段特征:
- “Crowded” (拥挤): 暗指出现了像 Rust、Go等强有力的竞争者。
- “Thriving” (繁荣): 尽管有竞争,C++ 通过 C++11、C++14、C++17、C++20 等现代标准的快速迭代,依然保持着旺盛的生命力。
编程是科学和艺术的结合。
程序设计范式一般有两类:
- 面向步骤:基于步骤和调用的概念。偏向图灵机的思想。
- 面向对象:引入概念和模型来刻画现实中人与世界交互的现象。特点是封装和继承。
- 函数式:由微小且有用的函数聚集起来,合成最终的结果。
- 逻辑式:根据公理和推导规则进行推理,回应用户的询问。
- 并发编程:使程序可以分发到独立的个体上运行。如多线程和并发计算等。
- 泛型编程:将常用的数据结构和算法进行抽象,设计出效率高、可重用的库。
面向对象程序设计的历史
-
Simula I:最初是作为 ALGOL 60 的扩展或预处理器,专门用于离散事件仿真。它引入了“进程”(Process)的概念来模拟活动实体,但尚未具备完整的类继承体系,主要关注于特定领域的仿真任务
- Simula 67:面向对象的开山之作,引入了”类“和”对象“的概念,但性能太差,不适合实际使用。
- Smalltalk:将”万物皆对象“的理念推向极致,将数据和功能均封装在对象内,所有操作都是对象间的消息传递。
- C++:继承了 Simula 的类、继承、多态等特性,同时保持了 C 语言的效率和灵活性。
- Java:通过 Java 虚拟机(JVM)实现了跨平台的应用开发,并推动了规范化的面向对象程序设计。
函数式编程
声明式编程的一种
函数式编程不像命令式编程那样一步步告诉电脑“怎么做”(修改状态),而是通过将大量小的、纯粹的辅助函数(Helper Functions) 组合起来,像搭积木一样合成(Synthesizing) 出最终的大结果
四大核心特性
- 数据不可变 (Immutable Data): 变量一旦赋值就不能改。不像 C/Python 里
x = 1; x = 2,这里必须创建新变量。 - 无副作用 (No Side Effects): 函数就像数学公式,只计算并返回结果,绝不偷偷修改外部变量(比如全局变量)或修改文件/数据库状态。
- 函数是一等公民 (First-class Functions): 函数可以像整数、字符串一样,被赋值给变量,或者作为参数传递给另一个函数(比如 Python 里的
map(func, list))。 - 引用透明 (Referential Transparency): 只要输入相同,输出永远相同。这让代码非常容易预测和测试。
优势与局限
- 优势 (Pros):
- 天然线程安全: 因为数据不可变,多个线程同时读写不会冲突,不需要复杂的锁机制(这解决了并发编程最大的头疼问题)。
- 数学可证明性: 代码逻辑严密,可以通过数学推导证明它是对的。
- 局限 (Cons):
- 学习曲线陡峭: 思维方式与传统编程完全不同,很难上手。
- 不适用于状态密集型场景: 如果一个系统需要频繁修改状态(比如游戏里的一滴血、一步路),用“不可变数据”来模拟会非常麻烦且低效。
不适用的场景
强依赖状态变化的领域:
- 实时游戏开发:
- 原因: 游戏全是状态(位置、血量、装备)。每一帧都在变,如果每次变化都创建新对象,内存和性能扛不住。PPT 提到了物理引擎、AI、渲染都依赖状态变更。
- 高频金融交易:
- 原因: 订单簿每秒更新数万次,要求纳秒级响应。函数式编程的层层抽象和对象创建开销在这里是不可接受的。
- GUI 应用程序: 用户的每一次点击、输入都是在改变界面的“状态”,这与函数式编程的理念天然冲突。
逻辑编程范式
编程范式 (Programming Paradigm)
- 逻辑式 (Logical)
- 人工智能领域内的自动证明 (Automatic proofs within artificial intelligence)
- 基于公理 (axioms)、推理规则 (inference rules) 和查询 (queries)
- Prolog (一种经典的逻辑编程语言)
这两张 PPT 详细阐述了 C++ 诞生的历史背景(1979年)、设计初衷以及其背后的哲学思想。它是为了解决特定工程难题,在现有语言(Simula、BCPL、C)的权衡中产生的。
以下是整理好的学习笔记:
C++ 的诞生:从史前探索到设计哲学
- 历史背景:1979年的困境 (Prehistory 1979)
- 人物与环境:Bjarne Stroustrup 在剑桥大学攻读博士学位期间,研究分布式系统的系统软件组织。
- 目标:设计由“隔离良好的模块”组合而成的软件,并在 IBM/360 上运行细节繁杂的模拟器。
- 面临的挑战:当时没有合适的工具来解决这个问题。Stroustrup 的原则是:“没有合适工具,绝不冲击一个问题”。
- 工具的尝试与失败 (Trials and Failures)
在开发过程中,Stroustrup 经历了两个主要阶段的尝试,深刻体会了当时语言的优缺点:
- 第一阶段:Simula (Simula-67)
- 优点:具有良好的可读性,支持协程(伪并行 pseudo-parallel),拥有类的层次结构,非常适合组织程序。
- 缺点(灾难性的):
- 性能差:运行时类型检查和垃圾收集(Garbage Collection)消耗了 80% 的系统资源。
- 链接器问题:不适合编写大程序。
- 尝试 Pascal:虽然类型表达能力强,编译器捕捉错误能力强,但存在低级编程错误和设计缺陷,最终放弃。
- 第二阶段:BCPL
- 优点:效率高,连接规则简单。
- 缺点:Debug(调试)太难。
- C++ 的设计蓝图 (Design Thinking)
基于上述教训,C++ 的诞生愿景被确立为:“以 C 为基础实现带有 Simula 类的 Algol68”。
科学观(技术实现维度):
- 程序组织 (Organization):借鉴 Simula,引入“类”的概念。
- 效率 (Efficiency):借鉴 BCPL,保持连接规则简单、灵活(支持异构语言)。
- 移植性 (Portability):设计目标是不能依赖复杂的运行系统(拒绝臃肿的 Runtime/GC)。
- 系统级特性:借鉴 操作系统 (OS) 的概念,引入了
protected(保护)、const(常量)、区分初始化和赋值、异常处理等机制。
- 独特的哲学观与价值观 (Philosophy & Values)
C++ 不仅仅是技术的堆砌,深受存在主义哲学家索伦·克尔凯郭尔(Søren Aabye Kierkegaard)的影响。
- 存在主义 (Existentialism):
- 认为实验(实践)比理论更重要。
- C++ 不是为了证明某种学术观点,而是为了解决一个具体问题。
- 它不是“科学家的玩物”。
- 多样性:风格多样,不强求一种所谓的“真理之路”。
- 文学观:设计中包含某种幽默感。
C++语言特性
- 静态、强类型
- OOP
- 泛型编程
- 异常处理