有意思的新东西

完全拖拽的方式实现表创建及管理(但是相应的例外建立的模型,和SQL关系不清晰,且无文档)

Gradle解决依赖和版本管理;

发布仍旧为手工发布?(好像是);

gitlab提供了版本管理流程;

平台提供所有组件,业务只需要Gradle引入相应的项目自动解决依赖(貌似看上去挺爽的);

又因为平台提供了所有组件,或者称为服务,所以内部普遍采用RPC的方式;

有自有wiki;

目测缺少bug track,用wiki暂时顶着(好像是)

gitlab提供了版本管理流程

由以上带来的缺点是:

新手入门还是很有成本的。

Gradle是要学习的新东东,另外Gradle不像ant那么的简单,但是可以从maven借鉴大量的概念来学习

没有显式的RPC调用语句,黑箱带来了一定程度上的阅读困难,特别是跨project的调用压根看不到服务提供者的实现细节,从而缺少了注释说明。

拓展性

假设我们有一张用户表:

uid,username,nickname,birthday……等有限个元素

当我们需要加入用户更多的信息应该如何实现?

有如下两个我想到的方案

  1. 根据uid作为外键,然后建立新表
  2. 在此表中加入一个可以动态扩展的字段

先说第一种,

比如我要新加一种属性,叫用户性别:gender;那么我就可以新建立一张表叫做gender,或者直接用db的外键,或者直接带逻辑代码中用uid查询。

这里的好处是可以保持原来的字段不改变,避免原来的表结构膨胀,可以直接做索引(扩展字段无法索引,随时可能超出64字节的索引量,MYSQL)

第二种,

我们可以在用户表中新增一个null的字段,叫做ext,中间保存的是json字符串,这个字符串由各个业务共同使用各自转换成相应语言中的数据结构

好处也是不增加新表

坏处是这个字段是无法索引的,所以只能存放一些静态的,不需要索引的数据

‘好’得边界

昨晚写JVM收集器的选择,说到编程中到处都是TradeOff,想起了前几天QQ群的一些讨论;

问:怎么样的一个工程才算是比较好的工程

群里面比较多的答复是;

比如有VCS啦,能够DevOps啦,还有关注代码质量啦。

但是在我看来,这些都没说到点子上。我认为一个好的工程应该是和其应用场景及生命周期相关的

Example 1:

我写了一个HelloWorld想学习一门新的语言,比如Java,那么这时候我们只需要一个Vim,一个JDK就足够了,就是一个好的工程了

Example 2:

我做了一个工具,能够自动的收集所在计算机的负载数据,我需要的数据在很长范围内是不会增加或者改变的,那么我随便一个IDE,怎么写得快就怎么写,这样可以快速使用,连VCS都可以不用有

Example 3:

我对外声称了一个比较小型服务,比如计算A+B的结果,那么我只要SVN和一个tomcat加上一个IDE就足够了,什么Spring,什么Struct都不需要。30KB+tomcat大小足以

Example 4:

我对外声称提供越来越多的服务,这时候可以用上DevOps的思想,节省部署的时间和复杂度

结论:

在没有提供使用场景和生命周期的情况下,说一个通用的项目应该具备哪些条件就是耍流氓。

在一般意义上,够用就好就足够了

Java性能调优.gc收集器的选择

需要关注

响应时间,吞吐量

最古典的Serial收集器在内存占用少于100MB的应用表现最好。

并行的Serial收集器在多核情况下能极大改善吞吐量,但是STW时间比较长

CMS同样在多核情况下表现好,但相比并行Serial收集器则吞吐量有下降但能极大的改善响应时间

包括新的G1收集器在内都无法解决不可控的STW时间

故而最近还有一种提议无收集器JVM,但是这样完全放弃了java的优势

还有一种java实时应用程序,用确定的STW时间来消除不可控的STW,但是极大地降低了吞吐量,且要在代码上作出一定的设计,否则程序无法顺利运行

总结:

Java的性能调优就是一场Trade off的行为

单点登录要素

单点登录的要素

中央认证服务器:用于生成ticket
应用服务器:要约定一个页面用于接收ticket,并写入相同域名内的cookie

技术上要解决

生成ticket的机制
ticket的失效机制

需要权衡的

每次验证ticket都需要到中央服务器认证:增加内部流量
通过租约:会有失效时间,不能保证马上所有位置都失效
中央服务器push到业务端通知失效:中央服务器压力大

Java NIO

什么是NIO

new IO 或者none block IO

什么是通道(Channel)

一个对可以实现IO操作的抽象,任何类实现了channel,则表明可以往通道存放一些byte,然后不需要再去操心如何去实现。

几种通道的介绍

  1. ByteChannel(声明了这个Channel可以处理的是byte)
  2. ReadableByteChannel(声明了这是个只读的Channel)
  3. WriteableByteChannel(名字如其意义)
  4. SeekableByteChannel
  5. etc

视图

事实上channel也不是直接操作byte[],而是操作其中的包装对象xxxBuffer。当然多数情况下我们连byteBuffer都懒得操纵,我们对ByteBuffer也做了装扮(decorate),使之变成了ByteBuffer的一个View,我们称xxxx是xxx的视图(view),实质上是表明,底层一样,但是对外的语义变换了。

视图带来了好处就是能够以我们熟悉的语义来操纵对象,而避免脑中还要顺便转换成相应的byte[]结构。

结论

NIO带来了新的对IO操作的抽象,但是也仅仅是模型变换,除此之外,更多的非模型上而是工程上实际问题带来了改进,比如非阻塞式的访问(其实Stream模型也可以做到非阻塞式访问,只不过要根据这个模型来重新实现),还有Network到Network的转发可以不经过用户态而直接在内核态的进行转发避免上下文切换带来的CPU和内存带宽的消耗,等其他可能我还没了解到的特性