一大坨知识-4-MySQL篇
1. WhyMysql? NoSQL数据库四大家族 列存储 Hbase K-V存储 Redis 图像存储 Neo4j 文档存储 MongoDB 海量Aerospike Aerospike(简称AS)是一个分布式,可扩展的键值存储的NoSQL 数据库 。T级别大数据高并发的结构化 数据存储, 采用混合架构,索引存储在内存中,而数据可存储在机械硬盘(HDD)或固态硬盘(SSD) 上,读写操作达微妙级,99%的响应可在1毫秒内实现。 Name Aerospike Redis 类型 Nosql数据库 缓存 线程数 多线程 单线程 数据分片 自动处理相当于分片 提供分片算法、平衡各分片数据 数据扩容 动态增加数据卷平衡流量 需停机 数据同步 设置复制因子后可以透明的完成故障转移 手动故障转移和数据同步 载体 内存存储索引+SSD存储数据 内存 Aerospike作为一个大容量的NoSql解决方案,适合对 容量要求比较大,QPS相对低 一些的场景,主要用在广告行业, 个性化推荐厂告是建立在了和掌握消费者独特的偏好和习性的基础之上,对消费者的购买...
一大坨知识-3-多线程篇
1. 线程调度 线程状态 线程是cpu任务调度的最小执行单位,每个线程拥有自己独立的程序计数器、虚拟机栈、本地方法栈 线程状态:创建、就绪、运行、阻塞、死亡 线程状态切换 方法 作用 区别 start 启动线程,由虚拟机自动调度执行run()方法 线程处于就绪状态 run 线程逻辑代码块处理,JVM调度执行 线程处于运行状态 sleep 让当前正在执行的线程休眠(暂停执行) 不释放锁 wait 使得当前线程等待 释放同步锁 notify 唤醒在此对象监视器上等待的单个线程 唤醒单个线程 notifyAll 唤醒在此对象监视器上等待的所有线程 唤醒多个线程 yield 停止当前线程,让同等优先权的线程运行 用Thread类调用 join 使当前线程停下来等待,直至另一个调用join方法的线程终止 用线程对象调用 阻塞唤醒过程 阻塞: 这三个方法的调用都会使当前线程阻塞。该线程将会被放置到对该Object的请求等待队列中,然后让出当前对Object所拥有的所有的同步请求。线程会一直暂停所有线程调度,直到下面其中一种情况发生: ①...
一大坨知识-2-JVM篇
JVM内存划分 1. JVM运行时数据区域 堆、方法区(元空间)、虚拟机栈、本地方法栈、程序计数器 1.1 Heap(堆) 对象的实例以及数组的内存都在堆上进行分配,堆是线程共享的区域,用来存放对象实例,也是垃圾回收(GC)的主要区域。开启逃逸分析后,某些未逃逸的对象可以通过标量替换的方式在栈中分配。 堆细分: 新生代、老年代 新生代分为:Eden区、Survivor1区、Survivor2区 1.2 方法区(元空间) JVM的方法区也称为永久区,存储已被Java虚拟机加载的类信息、常量、静态变量。JDK 1.8以后取消了方法区概念,称之为元空间(MetaSpace)。 当应用中的Java类过多时(如Spring等使用动态代理的框架生成很多类),如果占用空间超出设定值,会发生元空间溢出。 1.3 虚拟机栈 虚拟机栈是线程私有的,其生命周期与线程生命周期一致。每个方法执行时都会创建一个栈帧,栈帧中存放: 局部变量表 操作数栈 动态链接 返回地址 异常状况: 线程请求栈深度大于虚拟机允许深度:抛出 StackOverflowError 虚拟机栈动态扩展时无法申请足够内存...
一大坨知识-1-基础篇
不错的帖子, COPY一下 一大坨知识全都来自于此,原来帖子的名字如下: 这些年,背过的面试题 今天看到一篇文章,感叹失败的原因可能有很多条,但成功的道路只一条,来之前准备了半年,上篇俗称八股文,下篇是一些经验总结供大家参考。 网络基础 TCP三次握手 三次握手过程: 客户端——发送带有SYN标志的数据包——服务端 一次握手 Client进入syn_sent状态 服务端——发送带有SYN/ACK标志的数据包——客户端 二次握手 服务端进入syn_rcvd 客户端——发送带有ACK标志的数据包——服务端 三次握手 连接就进入Established状态 为什么三次: 主要是为了建立可靠的通信信道,保证客户端与服务端同时具备发送、接收数据的能力 为什么两次不行? 防止已失效的请求报文又传送到了服务端,建立了多余的链接,浪费资源 两次握手只能保证单向连接是畅通的。(为了实现可靠数据传输, TCP 协议的通信双方, 都必须维 护一个序列号,以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方 相互告知序列号起始值, 并确认对方已经收到了序列号起始值的...
C++ new & delete
C++ 的 new 和 delete 是动态内存核心,但现代代码中应避免裸用。理解其机制避免陷阱:new 分配内存+构造对象,delete 析构+释放内存。 1. Widget 示例类(全局唯一定义) #include <print> #include <format> class Widget { public: Widget(int value) : value_(value) { std::println("Widget constructed with value: {}", value_); } ~Widget() { std::println("Widget destroyed"); } private: int value_; }; 2. new 表达式 vs operator new 函数 new 表达式(语言操作符,不可重载):分配内存(调用 operator new)+构造对象,失败抛 std::...
C++ Stl Allocator
Allocator 是 C++ STL 容器内存管理的核心。它直接决定程序的内存效率和性能瓶颈。默认的 std::allocator 在高性能场景下往往不够用,但记住我的铁律:简单第一,复杂是敌人。 1. Allocator 的核心接口 STL 容器通过 allocator 抽象内存管理,解耦内存分配与容器逻辑。一个合格的 allocator 必须满足 allocator_traits 的要求: pointer allocate(size_t n): 分配 n 个元素内存,返回 pointer。 void deallocate(pointer p, size_t n): 释放内存。 rebind<U>::other: 用于类型转换。 重要:C++17 起,construct 和 destroy 成员函数已废弃。C++23 标准中已完全移除。使用 std::construct_at 和 std::destroy_at 代替。 // C++17+ 推荐方式 #include <memory> template <typename U, typename....
Cpp Callable Objects
在 C++ 中,Callable Object(可调用对象) 指的是任何可以像函数一样被调用的事物。简单来说,就是任何可以使用 () 运算符(Function Call Operator)的对象。 在现代 C++(C++11 及以后)中,可调用对象的概念非常重要,因为它是 STL 算法、线程(std::thread)以及回调机制的核心。 C++ 中的可调用对象主要分为以下 5 类。 1. 普通函数与函数指针 (Function Pointers) 这是最基础的形式,继承自 C 语言。 特点: 没有状态(Stateless),行为固定。 适用场景: 简单的回调,也就是所谓的 C 风格 API。 #include <print> void hello() { std::println("Hello from Function Pointer!"); } int main() { // 定义函数指针 void (*funcPtr)() = &hello; // & 是可选的 // 调...
C++ namespace
C++命名空间是语言的核心特性之一,用于解决名字冲突问题,尤其在大项目或使用多个库时。基于最新C++23标准,命名空间用法稳定,但结合模块(modules)使用更高效。下面直击要害,逐一拆解,包括[inline namespace]、匿名命名空间和命名空间别名。 参考:[cppreference.com] 1. 基本用法:声明与定义 命名空间通过namespace关键字声明,内容可以分散在多个文件中定义(如同函数定义)。 namespace MyLib { int add(int a, int b) { return a + b; } class Widget { public: void use(); }; } 使用方式: 限定名:MyLib::add(1, 2); 最安全,避免污染全局。 using声明:using MyLib::add; 只引入add,作用域内可用add(1,2)。 using指令:using namespace MyLib; 引入整个空...
Rust Iterator
什么是 Rust 迭代器? Rust 的迭代器(Iterator)是一种强大的抽象,它允许你遍历集合元素而不需要关心底层数据结构的具体实现。迭代器模式是函数式编程的核心概念之一,Rust 在这方面做得特别出色。 迭代器的基本概念 在 Rust 中,任何实现了 Iterator trait 的类型都可以称为迭代器: pub trait Iterator { type Item; fn next(&mut self) -> Option<Self::Item>; } 核心方法 next() 返回 Option<Item>,当迭代完成时返回 None。 创建迭代器的方法 1. iter() - 不可变引用迭代 fn main() { let vec = vec![1, 2, 3, 4, 5]; // 使用 iter() 创建迭代器 let mut iter = vec.iter(); assert_eq!(iter.next(), Some(&1)); ...
Common Algo
1. 贪心算法 (Greedy Algorithm) 核心思想: 每一步都做出局部最优选择,希望最终得到全局最优解。 适用场景: 具有「最优子结构」和「贪心选择性质」的问题。 示例:活动选择问题 #include <vector> #include <algorithm> struct Activity { int start, end; }; // 按结束时间排序 int maxActivities(std::vector<Activity>& acts) { std::sort(acts.begin(), acts.end(), [](const Activity& a, const Activity& b) { return a.end < b.end; }); int count = 1; int last_end = acts[0].end; for (...



