之前我写过Beetl开源那些事情 ,最早是2014年写的。每篇都会对开源有不同的感悟,今天这篇应该是这个系列结束之作。
第一篇,2014年,Beetl开源那些事情,感慨开源艰难,国外开源做比国内开源更容易得到信任
第二篇, 2015年 Beetl开源那些事情2,建议开源不要给公司,自己独立自主,同时,也对小白很不爽
第三篇,2018年Beetl开源那些事情3,对国内开源的待遇感到不公平,同时也对开源有所总结,
第四篇,也就是这一篇,在人到中年的时候,总结一下开源11年的感触。
一转眼,Beetl已经开源11年了,从早期托管到sourceforge,到后来的github,然后再到gitee,如今Beetl已经演变成为模板类语言的天花板级别的实现了。无论其功能,性能,可定制性都是顶配的,是国外开源不能比的。每天Beetl的文档都会被打开2000次。独立访问用户上百人。这在现在动态页面不怎么流行的情况,这个浏览量还是非常高的
Beetl之所以是模板语言的天花板实现,是因为它满足了几乎对所有模板引擎的需求,有些如下特性是国外模板语言不具备的
自定义定界符和占位符
使得模板更适合特定文件,比如在htlm里可以定义<!--# -> 作为定界符,再比如在代码生成Java文件模板里,可以定义 //# 和回车为定界符。避免了freemaker那种生成代码模板出现xml标签怪怪的感觉
脚本语法和xml标签语法同时支持,实际上xml标签会被翻译成相应的脚本语法,类JS语法非常容易学习。Freemaker只有XML标签,Velocity等只有脚本语法。
高性能执行引擎。
Beetl提出和借鉴了很多Java高性能编程方式(后来总结为我的Java系统性能优化书籍或者电子版)。比如,我在JDK8中看到的将浮点数转化成String用的性能技巧 FloatingDecimal.getBinaryToASCIIBuffer ,在Beetl中就早已经使用。可以查看我的书,里面提到了很多性能优化手段,都用在了Beetl里,或者我曾经的优化的JD的核心交易系统里。如下是一个性能测试汇总,或者直接运行JMH工程,你可以下载下来看看。
可定制的语法树。Beetl可以定制语法实现,比如简单的占位符输出 ${},可以解释为文本输出,也可以像再BeetlSQL那样,解释为输出"?" 从而防止SQL注入。 再比如Beetl在线引擎,http://ibeetl.com/beetlonline/ 运行了很多年从来没有意外过,那怕你输入如下代码也不会无限循环运行
while(true){
}
定制话的在线引擎会对while语法提供新的实现,只会执行固定的次数,这也是Beetl被很多开源平台用在在线模板或者脚本引擎的原因。 反观国内牛逼的FastJSON,缺少定制,如果Fastjson在渲染成JSON的时候,提供Interceptor或者可定制的注解,那么他的功能必然比Jackson更强大。
这种定制设计影响了BeetlSQL,比如你见到的BeetlSQL大部分注解和使用习惯都是可定制的,比如在BeetlSQL 2中,如下定义一个BaseMapper
//BeetlSQL 2定义
public interface BaseMapper<T> {
void insert(T entity);
}
insert方法的实现需要在别的地方配置。但是,到了到了BeetlSQL3,改成了如下
//BeetlSQL 3定义
public interface BaseMapper<T> {
@AutoMapper(InsertAMI.class)
void insert(T entity);
}
这样,很容易定义N个方法,只要使用@AutoMapper标注一下此方法的实现类即可。这种技巧用到了BeetlSQL其他地方,如果你看别的ORM工具,你以为的需要特殊实现,在BeetlSQL中都很简单。比如想实现对脱敏数据的存取。
@Table(name="sys_user")
@Data
public static class UserData{
@AutoID
Integer id;
@Base64
String name;
}
你可以自定义个Base64注解,并再注解上申明其实现类即可
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.FIELD})
@Builder(Base64Convert.class) /
public static @interface Base64 {
}
Base64Convert是此注解的实现类,实现AttributeConvert接口即可。
在2000年的最初10年,大家只希望开源具有完善的文档和充分的示例 。然而,如今不一样了,开源这11年,越来越意识到,把代码写的越好,开源本生的定制性越强,那么开源更容易被接受。开源也更容易发展-我最初写Beetl开源的时候,还有藏着掖着代码的想法,很龌蹉想法。
开源这11年,感觉变化还有
- 开源使用者已经开始学会提出问题。以前提问甚至连个错误贴图都不会贴,现在不仅仅有贴图,还有红圈标注重点,甚至还有自己的见解。
- 开源使用者已经能通过源码来解决使用问题,开源使用者甚至能贡献新的开源代码,一个普通程序员在多个开源项目里做贡献常见
- 无论是高端人才,还是一个初中学历的就业者,对开源的贡献都是一样的大。
- 开源作者得到了社会认可,相当于半个学历的提升了。比如,我作为普通院校本科生,这几年,有机会去更酷的公司,有机会给电子工业出版社写俩本书,以及能交往很多技术大牛,都是跟开源有关系的。我应该是国内唯一写俩个很好开源,出版过俩本很好书的人
- 公司资助的开源越来越强大,这可能会扼杀个人开源独立性,但谁不羡慕,一边做开源,一边有公司支付薪水的日子。比如API JSON就被腾讯收编,Shard-JDBC就被JD收编。我也多么希望我的开源也被收编:)
- 公司开源得到了各种媒体的资源倾斜,媒体资源而以前更倾向于个人开源。
开源11年,我也从青年变成中年,程序员的中年,感觉真的不是很好。如果时间能回到过去,我一定会对当时的我说,"别搞开源,别搞开源,别搞开源,去刷题,别在北京呆着,去杭州,别怕996"。然而,没有如果,把一个开源从无做到优秀,做到仍然在坚持,耗费了太多的精力。这里有个大概的统计数据,以解决Beetl&BeetlSQL的用户的问题(算上官网论坛和Gitee,Github,)至少解决了2500个用户提出的问题和建议。每个问题,都有可能是1小时,或者一天的时间的付出。 比起解决用户问题,编写文档和博客,和Beetl&BeetSQL代码编写,更是翻倍的时间耗费。如果把这些时间用在其他学习,我不会错过很多炫酷知识,以及更酷的公司。
我当时的某个HP同事就有先见之明,同样无聊的他刷了很多算法题目。得以顺利进入更好的公司。现在已经是技术总裁。而我,只是个中年程序员。
我之所以有点后悔,不仅仅是因为如今的中年程序员尴尬身份,而是因为刚碰到了失业。当初本来有更好的选择,但老同事三顾茅庐,又说公司有美国AI工程院士李飞飞作为董事长的背书,我想必然靠谱和有前景,谁愿意错过未来呢,厌倦了CRUD的我,觉定冒险试一试尚未A轮的创业公司。亢奋了一年多,结果是,当所有的AI支撑系统和业务实现都被我完成的很好情况下,却因为AI同事不给力,导致李飞飞决定暂时放弃中国业务。 这个公司有很多中年同事,都是熟人介绍,聘请过来打公司基础的,刚过完年,当天就得到了裁员通知,不得不说资本的力量是无情的。我对面的医学博士,非常聪明,在医学领域深更多年,也在裁员之列,之后他成天都失眠。 中年大叔们什么都没有做错,却被惨遭淘汰 。我在被裁员之前三个月还写了博客《中年程序员转》来调侃未来的自己。没想到这么快就实现了,今年被裁员的经历,整的我人生都不自信了。
开源11年,技术上炫酷的事情都做过,而且做的到很好,但暮然回首,事业一塌糊涂,甚至到了中年失业的状况。这一方面是IT行业本来变动就大,并没有一个行业能容你呆很长时间,比如电信没落,网络彩票不让搞,P2P违法和金融IT投资下降等,另外一方面还是没有太多时间和精力学习炫酷技术,以此进入好的公司。 关于未来,前景不明,但对于我的开源Beetl和BeetlSQL,我一定会坚持维护下去,在我规划中,至少还有3年的时间去完善剩下的功能和使用体验,我也找到一些志同道合的人一起维护。 希望10年以内,一提到模板引擎,都把Beetl作为技术选型之一,一提到数据库访问,能想到BeetlSQL也是备选工具之一。
(插图备注: 科学家一直没搞明白猿人进化成人类的关键步奏,我从996得到启发,也许高强度劳动是关键)