Re: [请益] 如何模仿专案

楼主: dannypsnl (秦书)   2019-02-24 11:37:21
关于这个,我可以分享一个我实际上做出来的side project: Rocket(https://github.com/dannypsnl/rocket)
最开始我的想法很简单,只是想知道后端的那些路由框架是怎么做的,当时我只会regex所以实作就只是一堆regex,用一个循环去跑regexp.MatchString
想当然尔这是个很烂的实作,如果我没有记错的话当时同样功能的路由执行时间是将近gin(https://github.com/gin-gonic/gin)的50倍,
简单来说就是个垃圾,没有比较快、没有比较方便、还有一堆不可用等级的bug相伴(主要是路由冲突很严重,顺序不同会引发不同的比对结果XD)
当时并没有真正的深入去研究路由比对究竟是怎么一回事,所以也就在开发不久后陷入停滞
后来会再度开发起这个东西是因为在前公司的经验,发现很多简单的接收JSON发送request到真正的处理者的程式码非常的重复,感觉大概就是
func(c *gin.Context) {
var user User
c.BindJSON(&User)
// verifying, ...
result := Request(...)
c.JSON(result)
}
所以我当时就把四处重复的验证放进被填充的那些结构里,这也就让我开始思考能不能让unmarshal本身也是自动触发的呢?
我可以展示一下自动unmarshal的范例:
type User {
Name string `json:"name"`
Password string `json:"password"`
}
func(u *User) {}
没错,就是直接用结构取代框架spec的context type
有了想达成的目标就有了重启专案的念头(原本应该会基于gin写一些lib来达成功能,不过没多久之后我就离职了,也就没有立即的需求,所以就变成了改造这个专案了)
第一步是修正那个问题百出的比对程式,所以我跑去查了怎么做超快的路由比对,发现了radix tree这个东西,
接下来我参考echo(https://github.com/labstack/echo)的实作,修改成了符合我的需求的结构,我只有用`/`分隔节点
,特别处理带有`:`, `*` prefix的部分(他们分别代表了variant跟wildcard),基于这个版本的测试已经进化到了约略是gin的1.5倍
Example:
/a/:a
/*b
/a/b -> /a/:a
/a/b/c -> /*b
后来我的朋友也加入开发行列,我们在这段时间没有特别关注效能,而是增加测试覆蓋率以增加功能,而且基本上加上越多需要执行的功能速度就会越慢,
到目前应该已经快变成gin的2倍了XD,另外开发期间 https://astaxie.gitbooks.io/build-web-application-with-golang/content/en/ 这个线上资源对我们有很大的帮助
,因为他踩了很多Golang net/http的雷点XD,让我们知道实作时需要注意的一些细节,目前下一步计划是让各个sub package能够被当成独立的lib去使用
我会说专案的成形需要一点时间,你可以看到最开始的时候我就是越级所以才会做不出来,但也是因为有去做才会有进步,与其花费心思思考什么会被打枪,
不如先动手做出东西试试。一年多前休学工作以来,我被打枪的次数可多了,英文不好、作品太废、算法不够强
模仿一个东西,出发点应该是弄清楚自己想要什么东西,就算看了程式码,那也不会是有用的参考,因为别人的程式库必然会有他们做出的抉择,
而这些抉择会舍弃一些功能以达到另一些特性,而这些如果不能过滤这些取舍,找出你想要的部分,那么有原始码也没有用,难不成要直接复制贴上?
而找出自己需要的部分是需要理解自己的需求的,而这是只有你才能做到的事情。
累积经验是很重要的,虽然我有个专案一直被吐嘈这到底能干嘛啦,但事实上rocket的unmarshal的部分能被抽取出来就是因为我该专案大量使用reflection,
让我知道reflection完全可以做到我想要做的功能,否则我根本想不到可以那么做
而分割问题也是非常关键的技巧,一般来说我会写一些pseudo code来验证一个程式接口可行,再根据一个可行的接口编写简单的、不完整的实作,
这个实作会伴随着一个特例作为测试,接下来我会把程式修改成通用的版本,移除原先的假设,为绝大多数的情境运作,
这时候第一个特例就能检查这个正确的版本是不是真的那么正确
最后我想相较于作品到底有多厉害,我想真正重要的是当人们问你:“为什么你要做出这个东西?”的时候,能够言之有物的说出你到底学到了什么
作者: oneheat (等待)   2019-02-24 13:31:00
gin用httprouter, 该router有benchmark结果,衡量单位是ns.....
楼主: dannypsnl (秦书)   2019-02-24 15:04:00
你是说几倍的部分吗,我是用回应时间除的啊,我的意思是耗时是gin的几倍XD

Links booklink

Contact Us: admin [ a t ] ucptt.com