主页

博客迁移

距离首次开通这个博客已经过去了四年时间。四年前我还在学校,每天畅想着美好未来,现在成了一个日渐肥胖的辛苦打工人。 记得刚知道能够搞github博客的时候还是很高兴,觉得能够白嫖github的服务器搞一个自己的网站,什么都自己设计,不是很爽吗。于是用hexo整了这个博客,然后用markdown写文章。后来又白嫖了百度的网站分析看看每天的pv, uv,进入来源,用户地域等数据。在这个网站也结识了一些从

Go二分查找sort.Search

之前对Go sort包的印象一直是只能做排序,毕竟包名就叫sort嘛。后来在一次刷leetcode的时候,发现官方题解做二分搜索的时候用了sort包里的Search函数,惊讶sort包还封装了二分查找功能。于是看了下sort.Search的源码,发现源码其实也写的很简单,就是一个普通的二分: 12345678910111213141516func Search(n int, f func(int)

ElasticSearch 数组去重

往ES某个字段中插入值时,有时候需要对结果进行去重,即需要这个字段里所有的值是互异的。而ES又没有Set这样的数据结构,所以需要在插入的时候执行脚本来实现这样的功能。 在参考了ES官方文档Script后,可以很容易写出这样的脚本,假设values字段是数组类型的,需要存储去重的值: 1234567List values = [];if (ctx._source.containsKey('value

Elasticsearch sum和group by(aggregation)的集成

Elasticsearch的API是RESTful风格的,传入json风格的DSL就可以进行很多种操作。然而DSL的语法和格式实在是有些太过复杂,对于新手来说难以快速掌握,所以有时候会用ES的SQL接口写一些SQL来进行查询。然而ES对SQL的支持并不是很完备,所以学习一点DSL的语法还是有必要的。简单的一些查询和插入方法在网上很容易搜到,但是一些比较高级的操作和他们的组合操作就有可能搜不到了。比

Go单个字节(byte)转字符串(string)的一点坑

最近遇到一个小问题,由于某个api只支持写入string,而我生成的压缩后的数据都是一个字节的byte,所以不得不将byte转成string。于是写出了如下的代码: 1s := string(b) // b is byte 这样只要b在00000000 到11111111之间,编译是不会报任何问题的,随便写了几个ut也没有问题,于是提交了代码。等到部署后发现,数据量比预估的大了很多,于是仔细rev

记一道动态规划+数学期望的算法题

最近碰到一个算法题,开始觉得很简单,后来觉得有点难,后来做了做发现其实没有那么难,感觉有点意思。在这里分享一下这道题和解题思路。这道题的题目如下: 一个n*m的网格,每个格子上有三个参数pD,pR,pS。pD表示下一步走到下方格子的概率,pR表示下一步走到右方格子的概率,pS表示下一步仍然在原地的概率。0<= pD, pR, pS <=1,pD+pR+pS = 1。从左上角格子到右下

用etcd做服务发现(service discovery)

什么是服务发现服务发现其实有两层含义,第一层是实例发现,第二层是端口发现。如果有两个服务A和B,两个服务都是分布式系统,在某个时刻服务A作为客户端要请求服务B,那么这时从服务A中的某个实例(instance)Ai就要访问服务B中的某个实例Bi,那么Ai找到一个合适的Bi就是服务发现的第一层含义,即实例发现。Ai找到合适的Bi后其实还没完事,Ai需要知道Bi响应这个请求的应用程序,也就是说需要知道B

Go语言slice前置插入(prepend)的坑

最近在工作中遇到一个需求,抽象为数据结构的问题就是:对于一个只记录了前向节点的链表,把其中所有节点的值转化为一个数组,数组需要保持原链表中各个值的顺序。也就是一个链表节点的数据结构长这样: 1234type ListNode struct { Val int Prev *ListNode} 需要向前遍历这个链表,用一个slice记录其每个节点的值,并且保持值在链表中

如何设计一个分布式限流器(distributed rate limiter)

Rate Limiter限流器(rate limiter)是一种在实际工程中广泛应用的组件,其主要作用就是限制上游服务的请求量。比如一个公司有两个服务:服务A和服务B,服务A需要经常请求服务B,那么服务B为了保证自己不被来自A的异常高的请求打挂(即是现在分布式系统时代做自动扩容很快,但对于TPS较大的服务来说这些异常高的请求量仍然是有显著影响的),就会和服务A协商,定一个服务A的TPS阈值,设置限

Go的奇特之处2--Go语言的slice

Go语言中的slice,你可以将它简单地看作一个动态数组。动态数组在很多语言中都有实现,比如C++中的vector<>,Java中的Array<>,Python中的[]。那为什么要说Go语言的slice奇怪?首先来回顾一下slice的基本知识: slice由三部分组成:首地址、长度len、容量cap 那么,根据slice的这些特性,slice有啥奇特的呢?首先,举个例子