一大坨知识-6-Kafka
1. Why kafka 消息队列的作用: 异步、削峰填谷、解耦 中小型公司 ,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ (开源、社区活跃)是不错的选择; 大型公司,基础架构研发实力较强,用 RocketMQ (Java二次开发) 是很好的选择。 如果是 大数据领域 的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。 RabbitMQ RabbitMQ开始是用在电信业务的可靠通信的,也是少有的几款 支持AMQP 协议的产品之一。 优点: 轻量级,快速,部署使用方便 支持灵活的路由配置。RabbitMQ中,在生产者和队列之间有一个交换器模块。根据配置的路由规则,生产者发送的消息可以发送到不同的队列中。路由规则很灵活,还可以自己实现。 RabbitMQ的客户端支持大多数的编程语言,支持 AMQP 协议。 缺点: 如果有大量消息堆积在队列中,性能会急剧下降 每秒处理几万到几十万的消息。如果应用要求高的性能,不要选择RabbitMQ。 RabbitMQ是Erlang开发的,功...
一大坨知识-5-Redis
1. WhyRedis 速度快,完全基于内存,使用C语言实现,网络层使用epoll解决高并发问题,单线程模型避免了不必要的上下文切换及竞争条件; Name GuavaCache Tair EVCache Aerospike 类别 本地JVM缓存 分布式缓存 分布式缓存 分布式nosql数据库 应用 本地缓存 淘宝 Netflix、AWS 广告 性能 非常高 较高 很高 较高 持久化 无 有 有 有 集群 无 灵活配置 有 自动扩容 与传统数据库不同的是 Redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向,每秒可以处理超过10万次读写操作,是已知性能最快的Key-Value DB。另外,Redis 也经常用来做分布式锁。除此之外,Redis 支持事务、持久化、LUA脚本、LRU驱动事件、多种集群方案。 1、简单高效 完全基于内存,绝大部分请求是纯粹的内存操作。数据存在内存中,类似于 HashMap,查找和操作的时间复杂度都是O(1); 数据结构简单,对数据操作也简单,Redis 中的数据结构是专门...
一大坨知识-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; 引入整个空...


