LeeYzero的博客

业精于勤,行成于思

0%

之前虽然看过很多分布式系统相关的书籍、论文和一些开源项目,但很少自己动手去实现。理论跟工程实现通常有非常大的差别,一个看似很简单的协议,在工程实现上可能非常困难。6.824是MIT开设的分布式系统课程,非常系统的讲解了分布式系统的主流技术,同时将理论和实践相结合,是一个非常好的课程。

本文是笔者在学习6.824 lec1课程的一些总结和思考,算是一个学习笔记。在看这篇文章之前,我希望读者先提前阅读以下资料:

本文主要分三个部分,第一部分概述性的介绍mapreduce的原理;第二部分概述性的介绍mapreduce的实现;第三部分介绍工程实现上需要注意的一些问题,完整代码实现参考github

Read more »

在现在生活中,我们经常在使用文件上传功能,但我们很少会自己去做一个文件上传的服务,了解文件的上传原理有助于我们开发出更健壮的程序。利用Go语言以及其标准库的能力,用很少的代码量就可以实现一个文件上传服务器。本文以小工具的方式讲解如何实现一个简单的文件上传服务器,并假设读者对Go、HTTP、HTML有一定了解。

完整代码参考:github.com/leeyzero/go-tools/uploadserver.go

Server端

文件上传一般使用multipart/form-data上传上传,Go语言标准库其进行了良好的封装,感兴趣的可以直接查询其原码实现。对于文件上传服务器,需要搭建一个简单的服务端框架,幸运的是Go语言http包已经为我们实现了,我们只需要实现一个handler即可,

1
2
3
4
5
6
7
8
func uploadHandler(w http.ResponseWriter, r *http.Request) {
...
}

func main() {
http.HandleFunc("/upload", uploadHandler)
http.ListenAndServe(":8080", nil)
}

在uploadHandler中,只需要进行以下三个步骤:
1、解析multiform data
2、遍历multiform data中的文件
3、将文件保存至指定位置

Read more »

开放授权(OAuth, Open Authorization)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表等),而无需将用户名的密码提供给第三方应用。OAuth2.0是OAuth的2.0版本。本文主要介绍OAuth2的授权流程。

名词解释

  • Resource Owner:资源拥有者
  • Resource Server:资源服务器
  • Client:客户端
  • Authorization Server:认证服务器
  • User Agent:用户代理,通常指浏览器

场景

在现实生活中就存在OAuth的场景:快递员给你送快递,但他进不了小区,他只能按下你家的门牌号,然后你通过摄像头确认他的确是给你来送快递的快递员,然后你给它解除门禁,快递员就能进入小区了给你送快递了。

在这个例子中,你就是资源拥有者(Resource Owner),小区内基础设施可以理解为资源(Resource),物业就是资源服务器(Resource Server),快递员是客户端(Client),门禁就是认证服务器(Authorization Server)。

你是受认证的业主,可以通过门禁卡、人脸认别等方式自由进入小区。但快递员不是业主,也想进入小区,怎么办呢?你可以直接把门禁卡给他,但这样不安全,所以门禁系统推出一个授权的功能,就是快递员先向你请求要进入小区,经过你的授权后再给他开门。如果你的快递比较多,这个快递员每天都要来送快递,每次都要你给他授权也比较麻烦,然后门禁系统又推出一个带有效期的临时出入卡,比如有效期一个周,那快速员就可以在这一个周之内自由出入小区了。

以上场景就是OAuth授权的原理,为了贴合互联网应用场景,OAuth制定了一套开放标准。

Read more »

Gin是一个用Go语言实现的高性能web框架,其API实现优雅,性能卓越,上手简单,而且比较轻量级,很容易引入到项目中。本文是一篇对Gin框架的学习笔记,不会对Gin框架的用法做面面俱到的,而是对Gin框架做一个整体上的认识与入门。

安装

1、首先需要先安装Go,依赖版本为1.13+,执行下面命令安装Gin:

1
$ go get -u github.com/gin-gonic/gin

2、在代码中引入Gin包

1
import "github.com/gin-gonic/gin"
Read more »

最近断断续续花了一个月时间看了一遍数据密集型应用系统设计,也就是大家所说的DDIA(Designing Data-Intensive Applications)。这是一本一看就停不下来的书,强烈安利做业务系统的同学看看。那这本书到底在讲什么呢?

数据模型是对现实世界的抽象,可以从微观角度理解为“数据结构”,它是一个应用系统中最重要的部分。数据模型在一定程度上会影响到系统设计人员解决问题的方式。关系型数据库在很长一段时间大行其道(虽然NoSQL越来越流行,但关系型数据库仍然有一席之地),通常我们在做系统设计时首先会对现实对象建模,建立对象之间的关系,以便能更好的用关系型数据库来表现。然而从这本书中我们可以看到,关系型数据库并不是惟一的数据模型,在做系统设计的时候,不应该受具体数据模型影响,了解各数据模型的优缺点和应用场景,有助于我们设计更具可靠性、可扩展性以及可维护性的系统。

一句话概括:这是一本介绍各种数据库原理及其应用的书

具体来讲,本书从可靠性、可扩展性和可维护性角度展开,介绍各类数据库原理和应用。全书一共分成了三个部分:

Read more »

今天从老东家离职了,在老东家度过了人生中黄金的5年,细细想来,虽然走了很多弯路,但最终走到了正确的道路上。关于为什么要离职,其实是一个值得思考的问题。按照马云爸爸的说法,离职无非是两种原因:要么是受到委屈,要么是为了钱。诚然,我目前还没有脱离这个层次,但经过8年的社会工作洗礼,至少还对其它的追求有点念想,希望5年后再看这篇文章时不会被生活磨平了棱角。

这次离职更多的还是个人职业发展问题。对个人职业发展还是有一个比较明确的目标,但在执行路径上其实并不是很清晰。每一次选择都是为了向目标最近一点,但这个选择是否正确,短期来看其实是很难判断的。对于离职,有几个值得思考的问题,虽然自己有做过思考,但还未做理性的分析。这几个问题是:

1、离职是不是在逃避问题?
2、从A团队离职的原因?针对这些原因有没有去做改变?
3、在B团队会不会有同样的问题?针对这些问题又将如何去应对?
4、2-3后,你想成为什么样的人?
5、你内心的源动力是什么?如果只是靠外界驱动,这种驱动力是不稳定的。

对于这些问题,的确值得思考,有些问题其实是有明确答案的,有些问题直到目前也还没有想得很清楚,这其实是一种思维惰性,也可以说是自己的天花板,目前正在想办法突破,也算是今年的一个小目标吧。先将问题记录于此,也供网友参考,待到自己真正想清楚那天,再写一篇文章回答这些问题,希望这天不会太久!

简介

并发是Go语言最重要的语言特性之一,是Go语言区别于其它语言的重要特征。Go语言原生支持并发,可以充分发挥多核CPU的机器性能,同时在语言层面上,Go以十分简洁的语法提供丰富的并发能力,让并发编程并得简单。本文总结Go语言并发编程的常用模式,模式也就是我们说的套路,先学会模仿,再学会融汇贯通,最后才能创造出新的模式,这就是所谓的无招胜有招吧。

Go对并发的支持

对于桌面客户端应用程序,为了提升客户端的运行效率和简化多线程编程,通常的做法是在客户端启动时,启动三个常驻线程,分别是UI线程,逻辑线程和IO线程。每个线程维护一个事件循环,线程之间通信(数据传输)只能通过消息队列进行传递,消息队列是线程安全。

这么做主要有两个好处,一是常驻线程避免创建和销毁线程的开销,多核情况下,通常没有线程上下文切换,线程运行效率高。二是通过消息队列传递数据,各个线程对数据进行操作时不用所以资源竞争问题,这极大降低了多线程编程的难度,并且设计出的程序也更简单,更容易理解。

接触到Go之后,才知道这种编程模型其实就是C. A. R. Hoare的Communicating Sequential Processes, CSP。Go语言原生支持并发(goroutine)和通道(channel),并且还提供了select对多路通道进行控制,极大简化了并发编程的难度。

接下来,本文将介绍Go并发编程的常用模式。本文并不适合没有Go语言基础的读者,在阅读以下内容前,请先查阅以下内容:

Read more »

最近又看了一遍 End-To-End Argument In System Design,有一些新的思考,但都集中在一些点上,不够系统,在此先记录下来,后续有新的想法再做补充和整理。

核心观点

这篇论文在由MIT计算机科学实验室发表于1984年,是一篇非常经典的关于系统设计的论文。论文论证了分布式系统设计的一个事实:端到端的可靠通信只能由通信的两端(End-Point)来保证,而中间的媒介(如消息中间件、网关、路由器以及TCP协议栈等)只能提高通信效率,但无法保证通信两端的可靠性。

在一个系统设计中,系统设计师的主要工作是对功能进行合理抽象,明确定义功能边界。将功能职责进行合理划分的设计原则是系统设计师最重要的工具之一,端到端设计原则便是这样的工具,它在分布式系统设计中,对功能职责的划分起了一定的指导作用。

Read more »

文件同步是利用网络将多个电脑或移动设备之间的文件进行同步的网络服务。文件同步的本质是对比网络上两台设备之间的文件变更,然后将文件的不同部分通过网络进行传输,以达到文件同步的目的。本文介绍dropbox的文件同步实现原理。

基本概念

文件系统

在本地电脑上,一个文件可以用文件路径来标识。但对于dropbox需要支持共享目录,定义了名字空间(namespace)的概念,用于对传统文件系统的抽象。每一个共享目录有一个惟一的名字空间,每个用户有一个根名字空间,每个共享目录可以挂载(mount)到不同的用户根名字空间下。即对于dropbox的文件可以通过名字空间和相对路径<namespace,relative path>惟一标识。

文件格式

rsync算法的启发,dropbox把每个文件被分割成4MB的块(最后一个块小于等于4MB)。每个块通过计算出的SHA-256进行标识,对于每个文件内容,可以通过一个块列表blocklist引用。比如,文件video.avi大小了14MB,可以分割成4个块h1, h2, h3, h4,我们说文件video.avi的块列表blocklist是[h1, h2, h3, h4],如下图:

image

Read more »

最近关于B站在北邮校园招聘时,面试官对候选人打压的事件在知乎上讨论的很激烈。我并不想讨论这些言论的真假,但从这件事件反映出了B站面试官的不专业性。本文结合自身的一些招聘经验,从面试官角度谈谈应该如何面试候选人。

人才标准

每个公司或团队都有一个正式的或非正式的人才要求,即你想要雇用什么样的人?这是招聘的总体准则,这个准则因公司或团队而异,但可简单的概括为:聪明且会做事情的人

聪明和会做事情的人并不能划等号。有的人的确很聪明,但并没有将其聪明才智用到正确的地方,容易分散团队的精力;只会做事情的人往往缺乏自己的思考,容易人云亦云,很难有培养空间。

在面试的时候是可以区分出这两种类别的人的。聪明的人在沟通过程中比较顺畅,逻辑思维清晰,语言组织有条理,反映比较敏捷,对开放性的问题有自己独到的见解;会做事情的人通常需要从其过往学习、工作经验中进行考察,会做事情的人通常有始有终,对待工作认真尽责,有较强的团队合作能力。

Read more »