肯尼迪关于GDP的言论

June 23rd, 2010 No comments

Too much and for too long, we seemed to have surrendered personal excellence and community values in the mere accumulation of material things. Our Gross National Product, now, is over $800 billion dollars a year, but that Gross National Product – if we judge the United States of America by that – that Gross National Product counts air pollution and cigarette advertising, and ambulances to clear our highways of carnage. It counts special locks for our doors and the jails for the people who break them. It counts the destruction of the redwood and the loss of our natural wonder in chaotic sprawl. It counts napalm and counts nuclear warheads and armored cars for the police to fight the riots in our cities. It counts Whitman’s rifle and Speck’s knife. And the television programs which glorify violence in order to sell toys to our children. Yet the gross national product does not allow for the health of our children, the quality of their education or the joy of their play. It does not include the beauty of our poetry or the strength of our marriages, the intelligence of our public debate or the integrity of our public officials. It measures neither our wit nor our courage, neither our wisdom nor our learning, neither our compassion nor our devotion to our country, it measures everything in short, except that which makes life worthwhile. And it can tell us everything about America except why we are proud that we are Americans.
  Robert F. Kennedy
  University of Kansas
  March 18, 1968

GDP并没有考虑到我们孩子的健康,他们的教育质量,或者他们的快乐。它也没有包括我们的诗歌之美,或者婚姻的稳定;没有包括我们关于公共问题争论的智慧,或者我们公务员的廉洁。它既没有衡量我们的勇气、智慧、也没有衡量对祖国的热爱。简言之,它衡量一切,但并不包括使我们的生活有意义的东西!

我们只是在美国的1960年代,因为我们现在也在盲目的追求GDP,但是我们的state leader还没发表这样的言论. 这就是差距.

Categories: life Tags: , ,

win7-64bit quake3 Set DeviceGammaRamp Failed

April 16th, 2010 No comments

Two days ago I bought a new machine, installed win7 64bits operating system, when playing quake3, the screen is dark and can’t adjust the gamma,console alert set DeviceGammaRamp Failed.
Initially i considered it to be the graphics driver’s problem, but reinstall the graphics driver is invalid. And then i check the log of quake’s init in console, all opengl lib’s loading is correct. Yesterday i found the solution in a forum ,it is to open the properties of quake3.exe, select the compatibility label, checked run in compatibility mode with XP-sp3. Apply and OK! Try it, hoho ,i can play this game again!

一个apache 502错误

April 12th, 2010 No comments

今天有人找我,说一个上传大文件的页面返回502错误,页面信息如下:

Bad Gateway
 
The proxy server received an invalid response from an upstream server.

这里先说说我们的server结构:
apache–>mod_jk–>jboss

这个页面的主要功能是上传excel,解析,处理.
apache,没有任何错误日志,jboss和mod_jk各有一些,jboss的日志基本上就是一些解析上的问题. mod_jk如下:

[Mon Apr 12 16:55:37 2010][25561:1685907776] [error] ajp_get_reply::jk_ajp_common.c (1962): (localnode) Tomcat is down or refused connection. No response has been sent to the client (yet)
[Mon Apr 12 16:55:37 2010][25561:1685907776] [error] ajp_service::jk_ajp_common.c (2440): (localnode) sending request to tomcat failed (unrecoverable),  (attempt=1)

这个页面在上传小文件的时候没有任何问题,只有在上传big file的情况下apache返回错误页面,但是jboss其实还是把上传的文件处理完成的.

这么来看就是jboss之前的tcp上发生timeout.

经过试验是mod_jk–>jboss的问题, 具体参数是:

JkWorkerProperty worker.localnode.socket_timeout=20

在jboss超出这个参数设定的时间后,mod_jk打印错误日志,apache返回错误页面, 试着将这个时间调整为之60秒,120秒同样的在相应的时间后,打印日志,返回错误页面.

socket_time何意呢?官方文档是:
Socket timeout in seconds used for the communication channel between JK and remote host. If the remote host does not respond inside the timeout specified, JK will generate an error, and retry again. If set to zero (default) JK will wait for an infinite amount of time on all socket operations.

是mok_jk与远程服务器间的socket通讯超时时间. 假如远程服务器没有在指定的时间内返回请求, 那么mod_jk将产生一个错误,并重试. 重试无结果,就返回apache了. 假如指定的超时时间是0,那么mod_jk会无限等待response.

从这个问题引出的思考:
我们设置这个时间有问题么? 20秒是否太短了? 对于绝大多数的正常访问来说,这绝对够了. 异常的情况下,jboss服务器或者某个存储发生故障,那设定20秒超时,apache返回502也没问题.

我们来看看这个功能的问题, 让一个servlet处理6m的excel数据,并对数据进行复杂的运算. 且在一个单线程下完成. 页面上也没有任何优化, 是否应该用异步的方式提示成功与否更合理呢?

作为一个web开发者,不能简单的满足对方的需求,更应该仔细考虑我们的解决方案是否合理,有效.

Categories: technic Tags: , , ,

(翻译)Handling null in Java

March 24th, 2010 No comments

原作者:Roy van Rijn
原文地址:http://www.redcode.nl/blog/2010/02/handling-null-in-java/

空值处理是我在jee的项目中遇到的最常见的问题. 但为什么这会是个问题呢? 接下来我们又准备选用何种策略来解决这个问题呢? 在这篇文章中我将尽力找出这个答案.

让我们先来看一段商业逻辑代码,并且我们假设没有空值:

         public BigDecimal getBalance(Person person) {
	    Set<Account> accounts = person.getAccounts();
	    BigDecimal totalBalance = BigDecimal.ZERO;
	    for(Account account: accounts) {
	        totalBalance = totalBalance.add(account.getBalance());
	    }
	    return totalBalance;
	}

这看起来非常的好理解! 但是这不是我们大多数项目中的情况. 通常我们看到的代码是这样:

         public BigDecimal getBalance(Person person) {
	    if(person != null) {
	        Set<Account> accounts = person.getAccounts();
	        if(accounts != null) {
	            BigDecimal totalBalance = BigDecimal.ZERO;
	            for(Account account: accounts) {
	                if(account != null) {
	                    totalBalance = totalBalance.add(account.getBalance());
	                }
	            }
	        }
	        return totalBalance;
	    } else {
	        return null;
	    }
	}

呵呵,这看起来一点也不漂亮! 我们如何去改进呢?

Inversion of logic
第一个策略可以根据我之前写的文章inversion of logic(http://www.redcode.nl/blog/2009/12/inversion_of_logic/). 这里的思想是先退出, 这将提高这个方法的可读性. 让我们看看更具这个原则改进后的代码:

         public BigDecimal getBalance(Person person) {
	    if(person == null || person.getAccounts() == null) {
	        return null;
	    }
	    Set<Account> accounts = person.getAccounts();
	    BigDecimal totalBalance = BigDecimal.ZERO;
	    for(Account account: accounts) {
	        if(account != null) {
	            totalBalance = totalBalance.add(account.getBalance());
	        }
	    }
	    return totalBalance;
	}

这看起来好一点了,简短些,但是还是有我们不想要的”!=”和”==null”的检查

Code by contract
避免空值检查的最好方式是在你的应用中避免空值. 只需要在你的所有的方法返回时非空! 这听起来非常容易并且直接,但是做起来比听起来要困难一些,因为每个方法返回非空并不是我们的习惯.
令人欣慰的是目前有些ide已经实现了@NotNull和@Nullable这两个annotations. 有了这两个annotations你可以通知其他的程序员,你的IDE及代码分析工具:你创建你的方法时的思想:

         @Nullable
	public Person getPerson(Long id) {
	    return something.retrievePerson(id);
	}
 
	public void printPersonName(Long id) {
	    Person person = getPerson(id);
	    System.out.println(person.getName());
	    //Causes warning: getPerson is Nullable, thus this is a possible NPE!
	}

它也可以帮助你清楚的声明,你的方法调用中,参数person非空:

         public void printPersonName(@NotNull Person person) {                
	    System.out.println(person.getName());                        
	    //Very good, we know we won't get a NPE here!                
	}                                                                
 
	public void executeThis() {                                      
	    Person person = null;                                        
	    printPersonName(person);                                     
	    //Causes warning: person might be null, thus can cause a NPE!
	    //Code analysis tools and/or IDE will warn you about this.   
	}

它也可以帮助你修正可能的编码错误:

        @NotNull     
        public Person getPersonFromDatabase(@NotNull Long id) {                            
	    //Use JPQL                                                                     
	    Query query = em.createQuery("SELECT p FROM Person p WHERE p.id = :value");    
	    q.setParameter("value", id);                                                   
	    return q.getSingleResult();                                                    
	    //The IDE will complain about this.                                            
	    //The database might return null, we don't allow returning null in this method.
	}

使用这个方法你多了几分把握. 但是这不是万全之策. 我们必须停下来想一想,空值是从哪里来的?
事实上,当时停止返回空值的时候(这取决于你和你的团队),仍旧有一些没有检查的情况. 例如你使用的外部的apis,框架,ORM-mapper. 所以每次执行非你写的方法的时候,你仍旧不得不手工检查. 但是你务必要做到这一点. 而后的代码你可以不做检查,因为你使用了@NotNull这个annotation. 假如你对上面的Person对象及所有fields这么做了,那么你可以是第一个例子的代码变得漂亮,干净很多. 没有空值检查,它们由annotation约束. 唯一要做的就是添加参数的信息.

        @NotNull
	public BigDecimal getBalance(@NotNull Person person) {
	    Set<Account> accounts = person.getAccounts();
	    BigDecimal totalBalance = BigDecimal.ZERO;
	    for(Account account: accounts) {
	        totalBalance = totalBalance.add(account.getBalance());
	    }
	    return totalBalance;
	}

在我的经验中,这样做很不错, 我已经这样做了有超过一打的次数,甚至在@NotNull和@Nullable出现之前. 在这两个annotations出现之前,我们就在javadoc里添加这样的信息, 但是随着IDE检查的出现,这样的做法就不变得容易很多.

Null object pattern
使用一个null-object是与coding-by-contract的方式完全不同的门路. 这种思想背后的模式是不返回空对象,代替的是返回一个真的对象. 我们的例子就会变成这样:

        public interface Person {                                                                          
 
	    String getName();                      
	    void setName(String name);             
 
	    List<Account> getAccounts();           
 
	    //..etc..                              
	}                                          
 
	public class NullPerson implements Person {
 
	    public String getName() {              
	        return "";                         
	    }                                      
 
	    public void setName(String name) {}    
 
	    public List<Account> getAccounts() {   
	        return Collections.emptyList();    
	    }                                      
	}

这样做后,巨大的好处是你在调用person.getName()的时候是永远安全的,因为即使你得到一个NullPerson,但这个对象也早就存在了. 这个Null-Object很明显是个单例.

         public BigDecimal getBalance(Person person) {
	    Set<Account> accounts = person.getAccounts();
	        //NullPerson returns empty list, no more NPE!
	    BigDecimal totalBalance = BigDecimal.ZERO;
	    for(Account account: accounts) {
	        totalBalance = totalBalance.add(account.getBalance());
	    }
	    return totalBalance;
	}

关于这个模式的更详细阐述,但更一般的版本是由martin Fowler的special case pattern(http://martinfowler.com/eaaCatalog/specialCase.html). 这里不只有一个Null-special情况,你也可以扩展:

        public class UnknownPerson implements Person {
 
	    public String getName() {
	        return "";
	    }
 
	    public void setName(String name) {}
 
	    public List<Account> getAccounts() {
	        return Collections.emptyList();
	    }
 
	}
	public class InvalidatedPerson implements Person {
 
	    public String getName() {
	        return "";
	    }
 
	    public void setName(String name) {}
 
	    public List<Account> getAccounts() {
	        return Collections.emptyList();
	    }
	}

现在你可以返回更多信息,而不只是一个无意义的”null”!

这种模式也有一个问题. 它也没有解决你的问题. 为什么我们会想要计算一个NullPerson的账户总结余呢?当你取得一个person并且是一个NullPerson实例的时候,捕获且适当的处理,而不是一味的继续下面的代码.

Safe null operator
有一段时间,有一种思考,就是通过Coin项目把Safe-null-operator引入java7中. 假如你有Groovy的编程经验,那么你可能见过以下的代码:

         public String getFirstLetterOfName(Person person) {
	    return person?.getName()?.substring(0, 1);
	}

这个思想就是用”?.”来替代”.”. 这个引号标志意味着”假如我们将要访问的对象是空,那么返回空,否则执行下一个方法”.
那么在这个例子中:
假如person为null,那么返回null
假如getName()为空,返回null
最后返回substring(0,1)的结果

假如写成目前的代码形式就是这样:

         public String getFirstLetterOfName(Person person) {
	    if(person == null) {
	        return null;
	    }
	    if(person.getName() == null) {
	        return null;
	    }
	    return person.getName().substring(0, 1);
	}

你也可以返回一个默认的值:

         public void printName(Person person) {
	    System.out.println(person?.getName() ?: "Anonymous");
	}

假如perrson或者getName()是空,那么”?:”操作符就返回默认的字符串.
这看起来非常的不错吧,哈?唯一的问题是,这样的新操作符最终没有被引入到Java7的变更列表中.
有趣的是:你知道为什么”?:”操作符被称为”猫王”操作符么?从侧边看起来它像猫王的一个笑脸,包括他大圈的头发!

Categories: translation Tags: , , ,

[翻译]Top 5 trends and technologies in software development

March 5th, 2010 No comments

不翻译了,有兴趣自己看原文,地址:http://blog.mostof.it/top-5-trends-in-software-development
在目前多变的软件开发的世界中,保持对当前技术,方法,趋势的了解是极其重要的. 但这不是那么容易就能做到的,简单的,不是每个人在工作和生活的同时还拥有足够的时间学习这些新玩意. 因此选择是关键,巧妙的选择一些进行学习,这样就不会错过一些重要的东西,而且也可以让我们远离那些垃圾或不重要的趋势.
我写了这篇文章列举了一些小的甚至不完整的事项, 我觉的这些是我要关心和实践的. 有些可能已经陈旧的,但是还没有充分的掌握.

1: Learn and use a modern scripting language
学习并使用一种现代的脚本语言,如:Ruby,Python,Groovy

2: Learn thogoughly and embrace the philosophy of a modern version control system
学习,拥抱现在代版本可控制的理念,如:svn,cvs

3: Be familiar with NoSQL solutions like MongoDB, CouchDB
熟悉NoSql的方案,如MongoDB,CouchDB

4: Learn a functional language – or more than one
学一些功能性的语言,如:Erlang

5: Study agile methods and concepts
学习敏捷开发的方法和思想,如:
TDD-Test Driven Development 测试驱动开发
iteration-based development 迭代开发
BDD-Behavior Driven Development 行为驱动开发
XP-Extreme Programmingn 极限编程
CI- Continuous Integration 持续集成
Scrum

Categories: translation Tags: