解决WSL2环境下的系统无法访问外网的问题
WSL2默认使用NAT网络模式,可能导致DNS解析异常或外网访问受限。建议切换为镜像模式(需Windows 11 22H2及以上版本)
在宿主机的powershell执行以下命令:[Environment]::GetFolderPath('UserProfile') 打印出用户目录,示例输出:C:\Users\Administrator
在用户目录下创建或编辑 .wslconfig 文件:notepad C:\Users\Administrator\.wslconfig
在.wslconfig文件中添加以下内容:[wsl2] networkingMode=mirrored,即可开启镜像模式(如下图)
保存文件后重启WSL2:wsl --shutdown
执行完以上步骤,可在WSL2的系统中查看IP地址是否和宿主机相同如果IP地址相同,则说明WSL2已经切换为镜像模式,可以访问外网。
雪花算法(go语言实现)
雪花算法由Twitter提出,用于在分布式环境下生成唯一且有序的64位整型ID,并且可以确保递增性。我在实习中经常见到使用雪花算法作为数据库主键,因此就把这个算法引入到ElectricSearch这个项目中作为倒排索引的文档ID。
算法原理与实现雪花算法的各个组成部分:
符号位(1位)
时间戳(41位)
机器ID(10位)
序列号(12位)
时间戳部分:占用了41位,用来记录生成ID的时间,单位为毫秒。时间戳部分可以支持大约68年的时间跨度(从算法开始的时间点算起)。
机器标识部分:占用了10位,可以用来标识不同的机器。这意味着可以支持最多2^10 = 1024台机器。每台机器在这个集群中都有一个唯一的标识号。
序列号部分:占用了12位,用来在同一个毫秒内生成多个ID。每个机器每毫秒内可以生成2^12 = 4096个不同的ID。
标志位:占用了1位,通常设为0,不使用。
生成唯一ID的过程:
获取当前的时间戳(毫秒级)。
将当前时间戳减去某个固定的时间基点(可以为编写算法时的时间点),得到相对于起始时间的时间差。
将时间差左移42位(即41位时间戳 ...
go语言实现布隆过滤器
概念与使用场景概念:布隆过滤器(Bloom Filter)由Burton Howard Bloom在1970年提出,用于测试一个元素是否在一个集合中。这种数据结构的特点是空间效率高且查询速度快,但有一定的误报率,并且不支持从集合中删除元素。
使用场景:
爬虫去重:在网络爬虫中,可以用来检测URL是否已经被抓取过,从而避免重复抓取相同的页面。
黑名单:用于快速判断某个IP地址、URL等是否在黑名单中。
防止(Redis)缓存穿透:当有新的key请求时,先通过布隆过滤器检查这个key是否存在。如果不存在则直接返回,不再查询数据库;当然也可以设置其他的处理方式,比如返回默认值或缓存预热。
工作原理组成:一个很长的二进制向量(Bitmap,也称为位图),以及多个独立的哈希函数。插入操作:当一个元素被添加到布隆过滤器时,多个哈希函数会被应用到这个元素上,每个哈希函数会产生一个索引,指示位图中的某个位置,对应这些位置的比特位会被设置为1。查询操作:查询一个元素是否存在时,同样使用相同的哈希函数来计算位图中的位置。如果所有位置上的比特位都是1,则认为该元素可能存在于集合中,如果有任何一个位置的比 ...
C++手简易写线程池
实现要点
任务队列:使用 std::function 来包装任务,通过完美转发传递参数实现类型保留
线程管理:初始化一组工作线程循环获取任务,当线程池不再被需要时,安全停止所有线程
同步机制:使用互斥量保护任务队列,使用条件变量来通知工作线程有任务可执行或停止工作
结果返回:使用 std::packaged_task 来包装任务,使用 std::future 来获取任务结果
代码:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108#include <iostream>#include <queue>#include <vector>#include <array&g ...
手写简易unique_ptr
实现要点
每个 unique_ptr 都独占其所管理的对象,因此无法被复制,应当删除其拷贝构造函数和赋值运算符。
使用移动构造函数或移动赋值运算时,要将被移动的对象的底层指针置空。
重载解引用 * 和箭头 -> 运算符,实现类似普通指针的调用
使用RAII机制自动释放资源
代码:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768template <typename T>class UniquePtr{private: T *ptr; UniquePtr(const UniquePtr<T> &other) = delete; UniquePtr<T> operator=(const UniquePtr<T> &other) = delete;public: explicit Un ...
手写简易shared_ptr
实现要点
shared_ptr 的引用计数应当使用原子操作(std::atomic)确保最低限度的并发安全。
多个指向同一个底层指针对象的shared_ptr,它们的引用计数应当相等,因此应该将引用计数也定义成指针。
使用移动赋值运算时,被移动的shared_ptr的引用计数应当减1,同时要判断是否释放资源(引用计数为0时)。
使用移动构造函数时,要将被移动的对象的底层指针和引用计数器置空。
重载解引用 * 和箭头 -> 运算符,实现类似普通指针的调用
使用RAII机制自动释放资源
代码:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118te ...
使用jmeter压测TCP项目
一、前置准备1.下载jmeter首先需要有java环境,安装java环境在这里不做演示
jmeter官网下载链接:Apache JMeter - Download Apache JMeter
下载下面的二进制压缩包
2. 中文切换(可选)在解压后的bin(apache-jmeter-5.6.3\bin)目录里编辑jmeter.properties文件,找到#language=en,将其取消注释并改成language=zh_CN
3.运行jmeter在bin目录里找到jmeter.bat文件,双击运行稍等一会后会出现jmeter的图形化界面
二、压测步骤1.创建线程组右键测试计划,选择添加->线程(用户)->线程组
这里我先创建1500个线程,设置启动延迟为10秒,并选择创建线程直到需要。解释: 线程数可以理解为并发数,启动延迟(Ramp-Up Period)可以理解为压测开始前的等待时间,当你在 JMeter 的线程组中设置了“Ramp-Up时间”时,JMeter 会在这个时间段内逐渐启动所有线程,而不是一次性启动所有线程。例如,我设置了线程数为 150 ...
快速排序、归并排序、堆排序对比
在所有排序算法中,平均时间复杂度为O(nlogn)的算法一共有三种:快速排序、归并排序、堆排序。
排序算法
最好情况时间复杂度
平均情况时间复杂度
最坏情况时间复杂度
空间复杂度
稳定性
选择排序
O(n²)
O(n²)
O(n²)
O(1)
不稳定
插入排序
O(n)
O(n²)
O(n²)
O(1)
稳定
冒泡排序
O(n)
O(n²)
O(n²)
O(1)
稳定
归并排序
O(n log n)
O(n log n)
O(n log n)
O(n)
稳定
快速排序
O(n log n)
O(n log n)
O(n²)
O(log n)
不稳定
堆排序
O(n log n)
O(n log n)
O(n log n)
O(1)
不稳定
希尔排序
O(n)
O(n log n)
O(n log n)
O(1)
不稳定
基数排序
O(nk)
O(nk)
O(nk)
O(n + d)
稳定
注:
稳定性:如果两个元素相等,排序后它们的相对顺序不变,则称该排序算法是稳定的。
希尔排序的时间复杂度和增量选择有关,如果增量序列是1,2,4,8,16 ...
为什么缓冲区可以大幅度提高I/O性能
缓冲区的基本概念缓冲区是在内存中分配的一段空间,用于暂时存储数据。当数据从一个设备传送到另一个设备时,缓冲区可以用来平滑这种传输过程,使得数据的发送和接收更加高效。
为什么需要缓冲区背景:计算机磁盘是由一个个磁道构成,每次进行数据读写的时候,都需要通过磁头寻找到到合适的磁道,才能执行读写数据的操作,而这个过程需要耗费一定的时间,即寻道时间。
原理:当我们引入缓冲区后,可以将多次小量的数据写入操作合并为一次大量的写入操作,从而大大减少寻道时间和旋转延迟,提高数据的读写效率。
与缓存的区别:
缓存主要用于存储最近或最经常访问的数据,利用硬件的性能优势,加快数据的访问速度,例如redis缓存利用内存速度远远大于磁盘的优势。在计算机底层则有CPU缓存(L1、L2、L3);内存缓存DRAM Cache;磁盘缓存Disk Cache等,从磁盘到CPU的缓存空间越来越大,性能也越来越好,造价也越来越高
而缓冲区主要用于减少数据传输和磁盘的读写次数,提高数据的读写效率。
缓冲区类型
全缓冲:数据只有在缓冲区满时才会被实际写入或读取。
行缓冲:在文本输入的情况下,数据在遇到换行符时会被实际写入或读取。
...