Java lambda
Java Lambda 表达式是 Java 8 引入的一项重要特性,用于简化函数式编程的实现。它允许开发者以更简洁的方式编写代码,特别是在处理集合操作、事件监听或函数式接口时。 1. 什么是 Lambda 表达式?Lambda 表达式是一种匿名函数,它提供了一种简洁的方式来表示函数式接口(Functional Interface)的实例。函数式接口是只包含一个抽象方法的接口,例如 Runnable、Comparator 或 Function。 Lambda 表达式的核心目的是: 简化代码:减少样板代码(如匿名内部类的冗长写法)。 支持函数式编程:使 Java 更适合处理函数式编程范式,例如流式操作(Stream API)。 2. Lambda 表达式的语法Lambda 表达式的基本语法如下: (参数列表) -> { 方法体 } 参数列表:可以为空,也可以包含多个参数。如果只有一个参数,可以省略括号。 箭头操作符(->):分隔参数列表和方法体。 方法体:包含执行逻辑,可以是单行表达式或多行语句块。如果是单行表达式,可以省略大括号和 return 语...
Java 虚拟线程
Java 虚拟线程(Virtual Threads)是 Java 19 引入的一项特性,并在 Java 21 成为正式特性。虚拟线程是轻量级的线程实现,旨在提高 Java 程序在高并发场景下的性能和可扩展性,特别适合处理大量并发任务(如 I/O 密集型任务)。它通过将用户线程与平台线程(OS 线程)解耦,极大降低了线程创建和管理的开销。 一、虚拟线程的核心概念 什么是虚拟线程? 虚拟线程是 JVM 管理的轻量级线程,不直接绑定到操作系统线程(称为平台线程)。 虚拟线程由 JVM 的调度器管理,运行在少量的平台线程(称为载体线程,carrier threads)上,JVM 通过协程机制在平台线程上多路复用大量虚拟线程。 一个 Java 应用程序可以创建数百万个虚拟线程,而不会导致显著的性能开销。 虚拟线程 vs 平台线程 特性 虚拟线程 平台线程 资源占用 轻量级,内存占用低(KB 级别, 一般2KB) 重量级,内存占用高(MB 级别) 创建成本 低,几乎无限制(可创建百万级) 高,受限于 OS 资源 调度方式 JVM 调度,基于协程 OS 调度...
c++ optional & expected
在 C++ 中,std::optional 和 std::expected 是两个用于处理可能不存在的值或可能失败的操作的现代工具,它们在 C++17 和 C++23 中分别引入,提供了更安全和表达力更强的错误处理机制。以下是对它们的详细说明,包括定义、用途、特性、用法、差异以及实际代码示例。 1. std::optional定义std::optional 是 C++17 引入的标准库组件,定义在 <optional> 头文件中。它表示一个可能存在或不存在的值,类似于“可能有值,也可能为空”的概念。std::optional<T> 可以包含类型为 T 的值,或者为空(std::nullopt)。 用途 用于表示函数可能返回一个值,也可能不返回任何值。 替代传统的“特殊值”(如 nullptr、-1 等)来表示无值的情况,增强代码的可读性和类型安全性。 常用于需要明确区分“无值”和“有值”的场景,如查找操作、初始化状态等。 关键特性 类型安全:std::optional 明确表示值是否有效,避免了隐式的“魔法值”问题。 值语义:std::optional&...
c++ RTTI
下面把 C++ 的 RTTI(Run-Time Type Information,运行时类型信息)系统一次讲清楚,覆盖原理、用法、细节与坑,并给出精简示例。内容“精准”,不绕弯。 什么是 RTTIRTTI 是编译器在多态场景下,为对象保留其动态类型信息,以便在运行时查询和安全转换。标准接口主要有两件事: typeid:拿到对象(或类型)的类型描述 std::type_info。 dynamic_cast:做安全的向下转型(downcast)/交叉转型(cross-cast)。 触发条件:多态类(类里至少有一个 virtual 函数)。非多态类也能用 typeid(T) 或对非多态表达式用 typeid(expr)(这时只给静态类型)。 两个核心工具1. typeid 语义: typeid(T):返回编译期类型 T 的 type_info(无运行期开销)。 typeid(expr): 若 expr 是多态类型的左值/泛左值,结果是动态类型。 否则结果是静态类型,不求值 expr(无副作用)。 返回 const std::type_info&...
c++ const pointer
在 C/C++ 中,const 关键字与指针结合使用时,会产生不同的效果,主要是 const 指针 和 指向 const 的指针 两种情况。这两者在语法、含义和使用场景上有着明显的区别。以下是对这两种指针的详细讲解: 1. 指向 const 的指针定义:指向 const 对象的指针,表示指针指向的内存中的数据是只读的(不能通过该指针修改)。但指针本身的值(即指向的地址)是可以改变的。 语法: const T *ptr; // 或 T const *ptr; T 是数据类型(如 int, char 等)。 const 修饰的是 *ptr,表示指针指向的内容是常量。 这种指针可以指向任何 T 类型的数据(包括非 const 数据),但通过该指针无法修改指向的数据。 特点: 不能通过指针修改指向的数据:*ptr = value 会导致编译错误。 指针本身可以改变:可以让 ptr 指向其他地址。 可以指向非 const 数据:即使指向非 const 数据,也只能以只读方式访问。 示例代码: #include <stdio.h> int main() {...
c++ 中的 xxx_cast
在 C++ 中,提供了四种主要的类型转换操作符(cast),它们统称为 _cast 函数,用于在不同类型之间进行显式类型转换。这些操作符分别是 static_cast、dynamic_cast、const_cast 和 reinterpret_cast。它们取代了 C 风格的强制类型转换(如 (type)expression),提供了更安全、更清晰的类型转换方式。以下是对这四个 _cast 函数的详细讲解,包括它们的用途、语法、特点以及使用场景。 1. static_cast定义static_cast 是一种在编译时进行类型转换的操作符,用于执行相对安全的类型转换。它不会进行运行时类型检查,因此效率较高,但需要程序员确保转换的正确性。 语法static_cast<目标类型>(表达式) 用途 基本数据类型转换:在内置类型之间进行转换,例如 int 到 float、指针类型之间的转换(在安全的情况下)。 类层次结构中的向上转换:将派生类指针或引用转换为基类指针或引用(这是安全的,因为派生类对象总是包含基类部分)。 调用显式构造函数或转换函数:用于调用用户定义的类型转换(例如通...
c++ trap compilation
收集一下奇奇怪怪的玩意(包括冷门用法)。。。。 虚函数的默认参数#include <iostream> using namespace std; class Base { public: virtual void show(int x = 10) = 0; virtual ~Base() { cout << "~Base\n"; } }; class Derive : public Base { public: void show(int x = 20) override { cout << "x = " << x << endl; } ~Derive() override { cout << "~Derive\n"; } }; int main(int argc, char* argv[]) { Base* bb = new De...
CRTP
CRTPCRTP = Curiously Recurring Template Pattern。核心形式是:让派生类把自己作为模板参数传给基类 template<typename Derived> struct Base { /* 使用 static_cast<Derived*>(this) 调用派生接口 */ }; struct Derived : Base<Derived> { /* ... */ }; 这是 静态多态(compile-time polymorphism) 的一种实现:基类在编译期就能调用派生类的方法,达成“没有虚函数表、零运行时开销”的多态。 工作原理(Why / How)基类通过 static_cast<Derived*>(this) 或 static_cast<const Derived*>(this) 把自己转回派生类型,然后直接调用派生实现。因为在最终对象内确实包含派生子对象,所以在合法用法下这是安全的(前提:对象确实是 Derived 的实例)...
c++ 中的类型擦除
C++ 中的类型擦除(Type Erasure)详解类型擦除(Type Erasure)是 C++ 中一种高级编程技术,它允许我们在运行时处理不同类型的值,而无需在编译时知道具体的类型信息。这种技术本质上是将类型信息“擦除”或隐藏起来,通过动态多态或其他机制来统一处理多种类型,从而实现更灵活的泛型编程。类型擦除在标准库中被广泛使用,例如 std::function、std::any 和 std::variant 等组件都依赖于它。 下面我将从概念、原理、实现方式、优缺点、实际应用和示例代码等方面详细说明。内容基于 C++11 及后续标准(包括 C++17 和 C++20 的相关改进) 1. 什么是类型擦除?为什么需要它? 定义:类型擦除是一种设计模式,它通过将具体类型的信息隐藏在抽象接口后面,来实现对多种类型的统一处理。简单来说,就是让代码在编译时“忘记”具体的类型,只保留运行时所需的接口或行为,从而允许存储和操作异构类型的值。 为什么需要类型擦除? 泛型编程的局限:C++ 的模板(template)是静态的泛型机制,它在编译时生成具体代码,但无法处理运行时动态类型(如从用户...
c++ ranges
C++20 引入了 Ranges 库(位于 <ranges> 头文件中),这是对标准模板库 (STL) 的重大扩展和泛化。它使得迭代器和算法更强大、更易用,主要通过引入范围 (range) 的概念来实现统一处理各种数据结构(如数组、向量、列表等)。Ranges 库的核心优势在于算法的懒惰求值 (lazy evaluation)、直接操作容器,以及可组合性 (composability),这大大简化了代码编写,避免了传统 STL 中常见的迭代器对 (begin/end) 显式使用。 std::ranges 关键概念 Range:一个范围是一个可迭代的序列,必须提供 begin() 和 end()(哨兵)。示例包括 std::vector、std::array、std::string_view 等,甚至 C 风格数组。 Views:视图是范围的轻量级、懒惰表示,不会复制数据,只在需要时计算。它们是 Ranges 库的核心,用于管道式组合(如使用 | 操作符)。 Adaptors:如 views::filter、views::transform、views::ta...







