
s2: 软件进阶
涛歌依旧
毕业后就职于华为和腾讯
展开
-
写了一个多线程服务器(基于非阻塞socket)
大家好,我是涛哥。最近写了一个服务端程序,能与多个客户端进行通信。那么,这个服务端是怎么实现的呢?很简单,它就是很常规的多线程服务器。如果你还不太清楚,那我画个图,你就明白了。三个男生都追一个女生,这个女生又不好拒绝,于是与三个男生之间保持通信关系。 涛哥手绘服务端实现既然是多线程服务器,那么,这些线程肯定是有明确分工的。主线程来处理网络的连接,而通信线程来处理客户端与...原创 2022-02-20 22:47:16 · 1128 阅读 · 0 评论 -
漫话Redis源码之九
/* This is a helper function for the COPY command. * Duplicate a hash object, with the guarantee that the returned object * has the same encoding as the original one. * * The resulting object always has refcount set to 1 */robj *hashTypeDup(robj ...原创 2021-11-21 23:07:42 · 565 阅读 · 0 评论 -
进程、线程、协程对CPU的消耗
大家好,我是涛哥,又是周末,祝愿大家开心。今天,不分享复杂高深的东西了,仅来聊聊进程、线程、协程对CPU的消耗问题,并用实际代码来验证,加深对这些概念的理解。另外,值得一提的是,进程、线程、协程几乎是笔试面试必考的内容。而且,在实际开发中,也有必要深入理解这些基础概念。一. 单核CPU的消耗C语言死循环程序如下:int main(){ while(1); return 0;}开启单进程,可以看到,大约消耗100%的CPU核:开启2个进程,可以看到,.原创 2021-08-14 15:44:51 · 4589 阅读 · 5 评论 -
QPS和并发数,究竟是何种关系?
大家好,我是涛哥。又是周末,愿大家开心。今天不写复杂文章,来聊点简单有趣的,探讨下QPS(Query Per Second)和并发数的关系。就我的个人经验而言,很多人在工作中对这两个概念一知半解,也有很多人在面试时回答得模棱两可,不太应该哦。多年前,在面试阿里巴巴时,遇到了一个开放性问题:假设超市每分钟有10个人走出来,请估算超市里面有多少人?是不是感觉手足无措呢?嗯,可能如此。其实,这个问题没有标准答案,关键还是考查思路。我们先看一个有趣的定律,即Little's La原创 2021-08-14 15:42:03 · 5621 阅读 · 4 评论 -
free的含义究竟是什么?
今天要聊的是linux的free命令,它输出的是内存相关的信息。该命令看似简单,但它所涉及到的一些内存信息经常被误解,所以有必要澄清。在开发和运维中,我们不仅需要关注CPU资源的消耗情况,还需要关注内存资源的消耗情况,这就必须涉及到free命令,本文将进行实战讲解。我的云服务器内存简介我买了一台老东家的云服务器,每年三四百块钱,基本参数如下:可以看到,内存1G,即1024M. 当我用free命令查看时,结果如下:ubuntu@VM-0-15-ubuntu:~$ free -wh原创 2021-08-14 15:38:18 · 3198 阅读 · 0 评论 -
CPU使用率到100%了?
最近,一位同事急匆匆跑过来跟我说:糟糕了,服务器CPU的使用率达100%了。我心想不可能啊,CPU有那么多核,怎会跑满?于是看了一眼,结果虚惊一场。这位同事看到的100%,并非指整个CPU使用率到了100%,而是指CPU某些核的使用率到了100%.趁此机会,我来聊聊与CPU相关的概念,对很多软件开发和运维人员来说,这些概念是必须要掌握的: CPU主频 多个CPU 多核CPU 逻辑核(超线程) 大小端 以一款CPU为例,看下具体参数:.原创 2021-08-14 15:35:18 · 3434 阅读 · 1 评论 -
写给大学生新手的查杀bug方法
1947年9月9日,九九艳阳天,计算机历史上的第一个bug诞生了,我们之前在古今计算机发展简史(链接)中进行了比较详细的介绍。对于程序员来说,写bug、查bug、杀bug,都是司空见惯的事情。我博客和公众号的关注者中,有不少是大学生朋友。经常有人给我发一段程序,让我帮找bug在哪里。非工作日且有空的话,我一般会回复:打log调试。原创 2021-01-24 10:31:05 · 3947 阅读 · 13 评论 -
第一次遇到http code 413---上传文件太大被nginx拒绝
第一次遇到http code 413, 返回内容如下:<head><title>413 Request Entity Too Large</title></head><body><center><h1>413 Request Entity Too Large</h1></center><hr><center>nginx</center></body>经查,是上传文件太大,被nginx拒绝了。改nginx配置后,搞定。原创 2020-09-20 23:44:54 · 5456 阅读 · 3 评论 -
读从库导致的低概率bug
最近发现一个低概率问题: 现象: 金额丢失 原因: 代码流程控制出错,导致读取了从库的值,更改后,写入了主库。 而读取从库时,主从延迟太厉害,导致读取的值不是最新主库的值。产生更新覆盖丢失。 处理: 在涉及读后写的操作时,一定要从主库读。原创 2020-09-05 18:21:24 · 2888 阅读 · 5 评论 -
笔试面试题目:求top-K(使用堆)
top-K问题是很常见的。在T公司的两次面试中,都遇到了这个问题,在S公司的面试中,也遇到了这个问题。本文来具体聊一下top-K问题:有N个整数,求出最大的K个值,内存无法容纳这N个整数。 一眼便知道是海量数据问题,直接用堆就行了,确实如此。但是,我觉得这样太经验主义了,为什么要用堆呢?为什么不用其它的数据结构呢?原创 2020-08-01 08:54:00 · 2787 阅读 · 1 评论 -
搜索引擎提示功能的实现(使用trie树)
大家经常使用google, 当输入搜索内容后,有自动提示的功能,节省了时间。那么,这个自动提示功能是怎样实现的呢?关于搜索匹配,我们讲到过哈希表,也简单提到过红黑树,但今天要说的trie树更适合这种场景,因为trie树能实现前缀匹配。 trie树,就是retrieval树,也就是检索的意思,名如其实,我们先来看看trie树的数据结构。与其它数据结构相比,trie树在前缀查找方面,有独特的优势,而且非常快。实际上,大家经常使用的IDE的自动提示功能,也能使用trie树来实现。原创 2020-08-01 08:53:31 · 3069 阅读 · 4 评论 -
判断元素是否存在于集合中(使用Bloom Filter)
今天,我们来聊Bloom Filter, 它是1970年由Bloom发明的,在判断元素是否存在于集合中时,有广泛的应用。引入Bloom Filter后,能标记字符串,而且大大节省了bitmap长度和空间,只是牺牲了一些准确性。在大数据的相关应用中,会经常看到Bloom Filter的身影。原创 2020-08-01 08:53:03 · 3459 阅读 · 4 评论 -
哈希表查找的本质
某一天,黄药师、欧阳锋、周伯通、郭靖、洪七公、一灯大师入住酒店,每人一个房间。 江南七怪柯镇恶,要去酒店找郭靖,怎么找呢?线性查找的思路是:逐个房间敲门询问,直到找到郭靖为止。对于初入门编程的人来说,这是最直接的思路,而且好像不容易找到其它思路。 然而,对于稍有点生活常识的人来说,线性查找的思路挺傻的,何不直接找出郭靖所在的房间号,然后直接去这个房间找郭靖呢?原创 2020-08-01 08:51:38 · 3140 阅读 · 3 评论 -
https原理的来龙去脉
大家每天都在用https, 今天,我们来聊聊它的原理。 我们知道,http基于TCP协议,明文传输,不安全。https是加密传输,安全。任何不使用https的网站都是流氓网站。https的本质是加密传输,它需要解决一系列的秘钥管理问题。 https很简单,关键在于理解其背后的思路,这些思路可以指导我们设计更加安全的系统。另外,https也是笔试和面试的常考点。原创 2020-08-01 08:51:18 · 4374 阅读 · 7 评论 -
玩一下golang操作excel
最近要用golang操作excel,故来玩下:package mainimport ( "fmt" "github.com/360EntSecGroup-Skylar/excelize")func main() { f, err := excelize.OpenFile("/xxxxxx/test.xlsx") if err != nil { fmt.Println(err) return } // Get value from cell by given wor...原创 2020-08-01 08:55:06 · 4260 阅读 · 5 评论 -
逛淘宝天猫想到SSO单点登录
QQ音乐、王者荣耀使用微信和QQ登录,是不是第三方登录? 是的,但毕竟它们都是腾讯的亲儿子,所以能获取更多的权限和接口。微信和QQ账号,已经成为用户在网络上的身份ID.腾讯手握微信和QQ两大账号体系,所向披靡。我们可以看到,通过SSO, 如果用户登录了淘宝,自然就登录了天猫。如果退出登录淘宝,天猫自动退出登录。SSO的原理并不难,搞懂了SSO, 有利于理解前端和后台的一些重要知识。SSO也是很多笔试和面试的常见考点。原创 2020-07-05 10:53:36 · 5953 阅读 · 16 评论 -
Dom型XSS跨站脚本攻击和防御
在前面的文章中,我们讲了持久型XSS和反射型XSS, 我个人觉得这些命名真的很贴切,反应了概念的本质。 无论是持久型XSS还是反射型XSS, 恶意的js脚本内容都需要由服务端返回给用户,今天我们要说的Dom型XSS却例外,一起来看看。原创 2020-07-05 10:52:28 · 8401 阅读 · 2 评论 -
反射型XSS跨站脚本攻击和防御
在前面的文章中,讲述了最好懂的存储型XSS攻击和防御,本文来聊聊反射型XSS,所谓反射,就像镜子一样,一束光发过去,立即弹回来。这里依赖于微博服务器存在反射XSS漏洞。那么,坏人C为什么不自己搭建一个反射服务器进行反射呢? 这是个好问题。以js获取cookie为例,如果坏人C自己搭建反射服务器,那么很显然document.cookie就无法获取好人A的微博cookie,所以,还是要用微博服务器做反射,这样才能获取好人A的微博cookie,从而进行攻击。原创 2020-07-05 10:51:32 · 6387 阅读 · 3 评论 -
持久型XSS跨站脚本攻击和防御
XSS原名CSS(cross-site script), 但与CSS(cascading style sheet)重名,所以就改名为XSS, 今天我们来了解一下XSS攻击和防御。 XSS的本质是:坏人C写了一个恶意js脚本,然后让好人A的浏览器去执行这个恶意js脚本,从而实现对好人A的攻击。XSS有持久型、反射型和DOM型。持久型XSS是最好懂的,危害很大,本文会以持久型XSS为例,来说明XSS攻击和防御方法。原创 2020-07-05 10:50:26 · 4522 阅读 · 3 评论 -
golang中的2006-01-02和ParseInLocation
看程序:package mainimport ( "fmt" "time")func main(){ timeFormatDay := "2006-01-02" nowTime := time.Now() endTime := nowTime yesterdayTime := nowTime.AddDate(0, 0, -1) beginTime, _ := time.ParseInLocation(timeFormatD...原创 2020-07-05 10:41:53 · 11098 阅读 · 2 评论 -
CSRF跨站请求伪造攻击及防御
产品的安全性,是第一位的。在之前工作中,坏人曾使用CSRF(cross-site request forgery)进行过恶意攻击,今天来聊一下CSRF攻击及防御。顺便提醒大家: 1.遇到不明链接,不要随意乱点。 2. 在登录银行网站后,要记得退出登录,而不是直接关闭网页。原创 2020-06-06 21:02:08 · 3500 阅读 · 4 评论 -
数据库事务ACID、隔离级别、悲观锁乐观锁
在银行系统中,数据库事务是必须的。在电商系统中,也是如此。 来看下A给B汇款100元的例子,可以看到,A账户扣款100元,此时如果进程崩溃或者机器掉电,那么这100元就没有加到B的账户中,自然会导致用户的强烈投诉。 如果先给B账户加钱,然后给A账户扣钱,会怎样呢?可以看到,此时如果进程崩溃或者机器掉电,银行白白给B加了100元,而没有扣减A的100元,只怕银行会亏得没裤子穿。原创 2020-06-06 21:00:16 · 3631 阅读 · 11 评论 -
第三方账号登录的原理
一个网站或APP, 如果没有用户,那就没有价值。所以,如何吸引用户注册和登录,是一个重要问题,这就涉及到账号体系了。 自建账号体系的注册和登录,前面文章已经讲过。可是,很多用户并不想注册你开发的网站或APP,此时可考虑用第三方账号登录,比如微信登录和QQ登录。从目前现状来看,微信用户数早已突破10亿,以微信作为第三方登录越来越普遍,微信开放平台对企业合作伙伴进行赋能,彼此互为依存,利益共享。原创 2020-06-06 20:58:59 · 5445 阅读 · 9 评论 -
注册登录原理及密码安全问题
安全性,是一个公司生死存亡的关键,华为、腾讯和阿里等公司,都有大量的技术人员来保障业务安全。平时工作中,一旦遇到安全问题,必须立即高优先级处理。安全攻防,是一个动态的博弈,没有攻不破的防守,也没有防不住的进攻。原创 2020-06-06 20:57:08 · 5097 阅读 · 5 评论 -
数据库主从复制和读写分离的原理及应用
数据库一主多从,是很经典的结构,对于容灾、可扩展性和高可用性,都是有好处的。主从复制后,可以认为,从库和主库的内容是"一致"的。然而,由于主从复制需要时间,向主库写入数据后,如果直接从从库读取,很可能读不到最新的值,但是,对读实时性要求不高的业务场景,读写分离是没有问题的。原创 2020-06-06 20:54:45 · 2726 阅读 · 2 评论 -
数据库连接池的原理及验证
池子,是一个很广义的概念,电池,酒池,水池,资源池,进程池,线程池,协程池,内存池,连接池,都是池子。今天,我们以MySql数据库为例,来说说连接池。我们知道,TCP的连接需要经历三次握手,TCP的关闭需要经历四次挥手,都需要耗费时间,而MySql的认证和关闭也同样需要耗费时间。自然地,我们想到了MySql连接的复用:把建立好的连接保留起来,用完后不关闭,放在池子中,从而形成连接池,下次需要用的时候,直接去连接池中拿连接。原创 2020-05-16 19:49:00 · 3441 阅读 · 6 评论 -
同步log比异步log的性能更好?
最近,有个接口有性能问题。意外发下,把异步log换为同步log之后,性能明显好转。 这有点搞笑呢。 后来发现,其实并不是同步log比异步log的性能更好,而是在换为同步log后,执行了重启操作,释放了累积的资源,导致性能变好。 呵呵哒,查问题就是这样,很多东西只是现象和表象,不是真正的原因。 不多说。...原创 2020-04-11 19:10:39 · 3533 阅读 · 2 评论 -
“网络问题“背的锅
服务A提供了一个接口: getXXX, 其中没有做任何操作,也没有打印log,收到请求后立即返回。 但是,调用服务A的接口getXXX发现,耗时偶尔比较严重。 开始以为是网络问题,后来发现不是网络问题,而是其它问题。 大家觉得有可能是什么原因呢? 欢迎讨论。 已经至少两次遇到类似问题了---资源泄露! 不多说。...原创 2020-04-11 18:46:34 · 2468 阅读 · 6 评论 -
从cat a.txt | grep -E "[5-9][0-9]{2}ms"看linux小命令的大用途
最近查一个耗时的问题,需要在log中过滤出耗时在500ms-999ms之间的log, 假设文件a.txt的内容如下:ubuntu@VM-0-15-ubuntu:~$ cat a.txtxxx 1ms yyyagag aga 2ms zzz300msagagagxxx agag agaga 600ms 直接用grep加正则表达式搞起:...原创 2020-04-11 17:07:24 · 3042 阅读 · 2 评论 -
最近碰到概率性的http 403错误
最近,跟国外一个公司进行联调,需要调用他们的https接口,我在调试时发现,每次调用他们,都会概率性出现403错误,从直观上看,肯定就要找他们帮看具体原因了。 我问了一下对方,但他们非常不responsive,其实,只要他们看一下log或者返回403的逻辑,就很容易知道问题。没办法,只能我自己猜测并尝试。 考虑到他们的接口有IP白名单机制,所以我怀疑是...原创 2020-03-21 18:39:11 · 4221 阅读 · 5 评论 -
如何查看tcp连接的建立时间?
在进行服务性能分析时,有时需要确认连接池、长连接、短连接相关的问题,需要查看tcp连接的建立时间? 怎么看? 1. 以如下tcp链接为例:ubuntu@VM-0-15-ubuntu:~$ netstat -nap | grep -i esta(Not all processes could be identified, non-owned process info...原创 2020-03-06 22:29:16 · 14876 阅读 · 10 评论 -
用Little‘s Law理解系统的QPS、耗时、并发数
我们先看Little's Law: 在一个稳定的系统中,设长时间观察到的平均顾客数量为L,长时间观察到的有效到达速率为λ,平均每个顾客在系统中花费的时间是W,则有如下关系式: L= λW原创 2020-01-31 20:26:36 · 3079 阅读 · 1 评论 -
多进程、多线程、多协程对单核、多核CPU的消耗
搞后台开发,不仅需要关注服务的功能,还需要关注服务的性能。在本文中,我们简要地来看看多进程、多线程、多协程对单核、多核CPU的消耗。在多核情况下,采用多进程、多线程、多协程,能更好地利用CPU, 它们不仅能并发执行,而且能并行执行。原创 2020-01-31 20:14:56 · 5252 阅读 · 2 评论 -
深入理解linux free命令及内存含义
对于软件开发(尤其是后台开发)工程师而言,不仅需要关注服务器的CPU,还需要经常关注服务器的内存。 在之前的文章中,我们探讨了CPU的参数,并且弄清了CPU核相关的一些概念。在本文中,我们来聊内存。原创 2020-01-31 20:09:51 · 6067 阅读 · 4 评论 -
深入理解计算机CPU的参数: CPU主频、多个CPU、多核CPU、逻辑核(超线程)、 大小端
对软件开发(尤其是后台服务开发)工程师来说,这几个概念几乎是必须要缕清的:CPU主频、多个CPU、多核CPU、逻辑核(超线程)、大小端。本文我们会逐一来聊聊。 在之前的文章中,我们见过古老的4004CPU,也分析过古老的8086CPU,并对它进行了汇编语言编程。它们都是单核的(每个CPU只有1个运算器&控制器)。 那么,现代CPU长啥样子呢?原创 2020-01-08 21:46:51 · 14278 阅读 · 4 评论 -
etcd锁释放超时导致的数据不一致性
服务端代码: func proc() { begin lock begin transaction amount := queryAmountFromDb() amount += req.OrderAmount setToDb(amount) end transaction // 正...原创 2019-11-09 21:24:10 · 3050 阅读 · 7 评论 -
#define likely(x) __builtin_expect(!!(x), 1) 性能测试
看linux源码或者一些优秀组件的源码,经常碰到likely和unlikely, 其实很简单,无非就是显式告诉编译器怎么去优化。有兴趣的话,可以看看对应的汇编。下面,我们来实际测试一下likely/unlikely的性能优化效果:#include <stdio.h>#include<sys/time.h> #define likely(x) __bu...原创 2019-11-02 20:37:55 · 4095 阅读 · 9 评论 -
异步log让人临时怀疑人生------log是现象,还可能是假象,不可全信
在之前的博文中,多次说过:log是现象,还可能是假象,不可全信。 在实际开发中,见过太多太多这样的案例。 来看看最近遇到的一个让人临时怀疑人生的问题, go伪代码如下:type Money struct { Principal int}func main(){ p := new(Money) p.Principal = 10 log.Infof("...原创 2019-11-01 20:59:26 · 3036 阅读 · 4 评论 -
golang defer的那些坑爹事儿
先来一个最简单的:package main import ( "fmt") func f() { i := 1 fmt.Println("i1 is", i) defer fmt.Println("i2 is", i) defer fmt.Println("i3 is", i)}func main(...原创 2019-11-01 20:01:10 · 2473 阅读 · 3 评论 -
log丢失之谜
最近,遇到这样一个问题: a文件:func main(){ log.Infof("begin") y := sub(100, 20) log.Infof("end, y is %d", y) return} b文件:func sub(x, y int) int { log.Infof("sub begin") return x - ...原创 2020-03-06 22:31:43 · 2879 阅读 · 6 评论