写代码的人

Archive for the ‘技术文章’ Category

Twitter从Rails迁移到了Java

本文是从 Twitter moves from Rails to Java 这篇文章翻译而来。


Rail那插满五颜六色鲜艳羽毛的帽子现在跌落到了地上。Twitter决定放弃Ruby on Rails,改用Java,这次是包括他们的整个搜索库。早在2008年9月,他们就决定了把消息队列的后端程序从ruby迁移到Scala(一种Java虚拟机上的语言),而现在连同它们的前端也要迁移到Java。

他们开发了一个可扩展的叫做Blender的平台,使用的是依赖Java NIO的服务器(Netty),以此来克服目前的繁重的接入流量,MySQL被换成了Java上的Lucene搜索引擎,做出来的引擎能并行的完成多个后 台任何,相互独立管理,互不依赖。通过这种改造,搜索延迟降低了3倍,每台机器能接受比以前10倍多的请求。

不错,一个很大的成果。这是否意味着Java是一个比Rails更能胜任高扩展性需求的平台?即使真是这样,对于小规模的应用来说,Ruby on Rails的优雅比Java的性能更吸引人。

他们说这次改动使他们能够适应未来几个月搜索功能快速的迭代修改。伴随这个消息的事情还有Twitter扩招了25跟新员工, 这似乎也在表明对于相同的程序,Java比Ruby的可维护性更高——至少是在程序量巨大和团队规模很大的时候。这似乎也能表明跟他们最初时候着眼的问题 相比,他们现在关心的是系统的可维修性设计。但对于小开发团队和小规模程序来说,Ruby on Rails仍然是不二选择。

原文:http://www.aqee.net/2011/04/23/twitter-moves-from-rails-to-java/

在windows7下配置nginx的过程和一些问题

1、到nginx for windows由第三方编译的nginx Windows 版本下载
2、下载非安装版的php
3、将下载下来的nginx-0.7.59.zip包解压到你想到的位置(文件夹路径不能包含中文名)
4、直接运行nginx.exe,在浏览器中输入http://localhost,可以看到nginx的欢迎页面
5、配置nginx
我的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  185;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   D:/project;#网站根目录 需要与下面的fastcgi_param 对应
            index  index.html index.htm index.php;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
        #    root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  D:/project$fastcgi_script_name; #这个需要注意
            include        fastcgi_params;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }

    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

    # HTTPS server
    #
    #server {
    #    listen       443;
    #    server_name  localhost;

    #    ssl                  on;
    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_timeout  5m;

    #    ssl_protocols  SSLv2 SSLv3 TLSv1;
    #    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    #    ssl_prefer_server_ciphers   on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

6、使用RunHiddenConsole 隐藏php-cgi.exe的命令行,写一个批处理如下:

1
2
3
@echo off
echo Starting PHP FastCGI...
RunHiddenConsole D:\work\php\php-cgi.exe -b 127.0.0.1:9000 -c  D:\work\php\php.ini

7、关闭批处理

1
2
3
4
5
6
@echo off
echo Stopping nginx...
taskkill /F /IM nginx.exe > nul
echo Stopping PHP FastCGI...
taskkill /F /IM php-cgi.exe > nul
exit

其它可以参考
http://hi.baidu.com/rokaye/blog/item/3a44f6cbaf45dc19be09e6fd.html

【其它问题】
1、nginx网站根目录设置问题
fastcgi_param 和root 需要对应

2、The page you are looking for is temporarily unavailable.
打开某些页面时可能会出现The page you are looking for is temporarily unavailable.问题,在错误日志中可以看到
upstream timed out (10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond) while reading response header from upstream, client: 127.0.0.1, server: localhost, request: “GET
解决方案:修改 keepalive_timeout 185;

【补充说明】
在 Windows 下自动安装 Nginx 的项目:Farseer
这是淘宝 UED 部门的 明城 捣鼓的一个自动安装工具工具。地址:http://code.google.com/p/gracecode/wiki/Farseer

介绍几种常用的注册window服务工具

介绍五种方式

一,微软官方工具包

.1. 下载nginx windows版本

http://www.nginx.org

2. 下载微软的2个工具: instsrv.exe、srvany.exe
去微软网站下载安装Windows Server 2003 Resource Kit Tools(rktools.exe),它包括标题提及的所有必要的工具,下载完安装好。

3. 运行命令
在rktools安装目录下(一般在C:\Program Files\Windows Resource Kits\Tools目录)可以发现这两个程序.在运行下面命令之前,确保将srvany.exe复制到nginx的安装(解压)目录下,然后运行:

Command代码
  1. instsrv Nginx D:\nginx\srvany.exe

这样就安装了一个名为Nginx的服务。也就是将srvany.exe注册成一个服务Nginx。Net start Nginx时,肯定会运行srvany.exe。

4. 配置Nginx的运行参数:目的是运行srvany.exe时,附带运行D:\nginx\nginx.exe程序。

可以直接将配置导入到注册表

Window register代码
  1. Windows Registry Editor Version 5.00
  2. [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NGINX\Parameters]
  3. “Application”=”D:\\nginx\\nginx.exe”
  4. “AppParameters”=””
  5. “AppDirectory”=”D:\\nginx\\”

现在就可以通过控制面板->管理员工具->服务中找到该服务,并启动和停止了。
但是,当停止Nginix服务后,访问浏览器仍然能看到网站。查看进程,你会发现,Nginx启动了两个nginx进程(根据nginx.conf的配置worker_processes  1;),Fork出来的进程显然没有被停止,结果就是nginx永远关不掉。因此彻底关闭nginx请使用taskkill命令:

Command代码
  1. taskkill /F /IM nginx.exe > nul

结果是写一个stop_nginx脚本来处理nginx停止的所有操作

Command代码
  1. @echo off
  2. echo Stopping nginx service…
  3. net stop nginx
  4. echo Kill nginx process…
  5. taskkill /F /IM nginx.exe > nul

顺便,如果想删除服务,使用命令:

Command代码
  1. sc delete Nginx
原文:http://koda.javaeye.com/blog/600725     完全是copy过来的。。经测可用
二,利用小工具  AppToService  (找这个东东可能要费点劲)
demo:
D:\javatools\nginx-0.7.65>D:\javatools\cn.tsoft.system-empty\bin\AppToService.exe  /install nginx.exe /show:7 /absname:”nginx” /startup:A  /Arguments:”-p D:/javatools/nginx-0.7.65″   亲测可用
nginx如果不加  /Arguments:”-p D:/javatools/nginx-0.7.65″  这句会报
D:\javatools\nginx-0.7.65\nginx.exe:
could not open error log file: CreateFile() “logs/error.log” failed (3: The system cannot find the path specified)
错误   这个可以在系统日志中找到
三,利用小工具winsw-1.8-bin.exe
下载地址:
官方wiki:
我使用的demo如下:(D:/nginx 是我的nginx所在目录)
将winse*.exe 重命名为 nginxservice.exe  移动到D:/nginx 在同目录建立nginxservice.xml文件
内容如下:
<service>
 <id>nginx</id>
 <name>nginx</name>
 <description>nginx</description>
 <executable>D:/nginx/nginx.exe</executable>
 <logpath>D:/nginx/</logpath>
 <logmode>roll</logmode>
 <depend></depend>
 <startargument>-p D:/nginx</startargument>
 <stopargument>-p D:/nginx -s stop</stopargument>
</service>
然后执行nginxservice install    安装完成
注册这个服务的时候注意不要在路径中出现空格 比如 Program Files 这样的文件夹路径 否则会报路错误 在nginxservice.exe同级目录下的nginxservice.err.log文件看到错误内容
可以参考 : http://misterdai.wordpress.com/2009/10/16/nginx-windows-service/
四,apache的工具  tomcat就是用的这个
细看文档  还要window下面还要下一个 prunsrv.exe   好多人找不到 purnrv.exe这个文件
下载地址:http://apache.freelamp.com/commons/daemon/binaries/1.0.3/windows/
下载 commons-daemon-1.0.3-bin-windows.zip 就有这个文件
其实这个文件就是tomcat下面的tomcat6.exe 只是被重命名了
demo 就不写了 http://commons.apache.org/daemon/procrun.html  上面说得很清楚 wiki上面也有
这个用来作java 程序的服务是相当好的。提供不同平台的版本  曾经用这个和AppToService注册java服务。
demo也不好写了。。上面3个差不多就够用了

能说明你的Javascript技术很烂的五个原因

本文是从 5 Reasons Your Javascript Stinks 这篇文章翻译而来。


Javascript 在互联网上名声很臭,但你又很难再找到一个像它这样如此动态、如此被广泛使用、如此根植于我们的生活中的另外一种语言。它的低学习门槛让很多人都称它为学 前脚本语言,它另外一个让人嘲笑的东西是动态语言的概念是偏偏使用了高标准的静态数据类型。其实,你和Javascript都站错了立场,而现在,你让 Javascript很生气。这里有五个原因能说明你的Javascript技术很烂。

1. 你没有使用命名空间。

是否还记得在大学里老师告诉你不要在家庭作业里使用全局变量?Javascript里的全局变量的使用方法也不例外。Web网页稍不留神就会变的混 乱不堪、到处都是从互联网上各个角落里找来的乱糟糟的相互侵犯的脚本和脚本库。如果你把一个变量命名成loader(),那你是成心自找麻烦。如果你在无 意识的情况下重载了一个函数,Javascript根本不会提醒你。你还把它叫做一种学前教育编程语言,还记得吧?我要说的是,你需要知道在做了这些后发 生什么情况。

function derp() { alert(“one”); }
function derp() { alert(“two”); }
derp();

“two”,答案是“two”。并不是一定会这样,它也可能是“one”。所以,把你所有的代码都放在自己的命名空间里,这很容易。下面是定义自己的命名空间的一个简单做法。

var foospace={};
foospace.derp=function() { alert(“one”); }
function derp() { alert(“two”); }
foospace.derp();

2. 你在变戏法,你把变量定义的东一个西一个。

你使用莫名其妙的数字字母组合作为变量名是一个双输的结局。在40行的代码块了中寻找一个不带任何表意的字符变量,对于维护工作来说简直是场噩梦。 把对变量的第一次声明混合到一个40行的代码块里同样也是一场噩梦。即使你自己遇到这样的变量时,你也要不由的问自己:“这是在哪里定义的?”,然后迅速 的使用Ctrl+F组合在源代码里寻找这个变量最初定义的位置。不,不要这样,相反,这是对Javascript的滥用,是一种愚蠢的做法。你应该始终把 变量定义在它的使用范围的顶部。并不能说因为这不是必须的,你就可以不这样做。

function() {
var a, //description
b; //description
//process…
}

3. 你没有理解Javascript的变量范围。

你是个天才的程序员,你吃的是C++、拉的是List。你知道什么是变量范围,你对你的变量有完全的控制,你就像太上皇似的的注视着它们。然而,Javascript却在你的咖啡里拉了一泡屎,并且大笑不止。

var herp=”one”;
{
var herp=”two”;
}
alert(herp);

在这种情况下你得到的herp不是“one”,而是“two”。Javascript的变量有效范围并不是跟其它语言一样依赖于代码块。Javascript的变量范围是以函数为基础的。每个函数都有它自己的变量范围,Javascript这一点上表现的很酷,根本不理睬这毫无意义的花括弧包起来的范围。事实上,Javascript是如此的酷,以至于你甚至可以将变量范围像命名空间或变量那样进行传递。

4. 你以为Javascript的面向对象特征只是嫁接而来的。

Javascript,自从呱呱落地起,它就是一个面向对象的语言。所有的东西在Javascript里都是对象,所有的!甚至数字和字符这样的文 字符号都可以通过它自身固有的构造器转化成对象。跟其它面向对象的语言比起来,Javascript的不同之处在于,它没有类(class)。 Javascript对象像函数那样定义,甚至函数自己也是对象。Javascript有个属性叫做prototype,所有对象里都内置了这个属性,你可以通过它来改变对象的构造,修改对象、添加更多的变量、更多的功能。

var derp; // will hold a Herp instance
var Herp= function() {
this.opinion=”Javascript is cooler than BASIC.”;
}
Herp.prototype.speak=function() { alert(this.opinion); }
var derp= new Herp();
derp.speak();

如果这个看起来跟你毫不相干,我愿意介绍我的好朋友Google给你,Google擅长于帮助人们学习知识。面向对象对于我这篇简短的、低姿态的文章来说实在是个太大的话题。

5. 你使用“new”关键字时就像是盲人瞎马。

Javascript肯定是你的初恋女友,因为你显得无所适从。如果你想像真人那样取悦Javascript,你需要去了解对象符号。除了在需要实例化一个对象,或罕见的需要延时加载数据的情况外,你基本上不需要使用new关键字。在Javascript里分配大量的new变量地址是一项很慢的操作,为了效率起见,你应该始终使用对象符号。

var rightway= [1, 2, 3];
var wrongway= new Array(1, 2, 3);

是否还记得我说过Javascript的变量范围是以函数为基础的?是否还记得有人说Javascript的对象像函数那样定义?如果你不使用new关键字来声明一个对象,你将会使这个对象成为全局范围内的对象。所以,永远使用new关键字来声明对象是一个好习惯。

var derp=”one”;
var Herp=function() {
this.derp=”two”;
}
var foo=Herp();
alert(derp);

如果你这样写,Javascript并不会在意,而你真正弹出的答案是“two”!有很多方法可以防止对象做出这样的行为,可以以使用instanceOf,但更好的方法是正确的使用new关键字,这样显得更专业。

现在你知道你的Javascript代码写的很烂了吧,如果你记住了上面所说的东西,你的代码就会有所改善。我喜欢用3个tab键来缩进代码,我喜 欢用下划线来连接单词,我喜欢把函数名首字母大写来表示它是对象。当然,这个是另外一场讨论了。有很多原因会导致你的Javascript代码写的很烂, 就像我有很多技术很烂一样,所以,尽情的在评论里表达你的意见,支持,反对,不吝赐教。

非常感谢rogeliorv 和 Jared Wein指出第五点中存在的错误。你们很强。

本文转载自: 外刊IT评论 http://www.aqee.net/

 

程序出错后,程序员给测试人员的20条高频回复

编者按:程序员和软件测试员之间的关系无须多言。这些经典回复是国外程序员总结分享的,“全球通用”。

20. “That’s weird…” 很奇怪……
19. “It’s never done that before.” 以前没这样过的。
18. “It worked yesterday.” 昨天还好好的。
17. “How is that possible?” 那怎么可能?(怎么会出问题?)
16. “It must be a hardware problem.” 这一定是硬件问题。

15. “What did you type in wrong to get it to crash?” 你输入什么东西后才崩溃的?
14. “There is something funky in your data.” 你的数据有问题。
13. “I haven’t touched that module in weeks!” 我好几个礼拜没动那个程序了!
12. “You must have the wrong version.” 你一定在用错误的版本。
11. “It’s just some unlucky coincidence.” 这只是凑巧。

10. “I can’t test everything!” 我无法测试所有东西。(我的机器环境下,无法测试所有的可能情况。)
09. “THIS can’t be the source of THAT.” “这”不可能是问题的原因。
08. “It works, but it hasn’t been tested.” 程序能用,不过还没有测试。
07. “Somebody must have changed my code.” 一定有人改了我的代码。
06. “Did you check for a virus on your system?” 你的电脑扫描病毒了么?

05. “Even though it doesn’t work, how does it feel? 即便程序不行了,(你觉得)程序写得如何?
04. “You can’t use that version on your system.” 你不能在你系统上使用那个版本的程序。(程序版本和系统有冲突。)
03. “Why do you want to do it that way?” 你怎么会想着那样操作啊?
02. “Where were you when the program blew up?” 程序崩溃时,你在做什么呢?(做了哪些操作?)

第1条会是什么?猜猜看吧!

01. “It works on my machine” 在我机器上好好的!!!(潜台词:怎么在你那就出问题了呢!!!)

编者后话

虽然已经远离编程,但经常还是会用到第20、19条,当然也不会“错过”第1条。各位看过之后,不知你都用上了哪几条哦~

来自:http://www.oschina.net/news/16877/20-answers-programmer-give-to-tester

酷壳陈皓:如何学好C语言

导读:本文作者陈皓在csdn上发表博客讲述《Java NIO类库Selector机制解析》。以下是他列举学习C语言的一些建议:

有人在酷壳的留言版上询问下面的问题

 

keep_walker :今天晚上我看到这篇文章。

http://programmers.stackexchange.com/questions/62502/small-c-projects

我也遇到了和提问的老外一样的问题。。能给像遇到这样烦恼的程序员一点建议嘛?谢谢!

 

我相信,这可能是很多朋友的问题,我以前也有这样的感觉,编程编到一定的时候,发现能力到了瓶颈,既不深,也不扎实,半吊子。比如:你长期地使用Java和.NET ,这些有虚拟机的语言对于开发便利是便利,但是对于程序员来说可能并不太好,原因有两个:

1.虚拟机屏蔽了操作系统的系统调用,以及很多底层机制。

2.大量的封装好的类库也屏蔽了很多实现细节。

一段时间后,你会发现你知其然,不知所以然。。我以前在CSDN上写过一篇《Java NIO类库Selector机制解析》,在那篇文章中我说提到过(有讥讽的语气)Java的程序员不懂底层实现,所以很难把技术学得更扎实。此时,一部分程序员会不自然地想学学底层的技术,很自然的,C语言就被提了上来。

下面是我给这位朋友的一些建议:

鼓励并为你叫好。我鼓励你想要去学C语言的想法和精神,很多人都觉得C语言好学,其实并不然,现在的这个社会更多地去关注那些时髦的技术,而忽略了这个流行了40+年的C语言。一门技术如果能够流行40多年,这才是你需要去关注和学习的技术,而不是那些刚出来的技术(过度炒作的技术,Windows编程史)。这才是踏踏实实的精神。

不要找借口。这一条路走下来并不容易,不要给自己找借口。我最不喜欢听到的就是“很忙,没有时间”这样的借口。我以前在银行做项目,早9点到晚10点,周一到周六,我一样可以每天抽1个小时来看书和专研,一年下来也能精读5、6本书。我现在的工作项目和招聘任务很紧张,刚生的小孩只有自己和老婆两人带,还需要准备讲课,但是我还是能够找到时间看文章写文章维护酷壳。所以,我可以告诉你,“时间就像乳沟,只要你肯挤,就一定会有”。

学好C语言和系统编程。我认为,学好编程有四个方面:语言、算法和数据结构、系统调用和设计。

语言。我可以告诉你C语言有两大主题你要好好学,一个是内存管理,一个是指针!这个世界上90%以上的C/C++出的严重性错误全是和这两个有关。不要看谭浩强的那本书,那本是本烂书。推荐这本书给你《C程序设计语言(第2版·新版)》

算法和数据结构。我认为,用C语言实现算法和数据结构莫过于最爽的事情。推荐你看这本书——算法:C语言实现(第1~4部分)基础知识、数据结构、排序及搜索(原书第3版)

系统编程。Windows下推荐两本书——《Windows 程序设计 》和《Windows核心编程》,Unix/Linux下推荐两本书——《Unix高级环境编程》和《Unix网络编程卷1,套接字》《Unix网络编程卷2,进程间通信》尤其是《Unix网络编程》这本书,一通百通,无论Windows还是Unix/Linux,都是一样的。

系统设计。关于设计方面,我全力推荐《Unix编程艺术》,看完以后,你就明白什么是真正的编程文化了。然后,当你看到Windows的Fans的某些言论时,你就知道什么叫一笑了之了。

如果你能在2-3年内精读完这些书,并全部融会贯通,那么你就明白什么是一览众山小的感觉了!我足足花了5年时间才算是真正全部读完这些书的。最后,祝你好运!努力!

原文链接:http://coolshell.cn/articles/4102.html

 

不要用面向对象来迷惑程序员新手

本文是从 Don’t Distract New Programmers with OOP 这篇文章翻译而来。


当我被问及“哪种编程语言是教我[儿子 / 女儿 / 其他没有编程经验的人的首选]时,”我的答案这五年多来一直没变:Python。

这也许会出乎你的意料,经常有人会说这是非主流语言,但我坚持我的看法。

Python十分适合解决很多简单的、有趣的问题,比用C语言要省力的多。(这是实话,几行Python代码你就能制作一个简单的拼写检查程序。)你会发现这种语言里几乎没有任何复杂或让人困惑的东西,用它编程简单易懂,比如说数组更新你可以用固有的方法来实现任何的操作算法。在Python里,你学习的曲线很平滑。数组,字典,集合是最主要的东西。

把Python当作入门语言,有一点需要注意:避免使用面向对象特征。你当然不可能完全的回避它们,有些基本数据类型里一些有用的方法跟它们有关 联,问题不大。你只是使用它们已经提供的东西,不要去创建什么类,要避免任何的面向对象设计里的声明,否则的话,你一点点的数据都需要会打包成类。

从面向过程到面向对象的转移带来后果是你从关注问题和解决方法转移到关注架构。你通过对比面向过程的程序和面向对象的程序,很容易能看出这点来。后者的程序会更长,到处是多余的接口和缩进和标记。你也许忍不住想将一些小代码移进类里,或往类里添加一些小方法,这些都没必要,等日后你再做这些也不迟。

当你在帮助某人把一个有问题的语句改正确的时候,你要做的最后一件事是给他们布置一些没有实际用处的技术工作。因为有些人没事时就喜欢玩能一些面向 对象的知识技术,做一些可怕的类继承,最终没有学到他们该学的东西。有些人在学习的时候慢慢的会失去兴趣,因为他们看到了太多的这些没有实际用处的继承、 接口代码,感觉程序越来越笨重、难以处理。

从某方面说,当然,你需要学习一下Python的面向对象的知识,但尽可能的避免使用它们吧。

 

好的代码里只要一个 return 语句

本文是从 A return to Good Code 这篇文章翻译而来。

别再这样写了:

public boolean foo() {
if (true) {
return true;
} else {
return false;
}
}

每次当我深入某个开源项目,看到大概是某个专家写的、并被有经验的专业人士审查过的这样的代码,我都会惊讶不已,竟然没有人去阻止这个开发者在这个方法里胡乱的放置返回语句。

请告诉我,把代码写成下面的样子很难吗?

public boolean foo() {
boolean flag = true;
if (true) {
flag=true;
}
else {
flag=false;
}
return flag;
}

这是Java基本常识。实际上,这不仅是Java基本常识,这是小学水平的Java知识。如果你的方法返回一个值,你应该在方法的开始处把它声明做 一个变量。然后再去做一些赋予这个变量正确意义的操作。然后,在你的最后一行,把这个变量返回给调用程序。这样做不仅仅是为写出好的代码,这是一种有教养 的表现。

你是否曾试图修改过一些在方法里到处都是返回语句的程序代码?无从下手。事实上,去维护这样的代码,你第一要做的是重新组织它的结构,让它里面不再有一大 堆的返回语句。这样才能把事情做好。没有任何一个方法是不可以写成只在末尾处有一个的、单一的、易于找到的返回语句的形式的。

的确,烂程序员总有一万个理由来说明他们为什么编写出这样糟糕的程序代码。“我只是为了避免在返回时一堆的多余的条件判断语句。”那好,首先,我告诉你, 计算机中执行一些条件判断语句时是该死的快,你用短路一个方法来节省CPU的一两个指令操作不是显的太荒诞了吗。此外,如果这些所谓多余的条件判断语句最 终没有派上用场的话,这是否是一个有用的信号来说明你的“多余”的代码可能需要重写,也许可以把它们重构成另外一个方法,让它们显的不多余?

关键要说的是,没有任何理由可以为写糟糕的代码或当懒惰的程序员做托辞,特别是当写出好的代码并不是那么困难的情况下。不要在写出里面有成百上千个返回语句的方法了。Java里的方法只可以返回一个值,相应的,一个方法应该有且只有一个返回语句。

更多关于Java的详细信息,或者下载地址请点这里

本文转载自: 外刊IT评论 http://www.aqee.net/

谷歌如何测试软件 —— 第三部分

本文是从 How Google Tests Software – Part Three 这篇文章翻译而来。 本文作者 James Whittaker, 前微软架构师,是“How to Break Software”系列图书中好几部书的作者,现任Google测试工程主管,最近他写了一系列的关于谷歌如何测试软件的文章,本文为其系列的第三部分。

在前两部分的文章中,很多人在评论里提出了问题。我没有忘记他们。希望大部分的人能在余下的几部分文章里找到答案。我现在还是开始这篇文章的主题。

在Google,质量并不等于测试。我相信在任何一个地方都是如此。“质量不是被测试出来的”这句老话是再正确不过了。从汽车到软件,如果它们起初制造的就有问题,那它们永远都不会没问题。试问任何一个曾经被迫大量召回的汽车公司,掩盖质量问题的代价有多大。

然而,事实情况并不是像这句话那样既简单又精确。虽然质量并不是测试出来的,但我们有同样的证据表明,没有测试,你不可能开发出任何有质量的东西。一个人怎么可能在没有测试的情况下认定你的工程具有高质量?

对于这种难题,最简单的解决办法就是:禁止对开发工作开方便之门,以独立自由之精神进行测试。测试和开发工作需要同步进行。编写一点,测试一点。再编写一点,再测试一点。更好的方法是制定测试计划,或者你开发之前先把计划做好。测试并不是一个独立的工作,它是开发工作的一部分,伴随着整个开发过程。质量不等于测试;为了质量,需要你把开发工作和测试结合到一起,搅拌它们,直到分不清你我为止。

在Google,这是我们明确的目标:把开发和测试融合,你不能单独进行任何一项工作。做一点,测试一点。再做一点,再测试一点。关键就是看谁在做测试。因为在Google,专职测试人员是出奇的少,所以唯一可行的方法就是使用开发人员。还有比这些实际开发了这些程序的人员更合适做测试的吗?还有比程序的作者更适合去发现bug的吗?是谁具有更多的愿望在程序第一次写出时避免bug?Google之所以安排这么少的专职测试人员的原因就是,开发者负责质量。事实上,坚持使用大型测试机构的团队通常会开发出有问题的东西。测试机构庞大,这是一个信号表明编码/测试工作的融和有问题。增加测试人员并不能解决任何问题。

这就是说,质量措施更多的应该是一种预防行为,而不是一种发现过程。质量属于开发问题,而不是测试问题。通过把测试工作一定程度的融合到开发过程中,我们极大的降低了一些本来被认为会写很多有问题的代码的人的出错机会。我们不仅避免了大量的客户方的问题,我们还非常有效的降低了测试人员提出的、其实不是bug的bug。在Google,测试工作的目标就是检查这些预防工作是否在有效的运行。测试工程部一直在寻找这种作为bug创造者的软件工程师和作为bug预防者的测试软件工程师之间的联合能达到的效果的证据,一旦这个方法出现问题,他们就会拉响警笛。

这种开发和测试的结合随处可见,从代码审查注释上写的“你的测试呢?”到厕所里的给开发者的最好的测试实践方法的宣传画——这是我们臭名昭著的厕所测试指导方针。测试是开发工作中是必不可少的,开发和测试的联姻是孕育质量的过程。软工就是测试者,测试软工就是测试者,测试工程师就是测试者。

如果你的企业也有这种类型的结合,请分享出你们成功的经验与挑战。如果没有,那么这是一个给你的企业带来好处的机会:在开发人员和质量之间画上全等号。你们都听过这样一个老故事:小鸡很高兴能为一顿咸猪腿加鸡蛋早餐奉献自己的力量,可猪究竟做错了什么?的确是 … 去对你的开发人员哼哼两声,看能不能得到他们哼哼回应。如果他们发出的是咯咯哒的声音,那说明你们之间存在问题。

来自:http://www.aqee.net/2011/03/21/how-google-tests-software-part-three/

 

Google的产品质量之道

James Whittaker是Google的测试总监,曾任微软构架师,也是“实用软件测试指南”系列图书中好几本书的作者。他最近写了一系列的博文,介绍Google是如何进行测试。Google把开发和测试紧密结合在一起,测试人员相对较少,每个产品在正式上线前都要经过好几个不同的版本。

Google保证产品质量的方法和很多公司是不一样的。Google没有一个庞大的测试部门,相反,部分测试工作委派给了开发人员。Whittaker写道:

测试和开发同时进行。编写一些代码,马上进行测试和构建。接着,编写更多的代码,继续测试。更好的是,在你编码的时候或者编码之前,就计划好你的测试。测试不是一个独立分开的过程,它是开发的一部分。质量不等同于测试;要想有高质量的产品,就要把开发和测试紧密捆绑在一起,直到不分彼此。

这是因为,Google认为要保证质量,预防胜于检查:

质量来自开发,而不是测试。为了拓宽开发环节,我们可以把测试融入到开发中去。我们已经建立了一个超高效的增量流程,只要有一个增量被证明缺陷太多,我们就可以回滚这些错误。我们不仅预防了很多产品级问题,还大大地减少了那些为确保消除“召回级别”缺陷而安排的测试人员的人数。

因此,在Google,测试人员不用做测试是众所周知的,他们只要“确保他们【开发人员】有自动框架和相关流程”进行测试即可。开发人员进行必要的测试,他们对他们的代码质量负责。这其实就是强调了一点:“质量的重担落在那些负责交付正确产品的开发人员的肩上。”为了实现他们的质量哲学,Google有三种类型的工程师,Whittaker解释道:

  • SWE或者软件工程师是传统的开发角色。SWE编写最终交付给客户的功能代码。他们编写设计文档,设计数据结构以及整体架构,花绝大部分时间编写和审查代码。SWE会编写很多测试代码,包括测试驱动设计,单元测试,以及在未来的几篇博文中我们会具体解释的,如何参与到简单、中等甚至复杂的测试集成中去。SWE们对他们参与的一切的质量负责,不管是他们编写的、修复的或者是修改的。
  • SET或者测试软件工程师(Software Engineer in Test)也是开发角色,只是他们专注于易测性。他们审查设计,密切关注代码质量和风险。他们重构代码,让代码更加易于测试。SET需要编写单元测试框架和自动化测试。他们的代码也会提交到SWE所工作的代码库(code base),但是他们更加关注提高质量和测试覆盖率,而不是增加新功能或者提高性能。
  • TE或者测试工程师则跟SET恰恰相反。他们这个角色会把测试放在首位,而把开发放其次。很多Google的TE会花很多时间来编写模拟了实际使用场景甚至是模拟了用户的自动化脚本和代码。他们也整理SWE和SET的测试工作,解读测试结果从而驱动测试,他们也会在项目后期参与到项目中去,来强力推动项目发布。TE是产品专家,质量顾问也是风险分析员。

换句话说,SWE负责软件功能特性和它们的质量。SET提供代码支持,从而使SWE能测试这些产品特性。TE快速地测试系统或者再次检查那些被开发人员忽略的主要缺陷。并且,他们协助用户测试,还进行性能、安全以及其他类似的测试。

在公司级别,Google有几个关注域(Focus Areas)——搜索、广告、应用程序、移动服务、操作系统等等。其中有一个关注域是工程生产力(Engineering Productivity,EP),它包括了一些“横向和纵向的工程规范(horizontal and vertical engineering disciplines)”,测试是其中最大的一块。EP包括

  1. 产品团队——为整个Google的所有工程师提供能提高生产力的工具,包括开源项目,比如“代码分析器、IDE、测试用例管理系统、自动测试工具、构建发布系统、版本控制系统、代码审查安排系统、缺陷数据库。”
  2. 服务团队——为任何Google员工提供关于可靠性,安全,国际化等领域的专业知识,包括“工具、文档、测试、发布管理、培训”等等。
  3. 派遣式的工程团队(Embedded Engineers Team)——在Google,测试人员会被借调去不同的产品团队。他们可以选择为一个团队服务很多年,但公司鼓励他们去不同的团队轮岗,从而能够“在产品知识和新鲜视野之间”保持一个良好的平衡。这些测试人员参与到产品团队中的很多不同的关注域,但是从组织关系上来说,他们汇报给EP管理层。这样做的理由是能够建立一个“让测试人员共享知识和信息的论坛。好的测试想法在EP内部很容易传播开来,从而使所有测试人员,不管他们为哪个产品服务,都能够了解到公司内最好的技术。”

这种测试策略带来的结果就是相对较少的测试人员。根据Whittaker的观点,这也可能是因为“我们很少尝试一次快速交付很多功能。事实上,我们的目标恰恰相反:构建一个产品的核心部分,一旦它对很多人有价值,我们就发布这个产品,随后我们收集反馈,继续迭代。”另外一个确保质量的关键元素是使用多重版本。Whittaker以Chrome为例,介绍了四种不同的版本:

  1. 金丝雀版(Canary Channel)——还没有做好发布准备的代码
  2. 开发版——开发人员使用的版本
  3. 内部测试版(Test Channel)——为了准备beta发布的版本
  4. 测试(beta)或者发布版——这个版本的产品可供Google内部或者公众使用。

产品发布以后,如果发现了一个缺陷,我们会编写一个测试,并且在所有的版本中进行验证,看看这个缺陷是不是已经在某个版本里面被修复了。

简单来说,这就是Google用来测试他们的产品、确保代码质量的流程和组织结构。

来自:博客园