niyue

Archive for the ‘programming’ Category

可视化Java的Call Stack

In javaprogramming on 7月 1, 2007 at 5:14 下午

Debugging DFC实在是很痛苦的一件事情,因为DFC类库十分庞大,API的层次很深,很多层次都是非常薄的对下层的一个封装。如果是DFC的使用者,只要考虑其外部接口还比较容易,但是作为API的开发者来说的话,尤其是作为一个刚入门还不太了解其内部结构的新手来说,每次都要花费很多时间在debugger上,仅仅是为了看一下一次访问的整个层次结构是什么样的。于是利用前段空下来的时间,写了一个小工具(InvokeVis)来进行Java的Call Stack的一个可视化。

目前这个工具支持四种可视化的输出格式:

普通文本格式
很简单的格式,仅仅使用缩进来表示不同层次的调用。
GraphViz Dot格式
这一格式可以使用GraphViz中的dot工具来进行转换,可以输出为gif, jpg, png, post script等多种格式。
HTML格式
这是基于Yahoo的YUI的一个HTML格式,Call Stack被可视化的表示为一颗HTML树。
XML格式
这一格式可以使用SpringGraph来进行浏览,用户可以通过Flash来交互式的浏览Call Stack。目前的代码库中自带了一个定制的SpringGraph的flash,可以查看InvokeVis输出的XML格式。

最开始我考虑支持的最主要的格式其实是Dot格式,只希望能够输出为一般的图片就可以了。但是后来发现Dot格式输出的图片的可扩展性不是很好,尤其是对于DFC这种超级巨大的类库而言,一个简单的小程序就会输出几千个节点的图片(在用GraphViz Dot工具转化成jpg时甚至因为节点过多无法输出,只能转化成gif),要想看清图片的细节,只能局限与整个图片的很小一部分,仅仅是窥豹一斑。于是就考虑输出为HTML树这种可以动态变化的方式来进行浏览,扩展性确实得到了很大提高,基本不管多大的节点数都不会有什么扩展性问题。但是又觉得HTML树看起来的时候的可视化效果不如dot格式转化出的图片出色,最后转而想到flash格式的输出,应该来说最后得到的flash的效果还是不错的,但是有部分功能还需要进一步完善,尤其是对现在这一flash中输出的是无向图而不是有向图(方向表示方法调用的发向, caller method -> callee method)这一点很不满意,如果有时间的话会把这点先改进一下。
输出效果图:

Dot format, converted by GraphViz? into gif format:

HTML format:

XML format, visualzed with SpringGraph? flash:

多核对java的影响

In javaprogramming on 11月 23, 2006 at 10:45 上午

今天看到一篇文章, Multi-core may be bad for Java, 里面讲到:

The trend towards multicore is moving along at a fast pace. Architectures like Suns Niagara seem to be getting copied by the other CPU vendors. The architecture is basically lots of cores but low clock speed per core.

This is a problem for Java as:

  • Java likely has a longer path length than languages like C and clock speeds won’t help with this.
  • JavaEE promotes a simple threading model for applications
  • Garbage collection remains heavily dependant on clock speed for small pauses.

对与第三点,其实早有大牛Amdahl定律在前头.按照前文的评论中的数值,垃圾回收一般占CPU时间的5%.根据Amdahl定律,s = n/((b*n) + (1-b)),如果处理器的数目足够多(n>100),基本可以认为满足Amadahl定律的极限值,也即s = 1/b, 所以,大概估算的话, 100核的处理器大概可以提高Java平台20倍的性能(这里仅考虑gc是瓶颈). 不知道这个数值算达到了什么程度, 感觉还是比较高的吧.

参考文献:

  1. The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software
  2. multi-core may be bad for java
  3. Amdahl定律@wikipedia

编码问题释疑

In otherprogramming on 9月 23, 2006 at 9:08 下午

生活在中国的程序员恐怕没有不会碰到这个问题的–编码问题. unicode, utf-8, GBK, charset, encoding, code page这么一大堆术语加缩写,让人一看到就头晕,根本搞不清哪个是哪个. 各种各样的地方都会出现编码问题–数据库, JSP, mp3标签等等等等,不一而足. 我自己就花了不少时间解决编码的问题(还曾经写了一个很粗糙的Firefox的扩展来修正网页的编码),但面对这么多的术语,再加上平时解决问题时间有限,一般都是找了个方法摆脱了乱码问题之后就再也不想去看这个玩意了。今天本来是想比较一下python和ruby两个语言的,结果从ruby对unicode的支持问题开始,又回到了编码问题上来,终于决定把这些东西搞个清楚。

不过相关术语是在太多了,我建议大家先去看Unicode的词汇表,有什么疑问的词就可以在这个表里面search一下,一般可以立即得到一个清晰准确的解释,我主要结合wikipedia上对unicode的注释(unaccessible for some well-known reason)和unicode的这个词汇表讲几个最常碰到的词语和几个最大的疑惑。
confusing question:
Q: 编码到底是怎么一回事(-_-超级大问题,就解决这一个了决定)?
A: 历史上,编码问题最初是不存在的或者说不是什么大问题(很明显的,计算机发展初期只有英文使用者),字符集和字符编码是不区分的,统一用charset这个词来表示,同时兼了这两个词的含义.到了现代,编码这个问题被解耦成为几个部分:

1. what characters are available
2. their numbering
3. how those numbers are encoded as a series of “code units”
4. how those units are encoded as a stream of octets (bytes)

部分1指的就是字符集,表示可用的所有的字符,包括数字,字母,标点,汉字等等.
部分2指的是编码字符集(这里用英文可能更准确一些coded character set,被编码了的字符集),也即部分1中的每个字符会映射到一个或多个数字或者其他符号,由这些符号来代表部分1中的字符.
部分3和4指的是如何将2中映射得到的数字最终表示为计算机可以识别的二进制串(3,4拆分为两步的主要原因于计算机对字节流的解释有关big-endian or little-endian,不考虑的话应该可以合并).
从这四个部分可以看出,解决编码问题需要定义字符集,定义映射方案,定义编码方案这几个重要步骤.

Q: Unicode又是怎么一回事,它和utf-8有什么关系?
A: Unicode和另外一个与之并列的标准ISO 10646共同组成了一个上面提到的解决编码问题的解决方案,它不是四个部分中的任何一个,而是这四个部分各自解决方案的一个组合.其中字符集是由ISO 10646定义的,numbering应该在Unicode的标准中有(?^_^我也没看过,不确定).utf-8是Unicode提供的用于解决编码子问题的方案之一,同时还有utf-16和utf-32等等编码方案.

Q: code page呢?
A: code page就是coded character set,最初是IBM使用的一个术语,后来微软也大量使用.

这就是我的demystifying encoding problem, 如有不当请指教.
http://www.niyue.com

参考文献:
[1] Glossary of Unicode Terms http://www.unicode.org/glossary/
[2] Unicode in Wikipedia http://en.wikipedia.org/wiki/Unicode
[3] Character encoding in Wikipedia http://en.wikipedia.org/wiki/Character_encoding

static关键字的含义

In programming on 9月 23, 2006 at 3:23 下午

在许多编程语言里面都可以见到static这个关键字,虽然很常见,但是对于它的具体含义我却一直不是很了解,为什么这个要叫做static而不是其他?比如在C,C++,Java,C#里面都有这个关键字,说明这个关键字的字面意思应该是能够表明它的含义的(否则不会这么巧大家都用这个关键字),但是这个关键字的含义又不是那么简单可以望文生义,今天自己花了一些时间看了看,有了个相对清晰的了解.

这个Q&A(What does the keyword ‘static’ mean?)是我最开始找到的资料,问的问题是我想问的,但是答案确不是.

The static keyword denotes that a member variable, or method, can be accessed without requiring an instantiation of the class to which it belongs.

它说明了static关键字所表示的结果含义,但是没有说明为什么代表这个含义使用了static这个关键字.而这个含义其实是有一定编程经验的人都知道的,大家都这么用,但是不知道为什么这个是叫static而不是其他的.
我又继续看了一些资料(参见下面的参考文献),自己总结了一下:

  1. static这个关键字想要表达的是变量或者方法等的生命周期,而不是访问的作用域的控制,这可以和public,private(Java等语言)这些关键字区分开来.
  2. static这个关键字的字面含义”静态”说明了由static声明的变量或者函数等的生命周期控制信息的存放地点–静态数据存储区域.

接下来我详细的解释这两点:

  1. static声明的往往是一个用做全局的变量,类实例等.这个”全局”主要说的是通过static声明,声明的变量等可以增大其生命周期到某个全局的范围,比如Java类里面声明了一个static的变量,则它的生命周期和这个类相同–贯穿程序运行的全过程.因为不会消亡,所以你在引用这一static变量的时候只会引用到同一个变量,看起来就是一个类级别的变量(从结果看起来这样理解也可以,类似与Ruby中的@@来声明变量,但这样很容易知其然而不知所以然).在c语言中并没有类的概念,因此这种说法就不大行得通.在c语言中声明了一个static的变量之后,这一变量的生命周期就可以跨越声明它的文件中的所有函数,当然,这个时候的含义可能也包括了访问控制的含义在里面,但是我理解更主要的还是生命周期的改变.
  2. 生命周期控制数据的存放地点.要理解这一点,首先要知道有哪些地方可以用来存储程序中使用的数据.对于这一点,文献[1][2]讲述的很清楚,大家可以参考,我就不重复了.主要讲一下随机存储器RAM中的三种存储方式栈,堆,静态存储(stack,heap,static storage).看到这里,大家应该都知道由static声明的话,生命周期相关的信息会存在哪里了吧,至于static这个名字是怎么来的,也不用多说了.对Java来说,
    1. 一般的不是由static声明的变量,如果是原始的数据类型,会直接保存在stack上,如果是通过new得到的对象实例,这一对象的引用会保存在堆栈上,其实际的数据会保存在heap上,如果这一变量相关的数据被pop出栈,那么这一变量的生命周期也就结束了.如果是对象的话,其在堆上的对应内存也会被释放,这以后就再也无法访问这一对象了.
    2. 如果是由static声明的变量,不是在stack上存放引用等信息,而是在静态存储区域存放,这样即使堆栈内容变化也不会影响这些变量的创建或者消亡,从而可以不实例化一个类直接通过静态存储区域找到这一变量使用.

这些就是我的一个小结,有部分是我自己的理解,可能不是很正确,请大家指教.

Update: 文献[9]是一篇写的很好的文章,我对static声明函数的含义可能有些曲解,大家可以参考文献[9]最后的static函数及其扩展分析.

参考文献:

  1. 对象保存在哪里? http://www.qsl.net/bd5hag/JavaCourse/Lesson2/2_9_1.htm
  2. c storage class http://www.phim.unibe.ch/comp_doc/c_manual/C/SYNTAX/storage_class.html#static
  3. Static Variable in Wikipedia http://en.wikipedia.org/wiki/Static_variable
  4. Local Variable in Wikipedia http://en.wikipedia.org/wiki/Local_variable
  5. Call Stack in Wikipedia http://en.wikipedia.org/wiki/Call_stack
  6. this and static keyword, Thinking in Java http://columnist.chinabyte.com/xufeng.cq/149/2183649.shtml
  7. 小议static http://www.csdn.net/develop/Article/20/20219.shtm
  8. What does the keyword ‘static’ mean? http://www.javacoffeebreak.com/faq/faq0010.html
  9. static关键字Q/A http://home.zhuonline.net/archives/2005/09/staticqa.html

标识关系与非标识关系的区别

In programming on 8月 29, 2006 at 11:54 上午

最近在用Rose画数据库的数据模型设计图,画出来的不是ER图,但是和ER图比较相近。不过里面有两个概念一直没搞懂,identifying/non-identifying relationship,仔细查了一下,有不少介绍这个知识的文章。

从结果来看的话,identifying关系中的子表必须将父表的外键作为主键,而non-identifying则不必。

Vim extremely boosts my productivity!!!

In learningprogramming on 7月 26, 2006 at 3:53 下午

使用Vim大概半年时间了,终于可以算走过了Vim最陡峭的那段学习曲线,现在越来越感觉到它的效率了.今天使用vim完成的一个工作真正体现了这一点。

这次的工作是要比较两个列表中的人名,看列表一中的人名是否在列表二中,每个人名占了一行。如果用一般的编辑器可就麻烦了,只能用鼠标选中列表一中的某一行,然后Ctrl+C,然后Ctrl+F,然后Ctrl+V,然后Enter查找是不是有相同的字符串在第二个列表中也有出现。第一个列表一共大概有80个人,都要这样来一遍可是非常痛苦的一件事情。于是Google了一下找到了一个vim approach来完成,效率和准确率都提高了不少。我是这样做的:

  1. normal mode: q a
  2. 0 v $ h y j
  3. :%s/Ctrl+R  “/&/g Enter
  4. q

以后查找每一行只要按@a就可以知道在列表二里面是不是有相同的人,如果有会高亮显示并且跳到列表二的这个人名,再按一次n又回回到列表一,没有比这个更方便的更好的效果了:-)

不过要克服前面的这个学习曲线可是很累人的一件事情,不过相信vim会给你带来回报的~

learning curve

Painting in AWT and Swing

In javaprogramming on 7月 23, 2006 at 10:24 下午

Java在desktop端好像一直没有得到过很大的应用,据说Mustang会在此做出很大的提高,不过不知道什么时候才可以正式release.最近想写一个Swing的程序,发现从server端换到desktop端写的东西还是有很大不同,尤其是Swing里面的painting实在是让人很疑惑–看不大懂那些API应该怎么组合才能正确的使用.网上search到的东西又都是很早的时候的东西(很多都是AWT的,在后来大家都发现java在desktop没前途转到server side去了).
找了一些tutorial和code eg是五花八门,在painting的时候就会用到好几个方法:

public void paint(Graphics g)
public void update(Graphics g)
public void repaint() 
protected void paintComponent(Graphics g)

到底overwrite哪些方法,其间又有什么不同呢,实在是很复杂的问题,好容易在sun的网站上面找到一篇文章,很全面的介绍了AWT和Swing中painting的机制,把这些问题都讲清楚了,可以参考一下.

使用Excel作为用户接口

In otherprogramming on 2月 14, 2006 at 5:17 上午

看到了不少使用Excel作为用户接口的例子,感觉是一个不错的方法,可以先看看Dion Almaer文章

  1. Interface Excel { @MaybeEasiest businessGuyDoit(); }
  2. Abusing the Semantic Web
  3. DDSteps
  4. Feedlists in Spreadsheet?
  5. Clean handoff, Collaboration and Pluggable Process Constructs(BPM分析中使用SpreadSheet作为用户接口,Update at 2006-7-26)

趣文两篇

In otherprogramming on 1月 26, 2006 at 4:34 下午

今天看了两篇很有意思的文章,都是用通俗易懂的文字介绍技术内容的,both worth reading~

  1. [翻译].NET委托:一个C#睡前故事
  2. Oracle是如何工作的

编写Firefox扩展

In learningprogramming on 1月 20, 2006 at 4:25 下午

最近想写一个Firefox的扩展用来自动的改变网站的编码,开始的时候想使用GreaseMonkey来做这件事情,似乎容易一些,但是稍微看了一些资料感觉可能无法实现,只能直接写一个Firefox的扩展来做这个事情了。

搜集的一些编写Firefox扩展的资料:

  1. How to write Firefox extensions using BugMeNot as an example
  2. How to create Firefox extensions中文翻译:如何创建Firefox扩展
  3. Writing an Extension for Firefox
  4. Firefox Extension Tutorial
  5. Extension development
  6. Building an Extension