1,最近google发布了一个序列化的库Protocol Buffers,尝试了下,在android下的表现很好。
首先看这个lib的大小
然后用官网的json库和google buffer在android上随机测试了一组性能,
下面是json的代码
1. Item[] itemlist = new Item[10];
2. JSONArray items = new JSONArray(new String(buffer.toByteArray()));
3. final int max = items.length();
4. for (int i=0; i < max; i++){ 5. Item item = new Item();
6. item.title = items.getJSONObject(i).getString("title"); 7. item.text = items.getJSONObject(i).getString("text"); 8. item.link = items.getJSONObject(i).getString("url"); 9. item.image = Base64.decode(items.getJSONObject(i).getString("image")); 10. itemlist[i] = item;
11. }
结果:
明显在android上google buffer是很有优势的,但是这个jar有800k,而json是android sdk自带了已经。
2,关于JVM的动态classpath,很多同学都忽略了,下面的代码可以帮你动态加载lib到classpath里
1: URI clientJarUri = DynamicClasspath.class.getProtectionDomain().getCodeSource().getLocation().toURI();
2: Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] {URL.class}); 3: addURL.setAccessible(true);
4: ClassLoader classLoader = ClassLoader.getSystemClassLoader();
5: for( URL jarUrl : classpathUrlsToAdd ){ 6: addURL.invoke(classLoader, jarUrl);
7: }
3,jQuery的一些小技巧
3.1 最快选中父元素 $("#searchBox").closest("div");
3.2 Document Ready的另外一种写法
- //Instead of
- $(document).ready(function() {
- //document ready
- });
- //Use
- $(function(){
- //document ready
- });
4,html里做元素的平移动画,传统方法,用timer移动元素的left坐标,但是在iphone的safari里有明显延迟,标准做法是用webkit支持的css来完成变换,这样得到硬件支持,完全无延迟。示例代码:
-webkit-transition: left 250ms ease;
-webkit-transform:translateX(-320px)
最近1个月再次尝试了一把ROR,感觉在做prototype的时候ROR的优势很明显,但是一旦项目做到一定的规模。RoR和其所鼓吹的敏捷就越发的弱势起来。
1,对一定规模的系统来说,安全性,事物,与各种单元的异构集成服务要求很高,这方面java已经有无数成熟的库,而ruby还在摸索前进。
2,在做prototype的时候ruby的效率的确是分分钟的,但是其代码风格自由随意,一旦代码量大了,维护起来极其困难。
总结来说RoR的快速,很大程序上时因为你无从选择,从而节省了选择的成本,减去了面对种种选择重新学习的时间
获取来访用户地理位置
原理:google ajax api自动生成google.loader.ClientLocation 函数/数组,包含地理信息。
实现:
1. 引入js:
<script type="text/javascript" src="http://www.google.com/jsapi?key=API_KEY_GOES_HERE"></script>
2. 加入以下代码
if(google.loader.ClientLocation)
{
visitor_lat = google.loader.ClientLocation.latitude;
visitor_lon = google.loader.ClientLocation.longitude;
visitor_city = google.loader.ClientLocation.address.city;
visitor_region = google.loader.ClientLocation.address.region;
visitor_country = google.loader.ClientLocation.address.country;
visitor_countrycode = google.loader.ClientLocation.address.country_code;
}
else
{
// ClientLocation not found or not populated
// so perform error handling
}
3. 实际页面效果
继承上述代码后用下列输出
document.getElementById('yourinfo').innerHTML = '<p>Lat/Lon: ' + visitor_lat + ' / ' + visitor_lon + '</p><p>Location: ' + visitor_city + ', ' + visitor_region + ', ' + visitor_country + ' (' + visitor_countrycode + ')</p>';
Lat/Lon: 49.3 / 7.067
Location: Sulzbach/Saar, Saar, Germany (DE)
计算两地距离
1. 初始化geocoder函数:
var geocoder= new GClientGeocoder();
2. 转换string到地理坐标:
var location1;
geocoder.getLocations(document.forms[0].address1.value, function (response){
location1 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
}
同理得到location2;
geocoder.getLocations(document.forms[0].address2.value, function (response) {
location2 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
}
3. 开始计算
function calculateDistance()
{
try
{
var glatlng1 = new GLatLng(location1.lat, location1.lon);
var glatlng2 = new GLatLng(location2.lat, location2.lon);
var miledistance = glatlng1.distanceFrom(glatlng2, 3959).toFixed(1);
var kmdistance = (miledistance * 1.609344).toFixed(1);
document.getElementById('results').innerHTML = '<strong>Address 1: </strong>' + location1.address + ' (' + location1.lat + ':' + location1.lon + ')<br /><strong>Address 2: </strong>' + location2.address + ' (' + location2.lat + ':' + location2.lon + ')<br /><strong>Distance: </strong>' + miledistance + ' miles (or ' + kmdistance + ' kilometers)';
}
catch (error)
{
alert(error);
}
}
4. 实际效果
Address 1: Peking, China (39.9081726:116.3979471)
Address 2: Frankfurt am Main, Deutschland (50.1115118:8.6805059)
Distance: 4834.5 miles (or 7780.4 kilometers)
最后送几张我关注的Jorge Colombo在iphone上的作品


Michael Armstrong的书一直是实用速成派的代表。我们这把年龄已经禁不起风险了,领导任何一个中小型Proj之前都要经济搭台,技术唱戏。而场景与场景之间,各种真假面的转换,资源的合理利用,更是成为我每天都需要面对的经典问题。这里,我需要的不是教条,而是可以量化和科学运用的东西。
这个月,事情很多,闲暇期间读完这本《how to be an even better manager》,很多问题迎刃而解,毕竟我做的不是不够好,只是要做的比别人更好。
和几个同学讨论,关于软件定价,纷纷不解,我为什么要卖那么贵?同样的东西,你只有脚踏实地从客户的角度出发,帮他设计,优化流程,确立规范,从灵感到实施全程参与,才能真正的赢得客户,同时也提高了自己。这个时候脑子里完全没有价钱,有的只是客户的利益。毕竟,只要客户赠钱了,那你的一切都没有问题。而我向来认为,我们先是伙伴,再是买卖。
以前做项目,卖的是技术。现在,更多的是卖的思想,技术可以复制,思想不能。也只有有了这个,你做的东西才经的起考验。
同时:强烈推荐所有立志于做Consulting, Proj Leader,CXO的同学通读马克思的《1844年经济学哲学手稿》,我人生第一次有这么强烈的愿望去读这样一篇以前读书时死记硬背的东西,也确实,提高了不少认识。。。读完之后,相信你会和我一样在控制、运营项目,评估、保证软件质量,平衡社会关系,逻辑等方面有不少新的认识。。。
个人心得:我认为老马认为,这世界的逻辑建立在掠夺之上,而掠夺者和被掠夺者都同样不自由。只有超越了对物的臣服,落实到对人之为人的关怀,才有人的自由。同理,我们在采用Object Adapter或者Decorator模式的时候,也会有Object和object之间的继承,实现与依赖。这关系着系统设计出来是否健壮。而只有全盘超越了单纯的oo,把面向过程在恰当的时候融入进来,才会让object之间的互动更为良好,功能更加清晰,整个程序的动态结构也就更有弹性。

这本书很有名,在此号召大家都看看。
不要以为是老瓶装老酒,html5,canvas,js里的oo,闭包,js在各大浏览器里的异常策略,利用BEA的ECMAScript来构建xml,以及新兴的Client-Side storage都是很有趣的东西,值得关注。最后不要忘了就是js的性能和调优迟早成为未来面试中的难题!
为了加速我们的页面下载,除了把import语句从放在页面底部,删除多余的TAB,空格,简短函数/变量名这这俩方法之外,还可以像gmail那样按需延迟加载。下面的代码验证函数是否被加载:
if (myfunction){
// The function has been loaded
}
else{ // Function has not been loaded yet, so load the javascript.
$import('http://www.xxx.com/myfile.js');
}
验证完毕后,动态加载
function import(src){
var scriptElem = document.createElement('script');
scriptElem.setAttribute('src',src);
scriptElem.setAttribute('type','text/javascript');
document.getElementsByTagName('head')[0].appendChild(scriptElem);
}
// import with a random query parameter to avoid caching
function importNoCache(src){
var ms = new Date().getTime().toString();
var seed = "?" + ms;
$import(src + seed);
}
声明:这不是恶搞。。。一句话总结widerbug就是firebug的宽屏版。。。。
官网:http://www.command-tab.com/2008/01/19/widerbug-widescreen-firebug/
截图:
网上已经有如何在eclipse里集成的教程了,鉴于eclipse已经成为肥猪流/非主流。。。现特上idea集成javarebel指南。
1. 避免idea每次改动后重新打包war
2. 在编译器设置里取消改动后重新部署,并选中编译depenencies
3. 在服务器的VM Parameters里填写如下行:
-noverify
-javaagent:E:/MyJavaLibs/javarebel/javarebel.jar
-Drebel.struts2-plugin=true
-Drebel.spring_plugin=true
-Drebel.dirs=E:/Idea.Workspace/HikingWS/out/exploded/HikingWSWeb/WEB-INF/classes //自行添加多处需要监视改动的路径
现在改程序那速度,杠杠滴!
现在大家可以从页面直接从google那载入js啦。
<!-- Always need this javascript -->
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
//get the latest moo
google.load('mootools', '1.2.1');
//other examples
google.load('jquery', '1.3.1');
google.load('jqueryui', '1.5.3');
google.load('prototype', '1.6.0.3');
google.load('scriptaculous', '1.8.2');
google.load('mootools', '1.2.1');
google.load('dojo', '1.2.3');
google.load('swfobject', '2.1');
google.load('yui', '2.6.0');
已于0714上市。
简介:
You might think more than enough design books exist in the programming world already. In fact, there are so many that it makes sense to ask why you would read yet another. Is there really a need for yet another design book? In fact, there is a greater need than ever before, and Practical API Design: Confessions of a Java Framework Architect fills that need!
* Teaches you how to write an API that will stand the test of Time
* Written by the designer of the NetBeans API at Sun
* Based on best practices, scalability, and API design patterns
What you’ll learn
* What an API is and what the theories are behind good API design
* When and why to build an API
* API design patterns applicable to all programming languages, especially modern, object–oriented languages
* How to optimize and test APIs
Who is this book for?
This book is recommended to every API architect who prefers a bit more engineering design over a purely artistic one.
Author Information
Jaroslav Tulach
Jaroslav Tulach is the founder and initial architect of NetBeans, later acquired by Sun. As creator of the technology behind NetBeans, he is still with the project to find ways to improve the design skills among all the programmers who contribute to the success of NetBeans open source project.
前因:http://dreamramon.spaces.live.com/blog/cns!9615FB50FFDBCFD3!2387.entry
好,我们现在来科学的解释为什么三种方法速度不一样。Java程序如下:
public class Test{
public static void main(String args[]) {
int A = 200;
int B = 300;
int C;
final int loop = 100000001;
System.out.println("Object creating...");
System.out.println("A=" + A);
System.out.println("B=" + B);
System.out.println("==================");
System.out.println("Method 1 starting...");
Long begin=System.nanoTime();
for(int i = 0; i< loop; ++i) {
C = A;
A = B;
B = C;
}
Long end=System.nanoTime();
System.out.println("A=" + A);
System.out.println("B=" + B);
System.out.println("Start Time: "+begin);
System.out.println("End Time: "+end);
System.out.println("Last Time: "+(end-begin));
System.out.println("==================");
System.out.println("Method 2 starting...");
begin=System.nanoTime();
for(int i = 0; i < loop; ++i){
A = A + B;
B = A - B;
A = A - B;
}
end=System.nanoTime();
System.out.println("A=" + A);
System.out.println("B=" + B);
System.out.println("Start Time: "+begin);
System.out.println("End Time: "+end);
System.out.println("Last Time: "+(end-begin));
System.out.println("==================");
System.out.println("Method 3 starting...");
begin=System.nanoTime();
for(int i = 0; i < loop; ++i){
A = A ^ B;
B = A ^ B;
A = A ^ B;
}
end = System.nanoTime();
System.out.println("A=" + A);
System.out.println("B=" + B);
System.out.println("Start Time: "+begin);
System.out.println("End Time: "+end);
System.out.println("Last Time: "+(end-begin));
System.out.println("==================");
}
}
編譯出的Bytecode:
方法1:
93: iload 6
95: ldc #16; //int 100000001
97: if_icmpge 112
100: iload_1
101: istore_3
102: iload_2
103: istore_1
104: iload_3
105: istore_2
106: iinc 6, 1
109: goto 93
方法2:
284: iload 7
286: ldc #16; //int 100000001
288: if_icmpge 309
291: iload_1
292: iload_2
293: iadd
294: istore_1
295: iload_1
296: iload_2
297: isub
298: istore_2
299: iload_1
300: iload_2
301: isub
302: istore_1
303: iinc 7, 1
306: goto 284
方法3:
481: iload 7
483: ldc #16; //int 100000001
485: if_icmpge 506
488: iload_1
489: iload_2
490: ixor
491: istore_1
492: iload_1
493: iload_2
494: ixor
495: istore_2
496: iload_1
497: iload_2
498: ixor
499: istore_1
500: iinc 7, 1
503: goto 481
可以看出第一种方法在Stack based VM上编译的指令更简单一些。
运行的结果:
$java -hotspot -classpath ./ Test
Object creating...
A=200
B=300
==================
Method 1 starting...
A=300
B=200
Start Time: 21265732594226
End Time: 21265903045778
Last Time: 170451552
==================
Method 2 starting...
A=200
B=300
Start Time: 21265904274984
End Time: 21266211578007
Last Time: 307303023
==================
Method 3 starting...
A=300
B=200
Start Time: 21266212842414
End Time: 21266516976319
Last Time: 304133905
==================
There are two ways of constructing a software design: one way is to make it so simple that there are obviously no deficiencies; the other is to make it so complicated that there are no obvious deficiencies.
—C. A. R. Hoare
今年已经过半了,JAVA类除了一本Effective JAVA 2ND 外还没啥重量级的好书。最近在给自己的WEB应用调优,居然发现很多市场上的container都提供eclipse plugin方便debug。而一直以来http://www.w3.org/Protocols/HTTP/1.1/rfc2616.pdf 一百多页的HTTP 1.1规范都没心思看。这次google到这本书确实不错,全书语言通俗易懂。第一章,作者从解释HTTP开始到JAVA SOCKET,带领读者建立一个超轻量级的HTTP SERVER。第二章,解释了如何为服务器上的静态资源创建request和response 对象。第三,四章,揭示了TOMCAT 4的connector原理。第五章讨论了容器的原理和他的实现org.apache.catalina。第六章,蛮有趣的,说明了J2EE怎么处理对象的生命周期。第十一章和十二章属于实用型,介绍了filter和context。其他的还未读。。就不做介绍了。。
后记:虽然TOMCAT现在没啥用,但是好在简单,作为新手入门的PROJ不错。源码结构和清晰,命名也易读,再配合这本书,更容易让你提升J2EE优化的能力。