- 博客(81)
- 收藏
- 关注
原创 设计方案总结
2G 内存在 20 亿个整数中找出现次数最多的数案例分析:整数占用 4个字节。整数的范围是 -21亿 ~ 21亿。kv 对需要 8个字节,k 存储整数,v 存储出现次数。存储 20亿个整数需要 16G内存。数据存储使用散列表。分治:要将一个大文件拆分成若干个小文件。同一个数字不能分布在多个文件中。20亿个整数能够均衡分布在多个文件中。通过 hash 运算实现。因为同一个数字经过运算会得到相同的值,可用于数据分流hash 算法具备随机性 → 将大文件中的数据均衡分布在多
2024-06-10 17:22:33
649
原创 操作系统总结
进程和线程的区别本质区别:进程是资源调度以及分配的基本单位。线程是 CPU 调度的基本单位。所属关系:一个线程属于一个进程,一个进程可以拥有多个线程。地址空间:进程有独立的虚拟地址空间。线程没有独立的虚拟地址空间:线程有调用栈、程序计数器(PC)、本地存储(LS)等少量独立空间。内存:系统会为每个进程分配不同的内存空间。系统不会为线程分配内存,线程所使用的资源来自其所属的进程。并发性:进程的并发性较低。线程的并发性较高。对于单个 CPU,操作系统会把 CPU
2024-06-08 22:15:36
1362
1
原创 C++ 网络编程
当服务端收到客户端发送的SYN包后,该连接处于半打开状态。半连接队列(SYN队列)用来存储半打开状态的连接→通过哈希表实现→以O(1)的时间复杂度移除元素。当服务端收到客户端的ACK包后,连接建立成功,先将该连接从半连接队列中移除,然后把该连接加入到全连接队列(accept队列)中。如果客户端收到SYN-ACK包后,不回复ACK包:也就是攻击者短时间伪造不同IP地址的SYN包,快速占满SYN队列,使服务端不能为正常用户服务 → SYN泛洪、SYN攻击、DDos攻击。
2024-05-20 22:34:39
1186
1
原创 C++11 特性
autodecltypenullptroverridefinalconstexprusingexplicitdefaultforfunctionlambdabindarrayshared_ptrweak_ptrunique_ptrthreadmutexlock_guardatomicT &&std::move万能引用 T &&
2024-05-12 00:14:55
903
原创 C++面向对象
publicprotectedprivateprivate权限继承:基类成员在子类中的最高权限是什么。可以通过using来提高基类成员在子类中的权限,只能提高,不能降低。支持多继承。支持接口继承(通过抽象类和纯虚函数实现)。
2024-05-11 20:17:52
1143
原创 Linux 基础命令、性能监控
在文件中执行关键词搜索,并显示匹配的结果。:计算文件的字节数、字数、或是行数,若不指定文件名称,或是所给予的文件名为 “-”,则 wc 会从标准输入设备读取数据。
2024-05-05 22:57:54
861
1
原创 CMake使用
三、子目录四、多个文件目录,子目录编译成库文件五、多个文件目录,子目录使用源码编译六、生成动态库七、生成静态库八、调用动态库、静态库如果同时存在动态库和静态库,优先链接动态库。强制链接静态库使用 。
2024-04-28 16:19:34
374
原创 C++ 多线程
一、线程 thread默认构造函数。// 创建一个空的 thread 执行对象thread() {}创建一个有参线程对象时,该线程就开始执行。template<class Fn, class... Args>explicit thread(Fn&& fn, Args&&... args);拷贝构造函数(被禁用),意味着 thread 不可被拷贝构造。thread(const thread&) = delete;thread t1;
2024-04-21 22:52:40
606
原创 右值引用和移动语义
int a = 6;左值可以取地址、位于等号左边。a可以通过取地址,位于等号左边,所以a是左值。右值没法取地址,位于等号右边。6 位于等号右边,6 没法通过取地址,所以 6 是个右值。int a_;A a = A();a可以通过取地址,位于等号左边,所以a是左值。A()是个临时值,没法通过取地址,位于等号右边,所以A()是个右值。有地址的变量就是左值,没有地址的字面值、临时值就是右值。
2024-04-20 16:16:27
806
原创 C++ 智能指针
一、为什么需要智能指针智能指针主要解决以下问题:内存泄漏:内存需要手动释放,使用智能指针可以自动释放。共享所有权指针的传播和释放,比如多线程使用同一个对象时析构问题。C++ 里面的四个智能指针:auto_ptr 、shared_ptr、unique_ptr、weak_ptr,其中后三个是 C++ 11支持,并且第一个已经被 C++ 11 弃用。shared_ptr 共享对象的所有权,但性能略差。unique_ptr 独占对象的所有权,由于没有引用计数,因此性能较好。weak_ptr
2024-04-20 12:07:05
963
原创 分布式锁的实现
一、背景在分布式系统中,一个应用部署在多台机器中,在某些场景下,为了保证数据的一致性,要求在同一时刻,同一任务只在一个节点上运行,即保证某个行为在同一时刻只能被一个线程执行。在单机单进程多线程环境下,通过锁很容易做到,比如 mutex、spinlock、信号量等。在多机多进程环境下,就需要使用分布式锁来解决了。分布式场景:我们的应用由多个节点构成,这些节点可能分布在不同的机器中,也有可能分布在不同的网络环境中,通常这些进程之间通过 socket 进行通信。二、分布式锁是什么类型的锁
2024-04-14 22:02:46
563
原创 用户态网络缓冲区的设计
生产消费模型生产者:,追加数据 → 把数据从内核态拷贝到用户态,填充用户态网络缓冲区 。消费者:从用户态网络缓冲区界定数据包,界定成功,取数据包 → 把剩余数据挪到最前面,修改 → 优点:结构简单,易于实现。缺点:需要频繁腾挪数据,只要界定成功一个完整数据包,就需要把后面的数据挪到前面,以空余更多的空间供生产者往里面填充数据。需要实现扩缩容机制,如果缓冲区剩余空间不足以存放数据,需要对缓冲区进行扩容,并且将旧缓冲区中的数据挪到新缓冲区中。使用场景:客户端发送的数据比较少,并
2024-04-09 22:42:37
699
原创 MySQL 连接池的实现
使用 MySQL 连接驱动与 MySQL 进行交互(执行 SQL 语句)。同步连接池和异步连接池跟具体的数据库绑定。以及动态库或静态库。
2024-04-01 21:49:43
1041
原创 线程池实现与性能分析
一、线程池是什么线程池是一种池式结构(用来解决资源的频繁创建和销毁的问题)。其他的池式结构:内存池,连接池,对象池(避免对象的频繁创建和销毁)。线程池是维持和管理固定数量线程的池式结构。为什么要维持管理固定数量的线程 ?固定数量:线程数量继续增加,由于系统资源的限制,不再带来性能的提升,反而给操作系统带来负担。每一个 CPU 的核心只能运行一个线程,比如 CPU 的核心是 8 个,那么只能同时运行 8 个线程;就算线程数量继续增加,核心也不会去调度这些多余的线程,那这些多余的线程就是
2024-03-30 23:34:49
845
原创 后端项目架构
fastdfs-nginx-module、nginx-upload-module 安装。重新编译 Nginx,并且给 Nginx 目录下的。以上就完成了 FastDFS 的安装与配置,可以。fastdfs-nginx-module 的配置。启动 Tracker 和 Storage 服务。接下来还要安装 Nginx。安装 libfastcommon。文件中增加头文件目录。安装 FastDFS。配置 Tracker。配置 Storage。
2024-03-29 16:00:23
951
原创 C/C++语言
拷贝情况:用同类的对象构建一个新的类对象。A a1;A a2(a1);函数传参为类对象,值传递,类的复制。函数返回值是类对象。运算拷贝构造函数浅拷贝对象中的成员数据的简单赋值。深拷贝为对象中的动态成员(指针)重新动态分配空间,或者重新分配资源。重写拷贝构造函数,重载 = 运算符。
2024-03-24 23:33:14
926
原创 MySQL 缓存策略
热点数据读写策略读:先读Redis缓存,缓存存在直接返回;缓存不存在,去访问MySQL获取,再写Redis。写:需要从安全和性能做平衡选择。为什么要先操作Redis?因为读是先走的Redis,所以写也要先走Redis。以安全为主:先要删除Redis中的数据,然后再写MySQL,最后将MySQL数据同步到Redis。问题:缓存方案的主要目标是提升效率,而现在为了安全降低效率。读远大于写。以性能为主:先写Redis缓存并设置过期时间(200 ms再写MySQL,接着MySQL。
2024-03-05 22:47:58
1185
原创 Redis 淘汰策略、持久化机制、高可用
配置淘汰策略:如果 内存空间已满,并且没有设置淘汰策略,再 会直接返回错误,提示内存空间已满;如果设置了淘汰策略, 会按照淘汰策略选择数据进行删除,再 就会成功。设置了过期时间的 ::最长时间没有使用。:最少次数使用,随机采样。:最近要过期。:随机。所有 :。。。禁止淘汰:。 不会在 到达设定的过期时间那一刻立即自动删除,而是采用了惰性删除和定期删除的混合策略:惰性删除:当某个 被访问时, 会检查这个 是否已经过期。如果已经过期, 会在该 被访问
2024-03-04 20:03:36
735
原创 Redis 单线程原理
为什么不采用多线程redis有多个对象类型,每个对象类型又有多种数据结构的实现,导致加锁复杂、锁粒度不好控制(操作临界资源所需要的时间)。频繁的CPU上下文切换,抵消多线程的优势。不能有耗时的操作,比如CPU运算、阻塞的IO,会影响redis的响应性能。redis处理IO密集型:磁盘IOfork进程,在子进程做持久化。使用,另起线程做持久化(异步aof刷盘)。网络IO服务多个客户端,造成IO密集;数据请求或返回数据量比较大。开启IO多线程。
2024-03-01 21:37:42
1216
1
原创 Redis 事务与异步方式
按照稳定的请求来处理,但是实际情况不一定是稳定的请求,所以局限性很大,没有很好地限定行为操作次数。实际情况可能是两分钟内出现了 次请求。滑动时间窗口限流滑动窗口内的行为统计。解决了窗口间的统计异常。滑动窗口的容量、移动速率是固定的。漏斗限流漏斗的容量是有限的,当漏斗水装满,水将装不进去;水从漏斗嘴按一定速率流出,当流水速度大于灌水速度,那么漏斗永远无法装满;当流水速度小于滚水速度,一旦漏斗装满,需要阻塞等待漏斗腾出空间后再灌水。漏斗的剩余空间就代表着当前行为可以继续进行的数量,
2024-02-28 20:45:03
1279
原创 二分查找、三分查找
lower boundlower \ boundlower bound在单调递增数组里 ,查找第一个 ≥\geq≥ 31 的数(返回下标),不存在返回 array.lengtharray.lengtharray.length。upper boundupper \ boundupper bound在单调递增数组里 ,查找第一个 >>> 26 的数(返回下标),不存在返回 array.lengtharray.lengtharray.length。lower boundlower \ boun
2024-02-28 16:36:04
1137
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人