`
王者之剑
  • 浏览: 194781 次
  • 性别: Icon_minigender_1
  • 来自: 湖北
社区版块
存档分类
最新评论

不要把简单的事情搞得N复杂(例1)

阅读更多

题目:用java写一个程序,打印如下图形

*

**

***

****

*****

请思考三钞钟,写下你的程序,然后看答案。

 

 

 

我刚毕业时的答案:

package com.albertsong;

/**
 * 
 * @author Albert
 *
 */
public class PrintStar {

	public static void main(String[] args) {
		for(int i=0;i<5;i++){
			for(int j=0;j<i+1;j++){
				System.out.print("*");
			}
			System.out.println();
		}
	}

}

现在的答案:

 

package com.albertsong;

/**
 *
 * @author Albert
 *
 */
public class PrintStar {

    public static void main(String[] args) {
        System.out.println("*\n**\n***\n****\n*****\n");
    }

}
 

 

看到这里,同学们肯定有话要说了。

 

我也有话要说,我想说的是:“与人方便,自己方便”。

 

仅就这个题目而言,显然第二个程序要好得多,它实现了和第一个程序一样的功能。无论从代码行数,还是容易理解的程度,第一个程序都无法与之相比。

 

讨论1:

M:第一个程序更容易修改,扩展,适应性更强。如果要打印下面的图形,

*

**

***

...

*****...***(注:第100行有100个)

改第二个程序还不累死?

A:如果第二天客户要打印的是下面这个图形呢?

*

**

***

* **

*** *

M:变态!%^&*

A:没有变态的客户,只有懒惰的程序员。

 

 

讨论2:

1)

A:到目前为止,这样的图形最多有几行?

G:十行吧

A:随着贵公司的发展,有可能到一百行吗?

G:当然是希望越多越好,但按公司目前的情况,十年之内不太可能。

G:但我们有可能调整业务,那时图形可能会变。

A:变了的话应该还是有一定规律的吧

G:那当然,也不能胡乱调阿,结果基本上不是正三角形就是倒三角形,最多会变成菱形。

2)

A:需不需要能够打印一百行,或者一千行的?

G:不需要,这个图还是昨天拍脑袋出来的,先给我打出来看看效果

A:会不会有中间哪儿少个*号的情况

G:你先别管这么多,先把目前这个问题解决了,中间会不会少*号这会儿还不知道。

 

讨论3:

T:本来想招个学过Java for循环的程序员阿

A:我们下回是不是把题目改成“用java写一个程序,打印如下图形(请使用for循环)。

 

现在到底哪个程序好,应该比较清楚了吧。

“不要把简单的事情搞得N复杂”,这句话是针对结果,而不是针对过程的准则。

前几天在闲聊中写道:不要解决不存在的问题,我想更为准确的说法是:不要解决了不存在的问题。

 

路人甲:哦,懂了,但是,这和前面说到的“与人方便,自己方便”有什么关系?

A:没有一毛钱的关系,如果“认真分析需求,为客户着想”这种理念高尚得让你有点儿难受的话,不妨想想,这样做,实际上可以为自己省下看毛片的时间呀,对不?

 

42
7
分享到:
评论
64 楼 zcy860511 2010-02-10  
这也是为什么设计师这么难当的原因
63 楼 dinguangx 2009-04-17  
引用
这样做,实际上可以为自己省下看毛片的时间呀

有意思
62 楼 QuakeWang 2009-04-17  
我认为pufan同学的意见是完全正确的,我明天上班就将博客ping功能从不可靠的curl改写成用健全的Java,其实这个很简单,我预计50行左右代码就可以搞定:
1. Java启动一个socket监听
2. ruby需要ping的时候,给这个sokect发个请求
3. Java收到请求以后丢到一个thread pool中
4. 另外一个thread负责从这个pool中轮询
5. 轮询到有需要发送的,调用Java的Http Connection给google发ping

这样就可以替换掉原先1行的curl代码了。
61 楼 pufan 2009-04-16  
rubynroll 写道

你的这个回复很有意思, 我估计可能也代表了不少人的想法. "跨进程去调未知实现"听起来似乎很有"不确定性". 在这里你怀疑了操作系统的能力, 怀疑curl是"未知实现",唯独对自己的程序有信心. 如果是我,面临一个待解决问题时首先想到的是能不能用现存的程序来解决问题,而不是编程去实现它.

按老兄的意思,linux下curl就是首选,估计windows下调用IE也是做得出来的吧。

不重复发明轮子是没错,可是放着语言内部的轻巧轮子你不用,偏偏去挑进口的,价格昂贵还不给质保。

恩,有钱人呀,不选对的,只选贵的。




60 楼 王者之剑 2009-04-16  
javaboy2006 写道

王者之剑 写道
javaboy2006 写道
王者之剑 写道javaboy2006 写道Java代码 System.out.println("*\n**\n***\n****\n*****\n");&amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;nbsp;&amp;amp;amp;amp;nbsp;System.out.println("*\n**\n***\n****\n*****\n");&amp;amp;amp;nbsp; 不知道别人看了这样的代码以后会说:“简单、易懂”还是“没水平”。简单!=水平低不知道我的观点对不对。对,水平高!=复杂但只会写简单代码的coder通常被认为是水平低,在做苦力。我也不知道自己算不算苦力。只会写简单代码肯定不行啦。如果写烦了简单的代码,可以让上司安排点儿有难度的任务做做。

只是有一点困惑,如何理解:
简单!=低水平
复杂!=高水平
何谓简单,何谓复杂?

简单就是花时间最少,花钱最少。
59 楼 rubynroll 2009-04-16  
pufan 写道

用curl怎么看都是bad smell,好端端的语言内部实现不用,非要跨进程去调未知实现,带来的不确定性可想而知。


你的这个回复很有意思, 我估计可能也代表了不少人的想法.

"跨进程去调未知实现"听起来似乎很有"不确定性". 在这里你怀疑了操作系统的能力, 怀疑curl是"未知实现",唯独对自己的程序有信心.

如果是我,面临一个待解决问题时首先想到的是能不能用现存的程序来解决问题,而不是编程去实现它.

58 楼 javaboy2006 2009-04-16  
王者之剑 写道

javaboy2006 写道
王者之剑 写道javaboy2006 写道Java代码 System.out.println("*\n**\n***\n****\n*****\n");&amp;amp;amp;nbsp;&amp;amp;amp;nbsp;&amp;amp;amp;nbsp;&amp;amp;amp;nbsp;System.out.println("*\n**\n***\n****\n*****\n");&amp;amp;nbsp; 不知道别人看了这样的代码以后会说:“简单、易懂”还是“没水平”。简单!=水平低不知道我的观点对不对。对,水平高!=复杂但只会写简单代码的coder通常被认为是水平低,在做苦力。我也不知道自己算不算苦力。只会写简单代码肯定不行啦。如果写烦了简单的代码,可以让上司安排点儿有难度的任务做做。

只是有一点困惑,如何理解:
简单!=低水平
复杂!=高水平
何谓简单,何谓复杂?
57 楼 王者之剑 2009-04-16  
javaboy2006 写道

王者之剑 写道
javaboy2006 写道
Java代码 System.out.println("*\n**\n***\n****\n*****\n");&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;System.out.println("*\n**\n***\n****\n*****\n");&amp;nbsp; 不知道别人看了这样的代码以后会说:“简单、易懂”还是“没水平”。简单!=水平低不知道我的观点对不对。对,水平高!=复杂

但只会写简单代码的coder通常被认为是水平低,在做苦力。
我也不知道自己算不算苦力。

只会写简单代码肯定不行啦。
如果写烦了简单的代码,可以让上司安排点儿有难度的任务做做。
56 楼 javaboy2006 2009-04-16  
王者之剑 写道

javaboy2006 写道
Java代码 System.out.println("*\n**\n***\n****\n*****\n");&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.out.println("*\n**\n***\n****\n*****\n");&nbsp; 不知道别人看了这样的代码以后会说:“简单、易懂”还是“没水平”。简单!=水平低不知道我的观点对不对。对,水平高!=复杂

但只会写简单代码的coder通常被认为是水平低,在做苦力。
我也不知道自己算不算苦力。
55 楼 王者之剑 2009-04-16  
javaboy2006 写道

Java代码 System.out.println("*\n**\n***\n****\n*****\n");&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("*\n**\n***\n****\n*****\n"); 

不知道别人看了这样的代码以后会说:“简单、易懂”还是“没水平”。
简单!=水平低
不知道我的观点对不对。

对,水平高!=复杂
54 楼 javaboy2006 2009-04-16  
System.out.println("*\n**\n***\n****\n*****\n");  

不知道别人看了这样的代码以后会说:“简单、易懂”还是“没水平”。
简单!=水平低
不知道我的观点对不对。
53 楼 h819 2009-04-16  
逞言语之快,无大将风度
多不了大事
52 楼 night_stalker 2009-04-16  
pufan 写道

你说得我同意,从服务的角度来说n个进程提供肯定比单个提供要健壮的多。
但这不意味着非提供服务的逻辑也要多进程呀,就比如这个curl。

你忘记为什么会点进来这个帖子了,不要把简单的事情搞得 N 复杂。
逞一时意气没什么益处,洗洗睡吧。
51 楼 pufan 2009-04-15  
potian 写道

对于复杂的系统来说,多进程可能是最安全、可靠的做法对我们来说,经过5-6年的摸索,很多程序,包括要求24x7的大并发集群的流媒体服务器、要求24x7的n路视频编解码的客户端,唯一可靠的手段就是多进程以及进程管理监测管理进制估计也是google浏览器的想法也是erlang的想法

你说得我同意,从服务的角度来说n个进程提供肯定比单个提供要健壮的多。

但这不意味着非提供服务的逻辑也要多进程呀,就比如这个curl。
50 楼 potian 2009-04-15  
pufan 写道

刚测了一下,一个curl命令在挂住的情况下占用490k左右的内存,300个就是150M左右。

用curl怎么看都是bad smell,好端端的语言内部实现不用,非要跨进程去调未知实现,带来的不确定性可想而知。



对于复杂的系统来说,多进程可能是最安全、可靠的做法

对我们来说,经过5-6年的摸索,很多程序,包括要求24x7的大并发集群的流媒体服务器、要求24x7的n路视频编解码的客户端,唯一可靠的手段就是多进程以及进程管理监测管理进制

估计也是google浏览器的想法

也是erlang的想法
49 楼 pufan 2009-04-15  
刚测了一下,一个curl命令在挂住的情况下占用490k左右的内存,300个就是150M左右。

用curl怎么看都是bad smell,好端端的语言内部实现不用,非要跨进程去调未知实现,带来的不确定性可想而知。
48 楼 yumi301 2009-04-15  
说一个实际例子,之前丢过重要的文件,所以每天要执行备份任务,将源码打包发送到QQ邮箱,大概20M左右,用java写的程序打包发送,建立一个计划任务,每天中文12:10调用程序。

实际中也碰到过发送失败的情况,可以说还蛮频繁,一个星期大概有3天发送失败,都是超时,附件太大了。但是备份任务对健壮性要求不高。要是启动一个jvm进程,每天就为了发送那个邮件,感觉还是不如计划任务方便。
47 楼 王者之剑 2009-04-15  
pufan 写道

robbin 写道
人身攻击的帽子都扣上了,我好怕怕呀。 给你算一个简单的算术吧,极端情况下,curl进程一天堆积300个左右,我实际测试了一下,1个进程占用1.6KB物理内存,300个总共是480KB物理内存。而启动一个独立的JVM进程作为服务来运行,即使不做任何事情,在我们的x86_64的Linux下面至少也要使用32MB物理内存。说到论坛帖子,就不需要ping google了,google也不接受这个ping,这种需求是不存在的,你又预设伪需求,自己为难自己了。还是那句话,YAGNI,不要为不存在的伪需求埋单。

一个线程只有1.6KB,那是初始值吧,curl跑起来还只有1.6KB?你的测试不准确。

是伪需求吗,sina、博客中国等会不会遇到此类需求?

有可能会有,但是你没有问过。
pufan 写道

robbin 写道
这就是博主本身要表达的含义,本来就是要打个鸡窝的(打印三角形星号),结果你非要安装盖大楼的需求给人家瞎斟酌,弄个大并发多线程安全非阻塞IO版本的打印程序出来,说说看这鸡窝搭的那是真壮观!啧啧~

恩,原来你们一直在讨论搭鸡窝的简单性原则呀,唐突了。

我文章的意思是你首先要搞清楚到底是要搭鸡窝还是建大楼。
就是建大楼你也不能一律按500米高十级抗震来打地基。

robbin的需求非常明确:Javaeye发表一篇博客要有一个ping,每天有700篇新博客。
你就算要争论也请证明在完成这个需求的情况下,你的做法高明在哪里?

看你的意思,就是你这个方法不仅javaeye也可以用,博客中国,sina也可以用。
这个功能只是javaeye网站的一个很小的功能,如果所有的功能都按你的标准来,javaeye做成sina一样强大的系统也不是不可以,关键是为什么要做成这样?

你还说到了“本质上的简单”和“形式上的简单”,你提出的方案也挺简单,但是不是更接近本质?这可不好说。因为你并不关注真正的需求,请看我原文中的讨论1。
46 楼 pufan 2009-04-15  
王者之剑 写道

pufan 写道
这段代码在极端情况下会存在n个Callable对象,curl方案会存在n个curl进程(线程)。那个方案比较放心,大家评一评。但是javaeye网站是用ruby做的阿,用java写个程序还得用ruby去调用。

因此ruby弱啊,呵呵。

我说的是思路,实现ruby应该可以做到的。
45 楼 pufan 2009-04-15  
robbin 写道

这就是博主本身要表达的含义,本来就是要打个鸡窝的(打印三角形星号),结果你非要安装盖大楼的需求给人家瞎斟酌,弄个大并发多线程安全非阻塞IO版本的打印程序出来,说说看这鸡窝搭的那是真壮观!啧啧~

恩,原来你们一直在讨论搭鸡窝的简单性原则呀,唐突了。

相关推荐

Global site tag (gtag.js) - Google Analytics