~/a.png

软件真的好难做啊(转载)

2014年9月03日 00:02


转自http://coolshell.cn/articles/4811.html

软件真的好难做啊

2011年6月10日 陈皓 发表评论 阅读评论 3 次点击    
 

还记得以前本站的那一篇“编程好难啊”吗,那是一篇众程序员调侃程序新手的文章,有恶搞的成分在里面。今天要和大家说的这个事没有一些恶搞和调侃的意思,是比较严肃的话题,你一定可以从中收获一些东西。这个话题来自StackOverflow上的一个问题——Cycle in Family Tree Software,这个程序员问了下面这个问题:

我是一个写家族族谱软件的程序员(我用的是C++和Qt),这个软件基本上没有什么问题,真到有一天有个用户报告了一个bug。这个问题是这样的——我这个用户和他女儿生了两个孩子

于是,我程序员的一些断言和硬性条件导致程序报错,因为我的程序在处理这个关系的时候,其发现X即是Y的爸爸,又是Y的爷爷,所以只能报错。

请问,在不需要移除我的断言和数据验证的情况下,我怎么才能解决这个问题

看到这里,请重点阅读一下下面的两点:

  • 如果你看到这里开始兴奋了,请你为你阴暗的心理去面壁反省10分钟,因为这是一个很技术的问题。
  • 如果你开始陷入了深深的思考如何解决这个问题,那么你绝对是一个合格的程序员,因为你已陷入技术已经很深了,有点呆了。

我在前面说过,“这个是一个严肃的话题,你可以从中收获一些东西”,当然,我并不希望你来收获乱伦的知识和心得,酷壳是一个技术博客,应该是收获技术方面的东西。

 

从技术的角度上来说,这是我们经常在设计软件时犯的错误——

1)作了错误的假设(Assumption)

Assumption是软件设计的重大天敌,Assumption的动词Assume意为Ass u me – Ass you and me 。你的假设做得越多,你的设计就越不靠谱。这里的假设是——我们以为family tree是一个tree,其实并不是tree。Assumption是魔鬼

还有一些经典的Assumption如下所示

  • 最著名的就是那个y2k臭虫。
  • 不要以为没有2月30日,在瑞典1712年有2月30日
  • 一分钟有60秒?闰秒呢?
  • 双胞胎的生日是同一天吗?
  • 双胞胎的父亲是同一个?
  • 性别只有男和女?
  • 婚姻只能是异性? 关于这一点,推荐一篇强文——Gay marriage: the database engineering perspective (同性婚姻:数据库工程)

2)没有认真分析用户案例(Use Case)

在设计软件时,我们需要考虑各种各样的用户案例,比如如下的东西:

  • 私生子的问题
  • 一夫多妻或一妻多夫,同父异母,同母异父
  • 就算一夫多妻制违反法律,也会有离异再婚的情况
  • 同性恋的问题,虽然不能繁衍,但可以领养。
  • 换妻活动
  • 各种乱伦关系——这种东西那个民族都不少,尤其是古时候,比如:
    • 先后嫁了两个人其是父子关系(昭君)
    • 达尔文同学和他的表妹,爱因斯坦的二婚是和他的表姐,埃及艳后嫁了她的弟弟,……
    • 顺治同学娶了四个老婆,这四个人还是一家人:姑姑,侄女,妹妹,女儿。(参看这里
    • 刘邦同学的母后干出来的事,相当变态(参看这里
    • 中国古代的“扒灰老” (类似于楼主那个问题的Use Case)

不想再列下去了,人类真TMD恶心,有点要吐了

——————————为了缓解一下恶心的气氛,请允许我插入一个搞笑短文——————————

一位自杀者在他的遗书里讲述了他自杀的原因,听起来实在让人头痛。遗书这样写道:“我和一个寡妇结了婚,她有一个已成年的女儿,我父亲跟我妻子带过来的女 儿结了婚。所以我父亲就成了我的女婿,女儿就成了我的后母,我管父亲叫爸爸,而我父亲也管我叫爸爸;我女儿管我叫爸爸,但我却管她叫妈妈;我还得管我妻子 叫姥姥,因为她是我后母的母亲。不久我女儿,也就是我后母生了一个儿子,他是我同父异母的弟弟,他也得管我叫姥爷,因为他也是我的外孙。后来我妻子,也就 是我姥姥生了一个儿子,他是我后母的弟弟,我是他的外甥,所以儿子管我叫爸爸,我管儿子叫舅舅。另外我是我妻子,也就是我姥姥的外孙,同时也是我姥姥的丈 夫,所已我也是我的外祖父。又因为我妻子是我的外祖母,我的儿子,也就是我的舅舅是我的弟弟和我女儿的弟弟,所以我……我的天哪,这么复杂的关系实在让我 伤透了脑筋,我只有一死才能得以解脱……”

————————————————————————插入完毕————————————————————

看完上面这个短文,不知道你是否和我一样,觉得这么一个简单的程序将是如此难做啊。另外,我决定在下一次的面试中让应聘者来设计Family Tree的程序

我又说多了,现在还是让我们回到技术上来。除了上面那几个观点,我在回复中还看到了如入一些有意思的回复:

  • “我的软件没有bug,是你的生活有bug”——让我想到了程序员惯用的借口
  • “算法中不应该加太多的限制,限制多了反而让算法不灵活。”
  • “移除断言,并不代表就不出错,对于这种rare case,我们最好给一个Warning提醒用户,让用户确认确实是这样的。”
  • “关于解决这个问题,移除那个断言,如果显示上会有问题的话,那就复制一下有不同关系的人就可以了”
  • “你真的应该想想你的软件的价值是什么?市场在哪里?你真的要照顾这样的用户吗?”

挺好的,相信你对软件开发又学到了一些东西。

倍受打击

2014年9月03日 00:02

tubo posted @ 2011年6月15日 19:39 in 未分类 , 0 阅读

倍受打击

看看人家的 Blog , 想想人家从中体现的水平,再看看自己的。

受打击呀。

不过, 知耻而后勇,以后还要继续努力,拓展知识面。

不过,我更想探索,怎样把上学期间学到的各种算法和公式慢慢的用程序表现出来?

伟大的数学。

彷徨着彷徨,迷惘着迷惘

2014年9月03日 00:02

现在的状态。

不要在功能上竞争(转载)

2014年9月03日 00:02

作者: 阮一峰

日期: 2011年7月14日

苹果公司的电子产品,最大的特点就是它的易用性(usability)----简单,美观,容易上手。

它们通常不是功能最强大的,但往往是最好用的。下图的左边是Mac,右边是PC,你觉得看上去哪个更好用?

不要在功能上竞争(转载) - vic_kk - Live and Learn

很多产品经理都想模仿这些特点。但是,一个难题就会随之而来:

很难让一件产品保持简单,同时还具备大量的新功能。

如果你不断为产品添加新功能,在变得强大的同时,它还会变得越来越复杂,增加了用户的使用难度;如果你大力简化产品,在功能上比较单一,那么怎样与竞争对手抗衡呢?

每个产品经理都会面对这个难题。对于新产品,这个问题尤其重要。因为新产品通常很难打开市场,最容易想到的解决办法就是为它不断增加功能,直到引起市场注意为止。但是,这样做是否正确呢?

不要在功能上竞争(转载) - vic_kk - Live and Learn

我对这个问题,一直很困惑,不知道开发新产品的时候,哪一个取向优先,多功能还是易用性?

昨天,我读到了硅谷产品经理Andrew Chen的文章,顿时醍醐灌顶,一下子就找到了答案。

他说,正确的做法,就是不要在功能上竞争。如果你的产品的核心概念行不通,那就重新定位这个产品,而不是为它添加新功能。你必须牢记在心,创造一个有竞争力的新产品,不要着眼于它的功能比别人多,而要着眼于它有一个截然不同的市场定位。

如果市场上都是复杂的企业级工具,那就开发一个针对个人用户的简化版;如果市场上都是很正式的高端葡萄酒,那就开发一种便宜的、针对年轻人的、更休闲的酒精饮料;如果市场上都是提供长篇Blog服务的网站,那就开发一个很简单的、每次只能写140个字的网站;如果市场上都是技术性的、廉价的电子设备,那就开发人性化的、高价的电子设备。

不要在功能上竞争(转载) - vic_kk - Live and Learn

总之,你要做的不是添加功能,而是做一个市场定位不同的产品。

这主要有两个原因:

首先,你不太可能通过一个更多功能的新产品,战胜现有厂商。因为你开发出全面胜过别人的产品,需要很多时间;而且,等你开发出新功能,别人可能又做出了改进,或者拷贝了你的新功能。

其次,比起新功能,消费者更容易为一个特殊定位的产品掏钱。

所以,更好的策略是,开发一个简化的产品,突出某种不同的市场定位,争夺现有厂商的低端用户。这样的话,你不用开发一个全功能的产品,节省了时间,而且由于设计目标不同,更容易做出颠覆式创新(disruptive innovation)。

下面是开发新产品时,几点可行的做法:

  (1)你不是做一个比竞争对手"更好"的产品,而是做一个"不同"的产品。

  (2)你只提供部分功能,但是很好地满足了用户的需求。

  (3)如果新产品的市场反响不好,增加新功能并不能解决问题。你应该重新定位你的产品,想想它能向消费者提供哪些不同的价值。

  (4)在产品设计和推广的每一个环节,都突出它的不同定位。

不要在功能上竞争(转载) - vic_kk - Live and Learn

(完)

文档信息



http://shhuanyayq.blog.163.com/blog/static/9754761420099771617709/


前几天为了和一个名师联系,但是由于台湾的yahoo博客被封了,于是就下了一个tor穿墙。用的正欢,昨天开始,tor就连不上了。现在的GFW还是很厉害的,封的很死,加上现在IP代理发布站都被和谐掉,几个翻墙浏览器也被喀嚓。心里咯噔一下,难道这下没辙了。

网上搜了一下,还是有人有办法的。

tor提供一个网桥中继功能。

可以通过访问 https://bridges.torproject.org/来获取网桥地址。

也可以给 bridges@torproject.org 发邮件,邮件正文为 “getbridges”,立即会收到自动回信。

得到如下信息

Here are your bridge relays:

bridge 67.166.252.156:9001 50190e89af98e18a79828006680748

af5c946a84
bridge 75.190.175.8:443ea20adbc86c91ae4e067289bb5a649ccac297596
bridge 218.189.200.130:4439c88ed76dfb3d42ce98047219e190aad4c970d8a4

然后按图设置,后面的key不需要填写。只要IP和端口即可。
连不上tor的解决方法(综合) - 自由职业者 - 自由职业者的博客

这样设置好,就可以翻墙了。如果地址被封,就再去获取网桥地址了。


Tor被封的解决方法 / 搞笑

2009-09-26 10:47 |阅读(1979) | 标签:科技新知| 字号:  

原载:http://www.my1510.cn/article.php?id=31f729a4cadb7caf

 

今天上网用Tor,发现无法连接。心想难道我疑惑的问题,GFW没两天就给出答案啦——前两天在想,依据技术圈最近流传的宏文《GFW的前世今生》,Tor是很容易封的,客户端启动连接Tor网络的阶段尤其脆弱,为什么大庆当前,GFW还没动静呢?

既然来了,咱们就得想办法,网上搜索加上不断的测试,得到一些经验,供大家参考。

方法一:是设置用网桥,很多网页上有介绍(http://tor.zuo.la/bridges.html.zh-cn),具体方法就不多说了。只说我用的过程,用了十个左右的网桥地址,都是从官方最新获取的,结果每次启动后三十多分钟bootstrapping依然停留在 5%,简单说就是设置网桥没效果。在自己摸索出方法二之后,去Twitter上搜索了一下,发现了某同学说的设置网桥不成功的原因——就是填写网桥配置时 只能写IP地址和端口,后面的Key一定不要写。笔者经过后经过多次正反试验确认了这一点,只要设置时填写网桥的格式正确,就可以连上Tor网络

方法二:是设置代理,首先通过普通网络搜索或者代理网站获得一个可用的HTTP代理,最好是海外的。验证可用后,在Vidalia中设置使用代理访问互联 网。一旦成功连接上Tor网络后,可以在设置中把代理去掉,再次重新启动Tor,这样没有经过代理,访问速度会快一点。以后使用Tor也应该是正常的。

至于其中的原因,我初步猜想:GFW采用了类似IP层特征码识别的检测方法,来阻断Tor客户端连接Tor网络。我们在设置中加上代理,就改变了发送到网络上的数据包及其特征码,因而能躲过了GFW的检测,也就避免了其对Tor连接的攻击。至于连上Tor网络之后就无需再用代理,应该是因为连上一次Tor 网络后,Tor软件就在本地存放了一些Tor网络的节点信息,可供下次连接使用。

经过分析对比,目前笔者已经找到了Tor节点信息的文件位置是“C:\Documents and Settings\Administrator\ApplicationData\Tor\”(其中C是系统盘,Administrator是用户名,具体到个人的机器会有不同),共有三个文件保存节点相关信息,cached-certscached-consensuscached-descriptors,保存这三个文件以备不时之需,应该也是有作用的。

 

Tor有关Bridge relays的建议与配置方案

04 5th, 2008 by MikeZhang

原载:http://logmike.com/?p=232

 

今天偶然间看到网上Andrew的一文大声疾呼:请中国的Tor中继服务提供者仅把自己设置为”中间人””后,深有感触。虽然实际使用中我并没有发现国内torrelay服务器被出用最终出口的情况,但只要是公开的relay服务器肯定有可能被利用来做最终出 口。如果最终出口在大--网络中的话,的确就失去意义了。虽然可能不会被找到访问者,但多少也有可能为torrelay服务运行者带来多多少少地麻 烦。所以在大--网络中设置仅以Bridgerelays模式运行torrelay看来是十分有必要的。

Win版的Tor设置Bridge relays方式为:
设定->中继->Tor 网络中继->服务策略->清除所有的选择(也就是一个也别选中)->保存

Linux版的Tor设置Bridge relays的方式稍复杂点,我试了一下,具体设置如下:
# vi /usr/local/etc/tor/torrc

在原来的ORPort设置的最后面,把此设置打开:
ExitPolicy reject *:*
即不允许原来的tor relay任何服务作出口,由于我还要运行着tor的匿名网站,故此断的relay其它设置还要保留着。

然后在此配置文件的最后面,把BridgeRelay的相关配置的前三行enable
ORPort 443
BridgeRelay 1
RelayBandwidthRate 500KBytes
#ExitPolicy reject *:*

保存后重启tor的服务即可。

如果你把debuglog打开,应该可以看到都是一些类似如下的日志记录:
Apr 05 11:44:23.939 [debug] directory_handle_command_get():rewritten url as‘/tor/server/d/0E1353F11009ECEA964B01930………………………………..(
太长了,中间省略)………………….z’.
Apr 05 11:44:23.939 [debug] conn_write_callback(): socket 19 wantsto write.
Apr 05 11:44:23.939 [debug] connection_dir_finished_flushing():Finished writing server response. Closing.
Apr 05 11:44:23.939 [debug] conn_close_if_marked(): Cleaning upconnection (fd 19).
Apr 05 11:44:23.939 [debug] connection_remove(): removing socket 19(type Directory), n_conns now 12
Apr 05 11:44:23.939 [debug] _connection_free(): closing fd19.
Apr 05 11:44:24.034 [debug] conn_read_callback(): socket 8 wants toread.
Apr 05 11:44:24.034 [debug] connection_handle_listener_read():Connection accepted on socket 19 (child of fd 8).
Apr 05 11:44:24.034 [debug] connection_add(): new conn typeDirectory, socket 19, n_conns 12.
Apr 05 11:44:24.166 [debug] conn_read_callback(): socket 19 wantsto read.
Apr 05 11:44:24.166 [debug] read_to_chunk(): Read 1448 bytes. 1448on inbuf.
Apr 05 11:44:24.166 [debug] fetch_from_buf_http(): headers not allhere yet.
Apr 05 11:44:24.166 [debug] directory_handle_command(): command notall here yet.
Apr 05 11:44:24.181 [debug] global_read_bucket now 10485760.
Apr 05 11:44:24.181 [debug] global_write_bucket now 10485760.
Apr 05 11:44:24.181 [debug] global_relayed_read_bucket now2048000.
Apr 05 11:44:24.181 [debug] global_relayed_write_bucket now2048000.
Apr 05 11:44:24.181 [debug] or_conn->read_bucket now10485760.
Apr 05 11:44:24.181 [debug] or_conn->read_bucket now10485760.
Apr 05 11:44:24.181 [debug] circuit_is_acceptable(): Skippingone-hop circuit.
Apr 05 11:44:24.181 [debug] circuit_is_acceptable(): Skippingone-hop circuit.
Apr 05 11:44:24.181 [debug] circuit_get_open_circ_or_launch(): oneon the way!
Apr 05 11:44:24.378 [debug] conn_read_callback(): socket 20 wantsto read.
Apr 05 11:44:24.378 [debug] connection_read_to_buf(): 20: starting,inbuf_datalen 0 (0 pending in tls object). at_most 16384.
Apr 05 11:44:24.379 [debug] connection_read_to_buf(): After TLSread of 1024: 1098 read, 0 written
Apr 05 11:44:24.379 [debug]connection_or_process_cells_from_inbuf(): 20: starting,inbuf_datalen 1024 (0 pending in tls object).

这些log和之前非仅仅是bridgerelays的模式的日志是完全不一样的。

同时在我把torrelay设置成bridgerelays运行后,再检测原来设置在此之上的“http://o2ykh5czcfujbqty.onion/”tor匿名网站也是正常的。

这样就一切ok设置好了。

关于Bridgerelays在配置文件里有如下一段说明:
## Bridge relays (or “bridges” ) are Tor relays that aren’t listedin the
## main directory. Since there is no complete public list of them,even if an
## ISP is filtering connections to all the known Tor relays, theyprobably
## won’t be able to block all the bridges. Unlike running an exitrelay,
## running a bridge relay just passes data to and from the Tornetwork –
## so it shouldn’t expose the operator to abusecomplaints.

主要意思就是说以Bridgerelays模式运行后,你的torrelay服务器就不会在公开的relay目录里显示出来了,这样可以防止被当地ISP根据公开的relay目录来block,当然你也只能作一个幕后英雄了。:-)不过此种情况实在太适合我们目前的情况了,我把我的tor relay服务器调整成这种模式后,所以我也宁可当一个幕后英雄。

非常感谢Andrew在其blog上的文章给我的启发。

 


/etc/hosts 备份

2014年9月03日 00:01

# /etc/hosts: Local Host Database
#
# This file describes a number of aliases-to-address mappings for the for
# local hosts that share this file.
#
# In the presence of the domain name service or NIS, this file may not be
# consulted at all; see /etc/host.conf for the resolution order.
#

# IPv4 and IPv6 localhost aliases
127.0.0.1 localhost
::1 localhost

#
# Imaginary network.
#10.0.0.2 myname
#10.0.0.3 myfriend
#
# According to RFC 1918, you can use the following IP networks for private
# nets which will never be connected to the Internet:
#
# 10.0.0.0 - 10.255.255.255
# 172.16.0.0 - 172.31.255.255
# 192.168.0.0 - 192.168.255.255
#
# In case you want to be able to connect directly to the Internet (i.e. not
# behind a NAT, ADSL router, etc...), you need real official assigned
# numbers. Do not try to invent your own network numbers but instead get one
# from your network provider (if any) or from your regional registry (ARIN,
# APNIC, LACNIC, RIPE NCC, or AfriNIC.)
#
203.208.46.30 www.google.com
203.208.46.30 picasaweb.google.com

203.208.46.30 lh1.ggpht.com
203.208.46.30 lh2.ggpht.com
203.208.46.30 lh3.ggpht.com
203.208.46.30 lh4.ggpht.com
203.208.46.30 lh5.ggpht.com
203.208.46.30 lh6.ggpht.com
203.208.46.30 lh6.googleusercontent.com
203.208.46.30 lh5.googleusercontent.com
203.208.46.30 lh4.googleusercontent.com
203.208.46.30 lh3.googleusercontent.com
203.208.46.30 lh2.googleusercontent.com
203.208.46.30 lh1.googleusercontent.com
203.208.46.30 images1-focus-opensocial.googleusercontent.com
203.208.46.30 images2-focus-opensocial.googleusercontent.com
203.208.46.30 images3-focus-opensocial.googleusercontent.com
203.208.46.30 images4-focus-opensocial.googleusercontent.com
203.208.46.30 images5-focus-opensocial.googleusercontent.com
203.208.46.30 images6-focus-opensocial.googleusercontent.com
203.208.46.30 s6.googleusercontent.com
203.208.46.30 s5.googleusercontent.com
203.208.46.30 s4.googleusercontent.com
203.208.46.30 s3.googleusercontent.com
203.208.46.30 s2.googleusercontent.com
203.208.46.30 s1.googleusercontent.com

203.208.46.30 plus.google.com
203.208.46.30 talkgadget.google.com
203.208.46.30 ditu.google.com
203.208.46.30 maps-api-ssl.google.com
203.208.46.30 mail.google.com
203.208.46.30 docs.google.com
203.208.46.30 scholar.l.google.com
203.208.46.30 news.google.com
203.208.46.30 video.google.com
203.208.46.29 translate.google.com

203.208.46.30 profiles.google.com

autocomplete-mode + flyspell-mode

2014年9月03日 00:01

简介:
A known bug in Autocomplete-mode
转载请注明出处


今天发现,在 enable 了 flyspell-mode 以后,autocomplete 不能正常工作了, 查了一下,发现是 autocomplete 的一个 known issue.
下面的内容摘自: , 描述了这一问题,并给出了解决方法:

11.1. Auto completion will not be started in a buffer flyspell-mode enabled

A way of delaying processes of flyspell-mode disables auto completion. You can avoid this problem by M-x ac-flyspell-workaround. You can write the following code into your ~/.emacs.

(ac-flyspell-workaround) 


Author:yangyingchao, 2011-07-26

简介:
Solution of how to disable Cache in Chromimum browser.
转载请注明出处


There's an option which does not appear in chromium's manual page --- "-disk-cache-dir".
This option specifies where the disk cache should be stored.
Hence, under Linux, we can set the disk-cache-dir to /dev/null. In that way, the cache will be disabled, and all contents will be read from the Internet directly.

Here is what the modified chromium-browser-chromium.desktop looks like:

[Desktop  Entry] 
Name=Chromium Type=Application 
Comment=Open-source version of Google Chrome web  browser 
Exec=chromium-browser %U --disk-cache-dir=/dev/null 2>/dev/null 
TryExec=chromium-browser 
Icon=chromium-browser
Categories=Network;WebBrowser; 
MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;   



Why I need to disable file cache?
Well, on my machine, when chromium browser starts up, it keeps reading cache and take a long time to show the homepage.
So I decided to disable it.



Author:yangyingchao, 2011-07-30

stardict 字典下载

2014年9月03日 00:01

刚刚发现, sourceforge  上的字典都被 Remove 了,找了一下,发现这里还有一些存货,不容易……

http://debian.ustc.edu.cn/debian-uo/dists/sid/ustc/pool/stardict/