Mark さんのプロフィールMark's Zoneフォトブログリスト ツール ヘルプ

ブログ


1月29日

给公司里的孩子们指条明道儿吧

    看看权威机构的评测TIOBE对编程语言流行度的排名,再看看专家的分析,也许是时候学习一门动态语言了。但是忘掉Ruby吧,虽然Groovy还只能排到31位,但有理由相信原生的基于Java的实现会让它迅速上升的。下面是摘自TIOBE的08年1月对比07年1月的语言流行度的对比。

Position
Jan 2008
Position
Jan 2007
Delta in Position Programming
Language
Ratings
Jan 2008
Delta
Jan 2007
Status
1 1 Java 20.849% +1.69%   A
2 2 C 13.916% -1.89%   A
3 4 (Visual) Basic 10.963% +1.84%   A
4 5 PHP 9.195% +1.25%   A
5 3 C++ 8.730% -1.70%   A
6 8 Python 5.538% +2.04%   A
7 6 Perl 5.247% -0.99%   A
8 7 C# 4.856% +1.34%   A
9 12 Delphi 3.335% +1.00%   A
10 9 JavaScript 3.203% +0.36%   A
11 10 Ruby 2.345% -0.17%   A
12 13 PL/SQL 1.230% -0.34%   A
13 11 SAS 1.204% -1.14%   A
14 14 D 1.172% -0.16%   A
15 18 COBOL 0.932% +0.30%   A
16 46 Lua 0.579% +0.48%   A--
17 22 FoxPro/xBase 0.506% +0.05%   B
18 19 Pascal 0.456% -0.11%   B
19 16 Lisp/Scheme 0.413% -0.26%   A--
20 27 Logo 0.386% +0.07%   B

    至于Java领域学点儿什么,我再贴几个反应工作信息变化趋势的图:

     看了这两个图,一切不言自明了,Spring Framework绝对是现在Java领域挂头牌的开发框架,同时它的各个子项目也几乎涵盖了企业级开发的各个方面,有什么理由不用它呢?

     可以想见,在不远的将来也许真的要进入多语言混合编程的时代了。在Java领域,也许就是Spring框架组织的产品级的纯Java的底层代码,动态语言实现的根据项目定制的定制模块。但是真的不知道对程序员来说,这是一件幸事还是一件不幸的事。

 

7月31日

应用Artifactory搭建企业级的内部Maven私服

     公司的开发团队用Maven已经很长时间了,而且在内网和公网都有Maven私服,但是一直用得很不爽,总结起来有如下几点:

  • 需要手工同步内外网的Maven库
  • 使用的第三方的库需要手工从公服下载下来再上传到私服中
  • Maven自身需要jar包非常多,手工工作量非常大

     昨天发现一个免费的Maven私服软件Artifactory,直接解决了现在所有的问题。通过配置Artifactory可以自动下载并缓存公服中的jar包,而且这个下载只是在第一次使用时下载,不会造成大量垃圾的存在。同时Artifactory提供了WebUI的管理界面,可以方便的浏览管理jar包。Artifactory还提供了备份还原等功能。

     应用了Artifactory,现在公司的Maven私服以外网为主,内网私服只建立了外网私服的一个缓存,这样公司内部的jar包只在外网私服发布一次就OK了。

 

 

6月3日

JDK1.5中对原子操作的支持

       最近用Hibernate总觉得Hibernate自带的主键生成机制都不太爽,所以决定给Hibernate扩展一个生成Long型主键。新的机制其实和老的DNA中一样,就是当前毫秒数*1000后后面加顺序值,此顺序值就是0~999循环取得的。

      原来用JDK1.4写的时候肯定这个类必须是一个单例模式,这个顺序值还得用Synchronized同步起来。现在JDK1.5提供了几种原子操作的类,这个问题就简化了,我只要一个支持原子操作的顺序值发生器就可以省去同步了。写完的代码大概如下:

/**
 * 长整型ID发生器<br>
 */
public class LongIdGenerator {
  private static final AtomicInteger intSequence;

  static {
    intSequence = new AtomicInteger(0);
  } 

  public Serializable generate() {
    long key = System.currentTimeMillis();
    key = key * 1000;
    key = key + intSequence.getAndIncrement(); //先取值,后增加
    intSequence.compareAndSet(1000, 0);    //如果等于10000了,那么再从0开始
    return key;
  }

}

      由于不知道Hibernate本身如何创建、创建几个这个自定义的LongIdGenerator的实例,所以该类没有设计成单例模式,那么那个intSequence就需要声明为静态的了。

      但在我对它测试的时候发现一个很危险的事情,System.currentTimeMillis()函数只能精确到大概15ms左右,也就是说currentTimeMillis函数每15ms左右才会改变.

 
 
 
9月25日

Spring + Hibernate的奇怪问题(二)

    今天抽空又测试了一把,把测试方法中的循环加入到Manager层中,这样所有插入操作都是在一个Session中完成,速度提高到了每100条170ms,这还算比较正常了。

    接着又把数据源配置为c3p0的数据源,两种方法都没有问题了,只是速度差异,大概每条都启动一个Session的速度大概是另一个的三倍。

    看来Spring自带的DataSource真的是很烂啊。

 

 

9月24日

Spring + Hibernate的奇怪问题

      前两天在论坛看到有关Hibernate插入数据库时的性能问题,今天加班时尝试了一把,本打算比较一下主键生成机制设置为Native和UUID这两种情况在Oracle上的性能差别,结果发现另一个很奇怪的问题。

      做了个很简单的表,一个主键(Native机制,在Oracle上通过序列号生成器来完成),一个字符串字段、一个整数字段。实体类也就这三个属性,在TestCase中做了个100*100的循环,每次循环都创建一个新实例,再通过Manager插入到数据库中,记录每100次操作的时间,结果发现居然要4秒多,也就是每秒不超过25条记录,开始猜想可以是Native机制搞的,打算一会儿再测测UUID的方式。可是奇怪的事情马上就发生了,在插入了大概1000多条记录后,Spring忽然抛出连不上数据库的异常了,用PL/SQL连也是同样情况,但是过了大概半分钟就好了。清空数据库又做了一遍测试,还是一样的操行,邪门了,难道那台服务器性能真的那么差?(配置:CPU P3 1.2G;内存1G;装了Oracle,MySQL及SQLServer),明天换台好机器再试试。

 

 

 

 

9月6日

对于推箱子的思考(二)

      把我的集成开发环境中的推箱子插件反编译,居然稍作修改就能变成Swing的桌面应用程序,太让我欣喜了。看了看源代码,如果想后面算法实现起来比较方便,还是要对数据结构做根本的修改,不过没关系,至少省了我最头疼的界面表现部分的代码。下面的工作就在这个基础上搞了,先把底层数据结构来个大换血吧。
 
 
 
7月11日

对于推箱子的思考(一)

      推箱子的游戏估计很多人都玩过,我原来也很爱玩推箱子,感觉这是一个很考脑力的游戏。
      原来玩推箱子的时候就一直想写个程序能对输入的图自动找出一个解,以前想过的算法大致是如下:首先,为了下面叙述,将不经过拐弯能直接到达某点的格子的集合称为该点的通道,其实对于一个格子而言,它的通道很简单,就是交汇于它的水平和竖直的两条直线;对于目标格子(即箱子最终要到达的格子),将它的通道格子标记为0,表示在它们上面的箱子不用拐弯就能直接到达目标格子;将这些标记为0的格子的通道格子标记为1,表示在它们上面的箱子首先要推到标记为0的格子,才能再次推到目标格子;以此类推,将输入的图中的所有格子都做上这种距离标记,那么将箱子从大数值的格子推到低数值的格子,看似就可以求出解。不过在边玩边思考这个算法的过程中,还是感觉这个算法没法做,因为在很多图中,箱子很多,通路又很少,开始的很多步都是要将箱子推到一个距离远但不碍事的地方,对于这个算法来说就比较困难了。
 
      上周六在单位等面试人员的时候,没事又玩了玩推箱子,再一次钩起了我对解决这个问题的冲动。这次的思路还是回归到踏踏实实的做深度优先的遍历,虽然方法可能比较笨,但是如果有好的启发函数,还是能很快的求出解的。这次思考的算法大致如下:对于每一步,都先计算出玩家可以到达的格子,这个计算很简单,利用填充色算法就可以很容易实现;与这些格子相邻的箱子就是玩家在当前这一步可以推动的箱子,那么程序就随机的推动一个箱子,推动后,判断是否会造成GameOver(对于什么样的情形会GameOver以后会详说),如果不会造成GameOver,那就递归处理下一步,如果造成GameOver,那就返回上一步,再去推下一个可推的箱子。这样不停的递归下去,早晚能把所有箱子推到目标格子上。
 
      今天就写这么多吧,先把星期六灵光一现的想法记录下来,以后我还会跟进的,这次怎么也得把这个算法写出来。
 
 
4月11日

中文真是麻烦

      不做IT行业的人,估计都不会太了解使计算机能处理中文是一件多么复杂和头疼的事。看看计算机所用的中文字符集有多少种大概就会有个了解了:基本集GB 2312-80,五个辅助集,ISO 10646,ISO 10646,GB18030,BIG5,GBK,UTF-8等等。这里面既有大陆用的,也有台湾用的,还有国际通用的。单说现在国内做简体中文Java开发吧,就有GB2312,GBK,UTF8等几个字符集,每家的产品可能支持的字符集都不一样,可是你还得偏偏把它们集成到一起,这几个字符集之间来回的折腾就能烦死你,能折腾出来你还就烧高香去吧。
      中文问题里还有个繁简转换的问题,简体和繁体的对应不像英文的大写和小写那个是一一对应的,在不同的词语中,同样的简体字是有可能对应到不同的繁体字的。这也使得简繁转换无法像英文大写转小写那样简单的减掉一个0x20就能搞定,而不得不做一套知识库系统来维护简繁转换了。
      说到这我倒想起来丫毛海生在MSN名字后面写的自己的回教名,我原来以为那些阿拉伯文字就是手写出来看不清楚呢,结果输入到电脑里也看不清楚,真佩服微软,这玩意儿丫也能实现。我永远也看不懂那是几个字母,那东西就好像几只纠缠在一起的喂鱼的线虫。
 
 
1月10日

平台规划

      新的一年了,公司面临的最大问题就是产品的升级和整合,产品整合的第一步必然是确定技术选型和基本框架。
      技术选型基本确定在Spring + Hibernate这个组合,至于表现层是用Struts还是Tapestry又或者是现在出镜率非常高的Ajax,目前我确实没有想法,因为我实在对表现层的东西掌握的太少了。开发框架包含底层平台及应用,下图是我设想的一个大致结构:
 
     
      底层平台管理和协调上层应用,为应用提供平台信息并获取应用的信息。应用通过实现统一的接口类Application将自己注册进平台并接受平台的管理。应用从平台获取诸如Application Server的类型、数据库的类型等信息,根据不同的环境向平台提供不同的配置文件;平台从应用读取应用中各种Bean的声明(Spring的配置文件)、持久类的声明(Hibernate配置文件),通过这些配置文件,平台为各个应用创建出一个运行环境。在平台启动后还可以顺序的调用各个应用的初始化函数(如果应用需要初始化),甚至当应用第一次部署到平台上时,还可以自动对应用进行首次的初始化(不同于每次启动应用的初始化)。应用间的依赖靠平台提供的IOC机制完成配置,这样可以很容易的进行后续的升级或改造。这一切功能利用Spring都可以很容易的实现。
 
12月3日

静态发布 VS 页面缓存

      最近接触了一下TRS的产品,是一个支持静态发布的内容管理系统,虽然这个产品都已经到5.1版了,可是使用起来还是很不爽,很多动态效果很难实现。我感觉只要不是像新浪那么大的访问量,完全没必要用静态发布,利用一些实体缓存、结果集缓存和页面级缓存就足以应付了,用这种静态发布的产品反而会得不偿失。
      EHCache可以提供页面级缓存,前两天又听国林说了一个什么ESI,有空研究研究。