作者dannypsnl (秦书)
看板Soft_Job
标题Re: [请益] 如何模仿专案
时间Sun Feb 24 11:37:21 2019
关於这个,我可以分享一个我实际上做出来的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来验证一个程式介面可行,再根据一个可行的介面编写简单的、不完整的实作,
这个实作会伴随着一个特例作为测试,接下来我会把程式修改成通用的版本,移除原先的假设,为绝大多数的情境运作,
这时候第一个特例就能检查这个正确的版本是不是真的那麽正确
最後我想相较於作品到底有多厉害,我想真正重要的是当人们问你:「为什麽你要做出这个东西?」的时候,能够言之有物的说出你到底学到了什麽
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 114.36.84.238
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Soft_Job/M.1550979448.A.5E1.html
1F:推 oneheat: gin用httprouter, 该router有benchmark结果,衡量单位是n 02/24 13:31
2F:→ oneheat: s..... 02/24 13:31
3F:→ dannypsnl: 你是说几倍的部分吗,我是用回应时间除的 02/24 15:04
4F:→ dannypsnl: 啊,我的意思是耗时是gin的几倍XD 02/24 15:06