- 博客(291)
- 资源 (30)
- 收藏
- 关注
翻译 Testivus On Test Coverage
原文:点这个链接Testivus On Test Coverage一天早上,一个程序员问大师:我准备要写单元测试了,请问我要达到多少覆盖率呢?大师回答说:不用担心覆盖率了,写出来有效的单元测试就好了。程序员笑了,向大师鞠躬,然后愉快的去干活了。过了一会儿,第二个程序员向大师问了同样的问题。大师指着小米牌智能电饭锅,对程序员问道:我该放多少米呢?程序员迷茫的回答道:我怎么知道呢?这处决于多少人吃饭,他
2017-07-06 15:17:00 2271 1
原创 GOLANG使用Context实现传值、超时和取消
原文:https://gocn.io/article/373GO1.7之后,新增了context.Context这个package,实现goroutine的管理。Context基本的用法参考GOLANG使用Context管理关联goroutine。实际上,Context还有个非常重要的作用,就是设置超时。比如,如果我们有个API是这样设计的:type Packet interface { e
2017-06-28 16:25:22 14424
翻译 Fire And Motion:聚焦前进,避免当炮灰
Fire And Motion2002年01月06日,JOEL SPOLSKY,Trello联合创始人,如果大神你不知道Trello是什么,那么你肯定知道Stack Overflow,嗯,我是StackOverflow的CEO。有时候,我就是啥事也没有干出来,啥事也没有干成。和你一样,我每天可是准时按点到公司,到处晃悠晃悠,然后回到我的座位上,每隔几分钟看看邮箱,然后看看微信朋友圈,读读今日头条,有
2017-06-26 13:49:53 1872 1
原创 GOLANG宽泛接口在测试中的大用处
原文:https://gocn.io/publish/article/368考虑测试一个函数:func request(ctx context.Context, hc *http.Client, api string) (err error) { var hreq *http.Request if hreq, err = http.NewRequest("GET", api, nil
2017-06-23 17:27:31 903
原创 GOLANG测试必须用带堆栈的errors
原文:https://gocn.io/article/366GOLANG测试时,可以用匿名对象填充测试序列,但是如果没有带堆栈的errors,那么会造成出现错误时无法排查。先看测试序列的填充,参考tricks-2015这个文章,怕你翻不了墙,我把内容粘贴过来就是:Anonymous structs: test cases (1/2)These properties enable a nice way
2017-06-22 18:11:45 2495
原创 GOLANG最容易做测试MOCK
原文:https://gocn.io/article/353测试时,一些底层的库非常难以MOCK,比如HASH摘要算法,怎么MOCK?假设有个函数,是用MD5做摘要:func digest(data []byte, h hash.Hash) ([]byte, error) { if _, err = h.Write(data); err != nil { return nil
2017-06-09 18:27:32 12659
原创 GOLANG空指针崩溃时堆栈消失和解决方案
原文:https://gocn.io/article/351在错误处理这个文章中,tkk提出了空指针时堆栈消失的问题,看下面的例子:package mainfunc main() { run() // line 4}func run() { causedPanic()}func causedPanic() { //defer func() {}() // line 1
2017-06-07 17:06:25 13292
原创 GOLANG错误处理最佳方案
原文:https://gocn.io/article/348ERRORGOLANG的错误很简单的,用error接口,参考golang error handling:if f,err := os.Open("test.txt"); err != nil { return err}实际上如果习惯于C返回错误码,也是可以的,定义一个整形的error:type errorCode intfunc
2017-06-05 10:06:41 12100
原创 函数式组合编程,完胜类体系编程
考虑打印MP4各种BOX的实现,一种是类似类体系,用函数重载来实现:template<typename T>stringstream& __srs_print_mp4_vector(std::vector<T>& arr, stringstream& ss, int level, bool is_box){ for (size_t i = 0; i < arr.size(); i++)
2017-05-30 18:33:47 947 1
原创 timeval和timespec转换
条件等待时,调用pthread_cond_timedwait,需要从timeval转换为timespec,如果转换错误,会导致条件等待失败返回22,正确的转换方式是:void wait(pthread_cond_t* cond, pthread_mutex_t* lock, uint32_t timeout_ms){ pthread_mutex_lock(lock);
2017-05-27 21:11:09 4249
原创 GOLANG使用Context管理关联goroutine
原文:https://gocn.io/article/333一般一个业务很少不用到goroutine的,因为很多方法是需要等待的,例如http.Server.ListenAndServe这个就是等待的,除非关闭了Server或Listener,否则是不会返回的。除非是一个API服务器,否则肯定需要另外起goroutine发起其他的服务,而且对于API服务器来说,在http.Handler的处理函数中
2017-05-19 15:09:06 2886 1
原创 GOLANG使用嵌入结构实现接口
原文:https://gocn.io/article/332考虑一个Packet接口,一般会返回一个Header,例如:type PacketHeader struct { ID uint32 Timestamp uint64}type Packet interface { encoding.BinaryMarshaler encoding.BinaryUnmars
2017-05-19 13:24:18 2759
原创 使用两个context实现CLOSE包的超时等待
原文:https://gocn.io/article/331在UDP中,一般发送者发送包后,如果一定的时间对方没有收到,就需要重传。例如UDP实现握手的过程,如果握手的包,比如RTMFP协议的IHELLO,发送给对方后,如果一定1秒没有收到,就应该重发一次,然后等3秒、6秒、9秒,如果最后没有收到就是超时了。最后一个Close包,发送者不能等待这么长的时间,所以需要设置一个较短的时间做超时退出。一般
2017-05-18 20:39:49 927
原创 GOLANG实现超时对象检测的最好理解的方式
原文:https://gocn.io/article/328依赖于心跳的系统,都需要超时检测。比如P2P系统中客户端每隔120秒向数据服务器发送一次数据汇总,服务器就需要维护一个超时时间。比如一个UDP服务器,在和客户端之间创建Session之后,如果没有数据包,一般会有Ping包,说明这个Session是存活的,服务器在发现Session超时后也需要清理。首先,服务器一般需要维护一个列表,以Pee
2017-05-16 17:40:57 2895 1
原创 GOLANG接口适配,组合方式的灵活接口演化
原文:https://gocn.io/article/326在OO(Object Oriented)原则中,有一条叫做:优先使用组合,而不是继承。虽然GOLANG并不是OO的语言(没有继承和多态),但是不妨碍GOLANG使用这条原则,而GOLANG的作者就强调过这一点,在GOLANG中是使用组合而非继承来扩展。装逼的说来,继承是一种名词化的语言体系,先进行业务抽象然后设计类体系和继承关系。而组合,强
2017-05-15 20:54:06 1896
原创 GOLANG简单类型定义,在协议解析的妙用
在协议解析中,经常需要用到转换不同的含义,比如声音的采样率,在FLV中定义和AAC中定义是不同的。在FLV中只有4中采样率5512, 11025, 22050, 44100。而在AAC中有16种采样率96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350(还有4个是保留的)。也就
2017-05-11 15:41:54 4039
原创 GOLANG实现类似C++模板,返回符合类型的对象
原文参考:https://gocn.io/article/319在协议解析中,C++的模板有比较大的作用,有时候我们希望丢弃所有的包,只留下特定类型的包。参考SRS的代码SrsRtmpClient::connect_app2:类型系统的设计, SrsConnectAppResPacket继承自SrsPacket:class SrsPacket;class SrsConnectAppResPacke
2017-05-09 20:20:57 3036
原创 GOLANG的context和并发模型
GOLANG1.7新增了context,最初这个package是在golang.org/x/net/context中的,后来证实对很多程序都是必须的,就纳入了标准库。对context的介绍是在context,读这个blog之前,要先读pipelines(pipelines提出了使用close(chan)的方式广播退出事件)。一般来说,context是用在request的处理,例如http请求的处理中
2017-05-03 19:27:13 4218 2
转载 The Log: What every software engineer should know about real-time data's unifying abstraction
转一篇KAFKA的英文文章:https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying
2017-04-26 09:38:11 1004
原创 HLS AAC音频爆音噗噗滋滋的原因
HLS AAC Muxer Issue很久以前,我就看到NGINX-RTMP,在将RTMP转换成HLS时,重新计算了AAC的时间戳,比如44100的采样率,RTMP的Audio包大约是23毫秒一个,NGINX重新计算90000*1024/44100.0=2089.7959,如果直接将RTMP转成TS时间戳应该是23*90=2070可见有19个时间戳单位的误差,因此会导致噗噗的杂音。如果是8000或1
2017-04-16 21:40:50 5966
原创 关于GOLANG的chan
GOLANG CHANchan是golang中非常重要的一个东西,用来做goroutine的通信,因为golang程序必然会有多个goroutine,如何同步这些goroutine就很重要了。使用chan时有几个心得:首先,永远是符号<-进行读取或者写入,譬如v,ok := <-c是读取,而c <- v是写入。其次,读取时,如果没有ok,也是可以读取的。不过如果closed也是能读的,没有赋值而
2016-08-06 23:31:22 6308
原创 关于C++ std::string如何增加数据
C++的std::string,和C的char*不一样,string是个char*和size,所以string里面能存任何char,包括NULL或(char)0都可以存里面,string并不依靠NULL或(char)0指定size。string能用做payload,譬如rtmp的video和audio的payload,也就是音频和视频数据,是可以直接用string存储的,而且能避免内存拷贝,不用自己
2016-08-05 12:33:56 8761 2
原创 家书两封
2016年7月2016年7月,支持老爸老妈阿姨姨夫买马(买地下六合彩,风行于农村的一种榨取农民血汗的诈骗方式)娘,你买马我是支持的,原因我告诉你。首先,辛苦了一辈子了,玩一玩没有过错,就像打牌一样,赢了输了都没事,就算去澳门赌博,我也支持,大不了就是倾家荡产,为了娘老子开心,有什么关系?辛苦了一辈子,玩一玩无所谓的。当年你住在那个理发店里,阴暗又潮湿,和老冠的赚那么点钱,不管有没有把我培养成世界级的
2016-08-05 09:36:24 1162
转载 [GoBlog] Defer, Panic, and Recover
The Go Programming LanguageDocuments Packages The Project Help Blog Next articleGo Wins 2010 Bossie AwardPrevious articleShare Memory By CommunicatingLinksgolang.orgI
2016-07-12 10:53:00 772
原创 FFMPEG如何使用LIB-FDKAAC解码
LIBFDKAACFFMPEG默认是用的内置的AAC解码器,而不是使用lib-fdkaac解码。可以编译debug版本的FFMPEG,然后gdb调试时直接用lib-fdkaac解码。FFMEPG DEBUG编译FFMPEG时,configure时加入几个选项就会编译debug版本的FFMPEG:--disable-optimizations--enable-debug=LEVEL--disabl
2016-06-24 09:58:50 8626
原创 论golang的文档即代码
GO TEST如果提供一个库,或者提供了一个模块,如何给使用者描述这个API的用法?一般都是给文档,但是文档非常容易不同步,在golang中,有更高级的做法,也是最好的做法。以go-fdkaac为例,这个是一个go binding,调用了lib-fdkaac的c函数,提供aac的codec的一个库。首先,因为设计到了如何下载fdkaac的c代码和编译,需要在doc中说明,也就是README.md中说
2016-06-22 17:13:40 1509
原创 2016年WINLIN研发和团队计划
2016年团队计划就是翻倍,WINLIN的研发计划就只有三点:HLS+,UDP传输和AndroidP2P,剩下的时间就是:吹牛装逼、种菜养鸡~
2016-02-13 16:52:05 5604 16
原创 技术债务终于还得差不多了
这周把License授权给改了,由8个文件变成了3个,由2个工具变成1个,1515行觥筹交错的代码变成了1175行秩序井然的代码,维护难度由没有维护的无穷大变成很容易看得懂,支持的license长度由117字节变成无限,支持的授权方式由文件变成文件和网络。这标志着我们技术债务还得差不多了,很快都是容易维护的社会主义产物了。无债一身轻啊!无债一身轻啊!无债一身轻啊!重要的事情说三遍,重要的事情说三遍,
2016-01-29 13:02:13 2889
原创 C代码对比,走心和不走心的程序猴
C估计是最普及的,几乎写代码都会抡两行出来,一听说写C写了240个月,那就得当面磕头,我还真见过时间越长代码越烂的(这个和英语4级是一样,大一过4级最容易,大四几乎很难过,因为从高中毕业就开始退化),所以我要说,好的代码和年纪没有关系,有些人就是好,有些人就是差,而且永远都不会长进。对比下一个程序,从RSA的公钥里面取出公钥来,打印出来,这个其实就没啥功能,也能看出来水平高低?是的。#include
2016-01-27 17:49:33 2951 2
原创 RaspberryPi和Arduino温室恒温改进
前一篇文章使用RaspberryPi和Arduino控制温室的温度,发现树莓派读取温度是总会出错,原因在于DHT11的控制协议是微秒级别的,但是树莓派达不到,因此改成传感器都有Arduino控制,树莓派和Arduino之间使用串口通信。Arduino上运行的程序如下:Arduino Commander,这个程序用到了SimpleSerial和SimpleDHT这两个库。树莓派上运行的程序是:Rasp
2016-01-24 00:34:33 2742
原创 RaspberryPi和Arduino控制温室温度
树莓派给Aruduino供电,通过PL2303芯片USB转TTL串口通信。Arduino的代码如下:void setup() { pinMode(3, OUTPUT); Serial.begin(115200);}char v;void loop() { // read from serial, // when got nothing, delay 1s and retry, w
2016-01-22 00:23:00 4069 1
原创 RaspberryPi2树莓派USB转串口连接Arduino
PI通过USB转串口连接Arduino我用树莓派2连接Arduino,然后通过Arduino控制继电器和其他设备。 树莓派连接Arduino大致有几种方法:TTL串口直接连接,有人说需要转电平,我没有试。I2C或SPI连接,我没有试。USB转TTL后,TTL连接Arduino,我用的这种方法。下面是用到的各种物件:树莓派2:http://item.jd.com/1646034971.ht
2016-01-20 00:09:04 11097
原创 RaspberryPi+Raspivid+FFMPEG软件编码数据
RaspberryPi+FFMEPGRaspberryPi的摄像头模块是500万像素,加载驱动后可以用ffmpeg编码设备/dev/video0输出流。FFMEPG摄像头的驱动是在树莓派的内核中的,不用下载和重新编译,直接加载:sudo modprobe bcm2835_v4l2可以看到设备就存在了:winlin@raspberrypi:~$ ll /dev/video0 crw-rw----+
2016-01-15 13:25:19 8506 1
原创 RaspberryPi自动连接多个无线,并且自动汇报IP
如何让树莓派自动连接Wifi,并且将自己的IP汇报给公网(或者内网)服务器呢?每次都连接显示器,或者串口TTL去查IP,觉得太麻烦了。自动连接Wifi我写了个程序raspi-wlan,可以自动连接Wifi,测试可以和EDUP N8508GS直接使用。买了这个无线网卡,然后插上USB后,需要将raspi-wlan下载到树莓派,并添加到自动启动。第一步,安装GIT:sudo apt-get instal
2016-01-12 21:55:17 3355 2
原创 [MarkDown]还是使用tcmalloc检查内存错误
Google的tcmalloc可以做内存越界检查,也就是查野指针。野指针是应用程序最难查的崩溃的问题。google真的很强大,赞!基本原理就是在分配时分配到页的底部,这样越界时就会报错了。也就是PAGE_FENCE,这个选项是可以通过环境变量设置的,代码在:src/debugallocation.cc: 101DEFINE_bool(malloc_page_fence, EnvToBool
2016-01-05 12:31:03 5478 2
原创 golang的bufio用于内容解析
golang提供了io.Reader,也就是读内容,可以从很多地方读,譬如:// from string.var r io.Reader = strings.NewReader(string("hello, world"))// from bytes.var r io.Reader = bytes.NewReader([]byte("hello, world!"))// from bytes
2016-01-03 14:10:01 7595
原创 RTMP转HLS音频爆音的问题
早在SRS1.0支持HLS的时候,就剽窃nginx-rtmp的HLS生成方式,对音频重新计算时间戳,代码在这里。当时还搞清楚了为什么不直接使用RTMP的时间戳,而要根据音频的个数、采样率和采样大小重新进行计算,大致说是精度不一样导致累计误差。在SRS2的时候,重新写了HLS部分,主要是把TS封装这块搞得比较清楚了,后来想到其实音频不必打时间戳,就累计在那里就好了,时间戳都打在视频上面的。SRS2发现
2015-12-01 11:38:54 3518 1
原创 RTMP转HLS音频爆音的问题
早在SRS1.0支持HLS的时候,就剽窃nginx-rtmp的HLS生成方式,对音频重新计算时间戳,代码在这里。当时还搞清楚了为什么不直接使用RTMP的时间戳,而要根据音频的个数、采样率和采样大小重新进行计算,大致说是精度不一样导致累计误差。在SRS2的时候,重新写了HLS部分,主要是把TS封装这块搞得比较清楚了,后来想到其实音频不必打时间戳,就累计在那里就好了,时间戳都打在视频上面的。SRS2发现
2015-12-01 11:10:11 593
原创 GO比较容易混淆的地方
GO比较容易混淆的地方GO在nil判断等方面容易混淆。nilGO的nil是带类型的,可以参考相关的文章。看下面的代码:import ( "io" "fmt")type MyWriter struct {}func (w *MyWriter) Write(p []byte) (n int, err error) { return}func main() { va
2015-11-30 10:46:32 1254
原创 GOLANG比较方便的地方
GO类型系统GO中很方便在基本类型上定义新的类型,这个虽然是个小东西,但是有时候非常好用。IsXXX经常需要定义这样的函数,譬如RTMP的消息IsAudio,IsVideo等等。如果是C++就需要定义个结构体,然后加函数:class SrsCommonMessage{public: SrsMessageHeader header;};class SrsMessageHeader{p
2015-11-20 10:22:43 8894
Pattern.Oriented.Software.Architecture.Volume.2
2012-11-29
mp4 file format引用文档
2012-11-04
The.Cpp.Programming.Language.Special.Edition
2012-10-29
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人