- 为博客新增动态发文功能
跟上潮流NO server BLOG加上自助动态发文和编辑,便于操作,可以不用,但不能没有;
Read More
- 软中断、硬中断在os里的应用
1.软中断分类
- 系统调用(System Calls): 程序通过执行系统调用来请求操作系统提供特定服务,例如文件操作、进程管理、网络通信等。系统调用是通过软中断来实现的。
- 异常处理(Exception Handling): 当程序执行中发生异常情况时,操作系统可以通过软中断来捕获和处理异常,例如分页错误、浮点运算溢出等。
- 任务切换(Task Switching): 操作系统使用软中断来实现任务切换,以在多任务系统中切换执行不同的任务或进程。
- 信号处理(Signal Handling): 进程可以通过软中断来处理信号,例如SIGTERM、SIGINT等,以响应外部事件或通信。
- 软中断机制(Software Interrupt Mechanism): 一些操作系统和内核使用软中断机制来执行特定的任务,例如Linux内核的软中断,用于执行高性能网络栈和其他异步任务。
- 跳表 Vs. B+树
redis的跳表 Vs mysql的B+树
先说结论:B+树是为了减少磁盘I/O, 查询利好,实现复杂;跳表实现简单,无磁盘I/O时写入占优; 具体分析:先看结构定义
Read More
B+树:
- 西门子运维开发实习
如何监控metrics
docker启动时候就开始进行log记录了,统一传入AWS CloudWatch,后端维护借助日志,on call duty负责对metrics面板进行监控,主要还是docker是否运行正常,是否激活(hotpool)。
Gitlab CI/CD
CI自动化部署yaml文件编写,构建工作流pipeline;主要是不同环境的推送和deploy之类的
证书更新、过期npm包更新
证书更新是S3存储桶+step functions 人工完成更新,stepFunction生成新的image,同时在后台AdminDashboard设置hotpool新的image,并disable旧的worker; npm包更新,基于CVE检测,冲突解决,dependency关联 npm.js查询
gitlab-runner
Read More
- 虾子二面突击 面经大荟萃
字节
调用fork函数发生了什么

copy on Write
Nginx网络模型及其惊群问题
Read More其实,在linux2.6内核上,accept系统调用已经不存在惊群了(至少我在2.6.18内核版本上已经不存在)。大家可以写个简单的程序试下,在父进程中bind,listen,然后fork出子进程,所有的子进程都accept这个监听句柄。这样,当新连接过来时,大家会发现,仅有一个子进程返回新建的连接,其他子进程继续休眠在accept调用上,没有被唤醒。 但是很不幸,通常我们的程序没那么简单,不会愿意阻塞在accept调用上,我们还有许多其他网络读写事件要处理,linux下我们爱用epoll解决非阻塞socket。所以,即使accept调用没有惊群了,我们也还得处理惊群这事,因为epoll有这问题。上面说的测试程序,如果我们在子进程内不是阻塞调用accept,而是用epoll_wait,就会发现,新连接过来时,多个子进程都会在epoll_wait后被唤醒! “惊群”,看看nginx是怎么解决它的-CSDN博客 简单一句话 概况epoll惊群解决:同一时刻只允许一个nginx worker在自己的epoll中处理监听句柄
- 虚拟内存空间分布专题
1.基础布局
Read More
- 网络八股 Reimagined

TCP三次握手过程:
Read More
- 称球问题
[1] 2次天平称出8个小球里质量偏大的那一个
分堆 3 3 2;天平三种信息对应三种利用情况,最好就是三分法; 一般化:3^(k-1)+1 ~ 3^k 个球的寻找问题,k次称重能够解决; 分类讨论即可; 
[2] 3次天平12个球找不同的1个
有12颗外观一模一样的小球,其中11颗的质量相同,而另一颗则不知是比其他小球重还是轻;现在可用的工具是一台天平称,要求称3次找出这颗与众不同的小球,请简要说明你的称法.
Read More【为什么三分法】:充分发挥天平三个状态、结果分流导向以实现目标范围缩减最大化;
- 矩阵的快速幂
https://www.cnblogs.com/yan-boy/archive/2012/11/29/2795294.html
while(n>0) { if(n&1) res*=A; A=A*A; n>>=1; }A_A_A_A_A_A => (A_A)(A_A)(A_A) 这样变的好处是,你只需要计算一次A_A,然后将结果(A_A)连乘自己两次就能得到A^6,即(A_A)^3=A^6。算一下发现这次一共乘了3次,少于原来的5次。如果用二进制去离散:例如A^19 => (A^16)(A^2)(A^1)一共有6次乘法,那为什么不用3进制了 A^19=A^9 * A^9_ A 一共才5次啊
Read More
- 文件结构 数据节 PE_ELF
1.ELF
段名 内容 .text 存放编译生成的机器码 .rodata 存放只读数据,一般是程序中的只读静态变量和字符串常量 .data 保存已经初始化的全局静态变量和局部静态变量 .bss 存储未初始化以及初始化为0的全局静态变量和局部静态变量 .rodata1 也是只读数据段,存放字符串常量,全局 const 变量,该段和 .rodata 类似。 .comment 存放编译器版本信息,比如 “GCC:GNU4.2.0” .debug 调试信息 .dynamic 动态链接信息 .hash 符号哈希表 .line 调试时的行号表,即源代码行号与编译后指令的对应表 .note 额外的编译器信息,比如程序的公司名、发布版本号等 .strtab String Table 字符串表,用于存储 ELF 文件中用到的各种字符串 .symtab Symbol Table 符号表,从这里可以找到文件中的各个符号 .shstrtab 各个段的名称表,实际上是由各个段的名字组成的一个字符串数组 .plt 和 .got 动态链接的跳转表和全局入口表 .init 和 .fini 程序初始化和终结代码段
2.PE WIN32
.text - 不多说了,就是保存代码的节 .data - 保存数据的节,这个对应C语言中以初始化的全局变量数据。想想为什么你在源码里初始化一个全局变量后运行时这个变量的值正是你想要的那个?int a = 12;并不意味着CRT为你执行了一个赋值语句,而是a在PE文件中保存的位置已经被硬编码了一个12的值。这样loader加载程序时,你给的初值被从PE文件读取到了内存中变量a的位置,这样才使你的变量a有了初值。 .rdata - 保存常量数据的节。这个可以对应C语言中的常数和常量字符串,同上面一样的原因,他们的初值被保存到了PE文件的次Section中,而不是在运行时被赋值。 .bss - (Block Start with Symbol)这个section对应C程序中的全局未初始化变量。啥?你说C中未初始化的全局变量实际上全被初始化成了0?这是因为实际上操作系统是这样干的——你的全局未初始化变量由于没有初值,所以不需要将值像上面两个一样保存到PE文件中(所以.bss节除了描述信息之外不占据磁盘空间),但是.bss会描述一段内存区域,loader在加载.bss section时直接开辟这么一块包括所有未初始化数据的内存区域,然后直接将这区域清零。这就是C中全局未初始化数据之所以为零的原因了。 .idata - 这个是保存程序导入表(Import Table)的节。当然,IT、ILT以及IAT也常常被保存在.rdata中,为什么?是考虑到安全的因素,所以将IAT放在不可写的.rdata里以防止IAT被恶意更改从而造成程序的安全隐患吧。 .edata - 这个是保存导处表的(Export Table)的节。 .reloc - 这个节是保存重定位数据的 .rsrc - 这节是保存程序资源的。想你的程序字符串啊、对话框模板啊、位图、鼠标光标什么的都在这里。实际上这个节储存.resx文件编译后的结果。 .textbss - 这节比较好玩,它是和微软Incremental Linking(增量链接)特性相关的。
Read More
- 单核多线程能提高效率吗?
1.单核多线程能提高效率吗
Read More
纯CPU运算的必然不能,反而切换开销降低效率; IO密集型运算,从CPU执行时间角度看并不会提高效率,但是从业务上看确实能减少最终完成时间;比如切片执行后,多个线程总是同一时刻进入IO阻塞,这时候IO阻塞时间会合并,因为两个IO文件的等待一般是小于硬件吞吐量的,可以把2次IO拷贝时间压缩为1次;
- 位运算
1.常用位运算操作
(1) 常用的等式: -n=~(n-1)=~n+1 (2) 获取整数n的二进制中最后一个1: n&~(n-1)或者n&(-n)。例如n=010100,则-n=101100,n&(-n)=000100。 (3) 去掉整数n的二进制中最后一个1: n&(n-1)。例如n=010100,n-1=010011,则n&(n-1)=010000。
2.如何位运算实现除2 (num/2)
Read More
- 从base64到protobuf
1.base64规则
Read MoreBase64的由来
Base64算法最早应用于解决电子邮件传输的问题。早期,由于“历史问题”,电子邮件只允许ASCII码字符。如果要传输一封带有非ASCII码字符串的电子邮件,当它通过有“历史问题”的网关是就可能出现问题。 这个网关很可能会对这个非ASCII码字符的二进制位做调整,即将这个非ASCII码的8位二进制码的最高位置为0。此时,用户收到的邮件将会是一封纯粹的乱码邮件,基于这个原因就产生了Base64算法。
- 二叉树遍历专题
-
传统DFS方式
:::info 主要是模拟递归时候,先序由于立即访问val是默认最简单的,中序和后序模拟时候有两种常见方案,后序还有一种额外的方案:借助先序逆转结果(当然这一种不是严格意义的后序次序访问) :::
-
传统DFS方式
- 主机序、网络序、字节序、位序、栈生成
1.字节序
默认Intel或AMD的x86/x64架构就一定是小端字节序。 外很多ARM CPU可以选择数据指令字节序,不过通常也都是运行小端字节序(比如我们的智能手机)。
Read More在第三版本之前ARM架构是小端模式,之后是两种模式都允许,可以进行设置来切换字节序列。例如,在 ARMv6 上,指令是固定的小端,数据访问可以是小端或大端,由程序状态寄存器 (CPSR) 的位 9(E 位)控制。 MIPS, MACOS是大端
- Windows 消息循环
1.消息循环体 消息循环体是一个无限循环,它从消息队列中获取消息并将其分派到对应的窗口或线程中进行处理
Read More类似于消息循环体,I/O多路复用也是一种事件驱动的机制,程序在有事件需要处理时才会执行相应的I/O操作,有效地避免了不必要的资源浪费。如网络连接的I/O操作
- webserver [多线程]
x.面试问题
REF: 轻量级服务器 TinyWebServer –参考和理解下的笔记 - 菜鸟C_5022 - 博客园 LT模式和ET模式 - DawnHouse - 博客园 深入理解 Linux 的 epoll 机制及epoll原理
C++14语法封装线程池是用了什么特性
使用了可变长参数模板编程,对其进行改进,使用模板元编程方法,使得线程池可接受任意类型的函数。
其中typename…Args为可变参数,可以接受任意数量的参数,通过bind函数将传入的函数f和对应的参数列表绑定为可执行对象,并通过packged_task封装为智能指针,最后通过匿名表达式包装为function<void()>类型,传入队列之中。如果先要获取执行结果,可以返回get_future,外部通过get获取结果,不然可以不返回值。 如果不使用packged_task再次封装一层,直接使用一下形式代码则会出现执行时对象已经释放的情况,造成崩溃。而function对象又无法封装为智能指针,故需使用packged_task。你的webserver有什么不同之处
①线程池部分使用了变长模板,同时使用future和packaged_task进行工作线程城池封装,使用了RAII思想用智能指针管理资源自动释放,并发控制使用了mutex和condition_variable,完成临界区互斥访问,以及工作线程的等待和唤醒; 我们使用packaged_task将可调用对象task包装成了一个异步任务。然后,我们将任务提交给工作线程池执行,并使用future获取任务执行结果。最后,我们等待所有任务执行完成。使用future、packaged_task进行工作线程池封装可以让我们更加方便地使用工作线程池; unique_lock:是mutex提供的类似智能指针的自动维护锁资源释放的工具模板,std::unique_lock 会在构造时自动上锁,并在析构时自动解锁。 condition_variable::wait用法:等待cv的notify并阻塞,std::condition_variable::wait 函数需要一个 std::unique_lock 对象作为参数,并且该 std::unique_lock 对象必须与相同的互斥量关联,即m_cv.wait(lk, condition)里的lk,这里会把lk解锁并等待通知; 任务完成后,通过condition_variable::cv.wait(lock);进行休眠,执行前需要确保unique_lock构造进行获取锁权限,确保执行wait时候互斥量处于解锁状态,以便释放mutex占用并休眠;
Read MoreQ: 为什么线程池析构时候要cv.notify_all() A: 一般是抢夺到mutex权后,设置m_stop退出标志位 Q:为什么线程池析构函数需要对每一个thread.join(); A: join()是对目标线程进行阻塞等待,全部阻塞等待意义在于,析构真正释放自我数据空间前,让线程先行退出,避免访问释放的公共资源; Q:说说你对m_cv.wait(lk, condition)的理解 A:使用条件变量时,通常需要与互斥量一起使用。互斥量的作用是保护共享资源,确保在同一时间只有一个线程可以访问共享资源,避免数据竞争和并发访问的问题。在这种情况下,互斥量 m_mutex 可以用于保护条件变量 m_cv 的访问。互斥量 m_mutex 的锁定和解锁操作控制了对条件变量 m_cv 的访问,确保同一时间只有一个线程能够操作条件变量。
- tcp socket连接图解
Read More

https TLS握手+会话密钥过程 (图解)
- TCP Nagle算法、NAT 和 NAT 穿透
Nagle
TCP的报文太小时候,避免低效大量tcp报文 对其进行累积到MSS再发送一个MSS单位的数据包。 为了避免造成延迟,需要仅对未确认的数据进行缓存: 发送条件: :::success
Read More
- Socket、libevent、Reactor、NIO
1.Socket 两台计算机之间数据传输,要通过网卡。网卡归谁管?操作系统。socket也是这么一个接口,用于程序和操作系统之间,进行网络数据收发的接口。在面向过程的语言中,socket是一个函数,在面向对象的语言中,socket是一个class,无论哪样,都是程序和操作系统之间的一个接口。在调用socket时,我们是需要指定协议的,如果指定tcp,那么这个socket就用tcp跟对方通信,如果指定udp,那么socket就用udp跟对方通信,其实还有unix-domain和raw类型的socket。 基于 Linux 一切皆文件的理念,在内核中 Socket 也是以「文件」的形式存在的,也是有对应的文件描述符。由下可知,processes[id].task_struct.fds[socket_file_descriptor] = Socket , 其中socket_file_descriptor是Socket对象对应的文件描述符,在fds(文件描述符数组)中对应与数组下标;
Read More文件描述符的作用是什么?每一个进程都有一个数据结构 task_struct,该结构体里有一个指向「文件描述符数组」的成员指针。该数组里列出这个进程打开的所有文件的文件描述符。数组的下标是文件描述符,是一个整数,而数组的内容是一个指针,指向内核中所有打开的文件的列表,也就是说内核可以通过文件描述符找到对应打开的文件。
- select 、 poll =_ epoll的演变与区别
1.前世今生
Unix最早只有select,在其后期对select的改进poll出现、后来很多年后才改进出了epoll,其过程是一个耦合较高的过程优化解耦提升了性能,现在linux网络编程已经通通使用epoll了。
2.基础功能
Read More
- RTT、TTL、DNS TTL
1.DNS TTL
Read More
- Redis速记
- 基础类型
- string、list、set、hash、zset
- hash、set = ziplist + dict
- list = ziplist + quicklist
- zset (Sorted Set)
- skiplist + dict
- 本质二分查找的有序链表
- string、list、set、hash、zset
- 底层类型 (复用底层类)
- 基础类型
- redis 布隆bloomFilter 数据结构Bitmap Hyperloglog PV UV统计
布隆过滤器 基于多个hash 实现,能保证判断不存在(其中一个hash映射位置为0就代表不存在),但不保证1存在判断正确率(多个hash位置终究会被其他映射冲突填满,全1并不一定存在,在数据装填越来越多后,此正确率持续下跌)
Read More
- p2p技术之udp打洞、nat类型
P2P 通信最大的障碍就是 NAT(网络地址转换),NAT 使得局域网内的设备也可以与公网进行通讯,但是不同 NAT 下的设备之间通讯将会变得很困难。UDP 打洞就是用来使得设备间绕过 NAT 进行通讯的一种技术。
Read More
- OSI分层结构TCP_IP协议栈及数据的封装解封过程
0.ip数据报中的ip怎么来的 是通过OS协议栈
Read More
网络层 IP 首部中的目的 IP 地址是怎么获取的? - 拾月凄辰 - 博客园 TCP Socket 编程原理详解 - 拾月凄辰 - 博客园 0.报文剥离
1.数据封装与解包逻辑
封装:由于通信数据包需要在往底层流动,以便承载二进制流的物理网线或信号上进行远程沟通,越靠近底层数据越返璞归真,失去语义和抽象文字,回归二进制流,这个过程中需要不断对各层报文加入新的字段以便在数据洪流中正确区分个体或者完整校验等用途。我们从应用层HTTP的文本信息里的特征id(如QQ号)作为不同个体独立标识,到传输、网络层的IP和端口作为标识,到链路层的MAC作为标识、到物理层无标识的0、1数据流 解包:0、1数据流经过帧标识解析给数据链路层,然后由MAC字段解析后发送给网络层、然后借助IP头部(包含souce、destination ip)划分后把数据分发给传输层,传输层通过TCP头部(含端口)的划分传给应用层,各个应用协议解析后返回给请求自身的应用程序中。 
- linux各类锁 和 内存屏障
锁:对资源的访问的禁止和允许实物化概念 不同锁区分:作用对象不同
Read More
1.各类锁
- linux 系统调用学习
1.brk(malloc实现) 2.fork、exit 3.pipe、mmap(文件到内存映射) 4.chown、chmod、open(fopen实现)、read、write
Read More
- linux 命令复习
- nohup和&的区别 &:是指在后台运行,当用户退出(挂起)的时候,命令自动跟着结束
- IP包、TCP包、MTU、MSS
1.MTU 与 MSS 只有UDP包才会在IP包时候被分片、TCP早在传输层就被MSS分段了
Read More1.IP分片产生的原因是网络层的MTU;TCP分段产生原因是MSS. 2.IP分片由网络层完成,也在网络层进行重组;TCP分段是在传输层完成,并在传输层进行重组. //透明性 3.对于以太网,MSS为1460字节,而MTU往往会大于MSS. 故采用TCP协议进行数据传输,是不会造成IP分片的。若数据过大,只会在传输层进行数据分段,到了IP层就不用分片。 所以可以看成是这种情况:传输层协议想发送一个超过了MTI的数据报,这个时候网络层就需要对其进行分片,一般UDP和ICMP会出现分片情况,但是TCP不会出现这种情况!因为TCP使用了MSS来避免分片! IP分片只有第一个带有传输层或ICMP首部,其余的分片只有IP头。至于怎么重组就是到对端以后IP层的事情了。 若TCP报文非常长那么在IP层传输时就有可能要分解成多个短数据报片。(计算机网络谢希仁) TCP分段每个都有完整首部。 PS:所以我觉得是这样的,TCP的分段是针对应用层的数据来说的,比如使用TCP发送70KB的数据,这个时候就需要将70KB分成若干个MSS,到了网络层就不需要分片了。MSS的存在就避免了网络层分片的发生,
- I_O多路复用
1.前世今生
访问管道或 socket ,默认是阻塞 I/O,当我们改用非阻塞 I/O 的方式访问时候,由于非阻塞其实是单独开辟线程轮询判断I/O是否完成。
Read More在没有事件通知机制的情况下,采用多线程实现非阻塞I/O的方式是通过轮询来实现。线程会不断地轮询等待的I/O操作,而不会被挂起。 具体来说,如果一个I/O操作还未完成,线程不会被阻塞,而是立即返回,继续执行后续的轮询查询。这种方式被称为”非阻塞轮询模型”,在没有更高效的事件通知机制时,是一种常见的非阻塞I/O实现方式。
- docker与os交互
1.为什么加入docker用户组后,不需要sudo即可执行docker命令 在 Docker 安装过程中,并没有创建名为 “docker” 的用户组。实际上,Docker 守护进程在 /var/run/docker.sock 这个 Unix 域套接字文件上设置了访问权限,以控制哪些用户可以与 Docker 守护进程进行通信。
Read More
- CPP基础遗忘
1.数组名和数组指针
int main() { int arr[5] = {1, 2, 3, 4, 5}; int (*pArr)[5] = &arr; std::cout << arr << std::endl; // 输出数组第一个元素的地址 std::cout << &arr[0] << std::endl; // 输出数组第一个元素的地址 std::cout << pArr << std::endl; // 输出整个数组的地址 std::cout << ((void*)arr==(void*)pArr) << std::endl; // 1 std::cout << ((void*)arr==(void*)&arr) << std::endl; // 1 std::cout << (arr==&arr[0]) << std::endl; // 1 }pArr是一个数组指针,pArr类型是’int ()[5]’,arr类型是int,一旦编译完成本质都是一样的 pArr只是类型不一样而已,但是他们指针值相等,arr本来就是存储数组首个位置了,我用&arr再获取arr的地址那还是 相同的内存位置,此时&arr已经是rvalue了,无法再求&&arr了。 &arr[0]也是int, 它和arr就是等同使用的,无需类型转换。 }
Read More
- Collection
源自:https://top.interviewguide.cn/
Read More
- C++11 新特性
1.lambda 仿函数
- 类模拟lambda
auto make_lambda(int a, int b) { class Lambda { public: int operator()(int x) const { return a * x + b; } }; return Lambda{}; }
- 类模拟lambda
- C++ ACM输入模板
0.关闭同步流 笔试提高输入输出速度模板
` int main() {
std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);} `1.c++从标准输入读取一行数据
string line; getline(cin, line); getline(std::istream& is, std::string& str, char delim); //每次取delim前的一个string(delim不能为string)
Read More可选参数,表示分隔符,默认为换行符 \n。当遇到该分隔符时,std::getline 将停止读取,将读取的内容存储在 str 中。
- anti-reverse [逆向]
1.IAT表是什么,怎么作用生效的
比如User32.dll,MessageBoxA这个API函数来说吧,其入口地址为77D504EA(显然超过0xC0000000 属于kernel space), 如果在操作系统版本或者User32.dll的版本跟我的不同童鞋的机器上运行,可能就会出错。这时IAT(Import Address Table:输入函数地址表)诞生,用于提供寻找系统api入口地址,提升程序的环境兼容性; 2^32 = 2^4^8 = 16^8 = 0xffffffff + 1 因此按照4GB的四等分:1GB=0x40000000 2GB=0x80000000 3GB=0xC0000000 4GB=0xFFFFFFFF+1
Read More
- [STL] stl__deque 底层学习
- deque是一个双端队列容器,其在底层为一个双端队列,所需要的头文件为#include
- deque的底层是双端队列,队列内存空间一般是连续的(但其实deque是不连续的,见后续),伪连续使得我们可以使用指针的直接跳转来访问队列中的任何元素,也就是说,我们可以使用 迭代器+偏移 的形式来访问deque容器中的数据。所以我们将deque中的迭代器称为随机访问迭代器。
- deque是一个双端队列容器,其在底层为一个双端队列,所需要的头文件为#include
- 16_32_64位系统下int 、指针、long、long long大小
指针类型void* 大小和第二行一致,和操作系统位数完全一致 其他就是记下long 和int 。 1、32位系统的最大寻址空间是2的32次方=4294967296(bit)= 4(GB)左右(一般是可以用3.25G左右就满了)。 2、64位系统的最大寻址空间为2的64次方=4294967296(bit)的32次方,数值大于1亿GB
Read More
- gWSL2+Vnc一键访问ubuntu桌面
WSL2子系统最终舒服使用捣鼓出来了。
Read More
首先说明:个人测试RDP很卡,可能是调整过加速,而且是win11家庭版暴力解锁的远程估计有bug,最后感觉VNC才是最快的,这次使用的是Xvfc + Vnc4server + (TigerVnc-viewer + gWSL GUI)
- 8月-10月 开发日志汇总
Read More
8月-10月 开发日志汇总
- 程序设计练习 KFC点餐 CreatePattern应用
KFC点餐系统 建造者模式+抽象工厂模式+普通工厂模式+单例模式
Read More
- 程序设计练习——三天打鱼两天晒网
程序设计练习——“三天打鱼两天晒网”
Read More
- Winds flow over , the things it brings and take away
I’m not as talented as you imagined, nobody will care your response and slips but I do, day and night hold you in my arm util my heats fade away, the guy in your eyes, is just be a illusion of emotion no appearance,no motivation just keeping and avoiding finding the truth life always donate like nature, but we never reflect on ourselves, one day , a knock may get to your door ,however it is a gift out of date, none will be reconginized, when everything drop down its fire, the world will not be the old one any longer, for me, its just a mysterious and advenrural stroy, waiting for my tears…..
Read More
- VIP系统网络验证
1.预估到了大客户的到来,前阵子脚本需要更新VIP录入机制了,因为用的是时间戳取部分特定格式MD5转码后取前几位本地判断。
Read More
弊端:容易在一段时间内反复激活软件
改进A:加入设备ID,MAC地址,IP限制判断。
改进B:高端GPS和网络定位一定时间地区只允许激活一个设备
改进C:引入手机登录验证,但是费时间
后两者都已经脱离本地范畴了,本地设备易克隆,技术缺陷于是还是引入网络验证吧!
- Wechat - Library Fate
来一次说干就干的微信小程序吧——莱布瑞之缘(Library Fate)
Read More
- SQL入门(1)45经典题入门
曾经那么远,却还是得与你相处——数据
Read More
- 使用opencv和opencv.js实现虚拟试戴、瞳孔定位功能中的一系列问题
因为项目需要虚拟穿戴效果,于是决定用opencv库, 一开始想法是用以前的c++代码想办法应用到web中,编译成动态链接库.so或者dll在对应平台调用 但这样对资源消耗很大,且视频流高频率调用也是不理想的。
Read More
- css学习之伸缩布局学习 (一)
一开始的导航菜单中sub—menu的width设置太窄,而且滚动条会出现,想设置居中到中心,且子菜单占版面过大如何比例缩小等
Read More
- win在kms激活工具后出现卡屏、system句柄激增问题
win10用着用着偶尔蓝屏一次,或者一段时间后鼠标键盘全部失灵,出什么问题了?!.
Read More
- 撒花~~~^_^~~博客诞生日
无意或有意,它终究还是开始了.
Read More
- java web 学习日志:spring和filter
Read More
10月30日-11月5日 log 系列
- 一起来用Jekyll!
You’ll find this post in your
Read More_postsdirectory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to runjekyll serve, which launches a web server and auto-regenerates your site when a file is updated.
- Testing Readability with a Bunch of Text
A ton of text to test readability.
Read More
