ZZZ, 好一个伟业(抓图 from 水木 bbs)!
2014年9月03日 00:02
Happy coding
转自http://coolshell.cn/articles/4811.html
还记得以前本站的那一篇“编程好难啊”吗,那是一篇众程序员调侃程序新手的文章,有恶搞的成分在里面。今天要和大家说的这个事没有一些恶搞和调侃的意思,是比较严肃的话题,你一定可以从中收获一些东西。这个话题来自StackOverflow上的一个问题——Cycle in Family Tree Software,这个程序员问了下面这个问题:
我是一个写家族族谱软件的程序员(我用的是C++和Qt),这个软件基本上没有什么问题,真到有一天有个用户报告了一个bug。这个问题是这样的——我这个用户和他女儿生了两个孩子。
于是,我程序员的一些断言和硬性条件导致程序报错,因为我的程序在处理这个关系的时候,其发现X即是Y的爸爸,又是Y的爷爷,所以只能报错。
请问,在不需要移除我的断言和数据验证的情况下,我怎么才能解决这个问题?
看到这里,请重点阅读一下下面的两点:
我在前面说过,“这个是一个严肃的话题,你可以从中收获一些东西”,当然,我并不希望你来收获乱伦的知识和心得,酷壳是一个技术博客,应该是收获技术方面的东西。
从技术的角度上来说,这是我们经常在设计软件时犯的错误——
Assumption是软件设计的重大天敌,Assumption的动词Assume意为Ass u me – Ass you and me 。你的假设做得越多,你的设计就越不靠谱。这里的假设是——我们以为family tree是一个tree,其实并不是tree。Assumption是魔鬼。
还有一些经典的Assumption如下所示
在设计软件时,我们需要考虑各种各样的用户案例,比如如下的东西:
不想再列下去了,人类真TMD恶心,有点要吐了。
——————————为了缓解一下恶心的气氛,请允许我插入一个搞笑短文——————————
一位自杀者在他的遗书里讲述了他自杀的原因,听起来实在让人头痛。遗书这样写道:“我和一个寡妇结了婚,她有一个已成年的女儿,我父亲跟我妻子带过来的女 儿结了婚。所以我父亲就成了我的女婿,女儿就成了我的后母,我管父亲叫爸爸,而我父亲也管我叫爸爸;我女儿管我叫爸爸,但我却管她叫妈妈;我还得管我妻子 叫姥姥,因为她是我后母的母亲。不久我女儿,也就是我后母生了一个儿子,他是我同父异母的弟弟,他也得管我叫姥爷,因为他也是我的外孙。后来我妻子,也就 是我姥姥生了一个儿子,他是我后母的弟弟,我是他的外甥,所以儿子管我叫爸爸,我管儿子叫舅舅。另外我是我妻子,也就是我姥姥的外孙,同时也是我姥姥的丈 夫,所已我也是我的外祖父。又因为我妻子是我的外祖母,我的儿子,也就是我的舅舅是我的弟弟和我女儿的弟弟,所以我……我的天哪,这么复杂的关系实在让我 伤透了脑筋,我只有一死才能得以解脱……”
————————————————————————插入完毕————————————————————
看完上面这个短文,不知道你是否和我一样,觉得这么一个简单的程序将是如此难做啊。另外,我决定在下一次的面试中让应聘者来设计Family Tree的程序。
我又说多了,现在还是让我们回到技术上来。除了上面那几个观点,我在回复中还看到了如入一些有意思的回复:
挺好的,相信你对软件开发又学到了一些东西。
作者: 阮一峰
日期: 2011年7月14日
苹果公司的电子产品,最大的特点就是它的易用性(usability)----简单,美观,容易上手。
它们通常不是功能最强大的,但往往是最好用的。下图的左边是Mac,右边是PC,你觉得看上去哪个更好用?
很多产品经理都想模仿这些特点。但是,一个难题就会随之而来:
很难让一件产品保持简单,同时还具备大量的新功能。
如果你不断为产品添加新功能,在变得强大的同时,它还会变得越来越复杂,增加了用户的使用难度;如果你大力简化产品,在功能上比较单一,那么怎样与竞争对手抗衡呢?
每个产品经理都会面对这个难题。对于新产品,这个问题尤其重要。因为新产品通常很难打开市场,最容易想到的解决办法就是为它不断增加功能,直到引起市场注意为止。但是,这样做是否正确呢?
我对这个问题,一直很困惑,不知道开发新产品的时候,哪一个取向优先,多功能还是易用性?
昨天,我读到了硅谷产品经理Andrew Chen的文章,顿时醍醐灌顶,一下子就找到了答案。
他说,正确的做法,就是不要在功能上竞争。如果你的产品的核心概念行不通,那就重新定位这个产品,而不是为它添加新功能。你必须牢记在心,创造一个有竞争力的新产品,不要着眼于它的功能比别人多,而要着眼于它有一个截然不同的市场定位。
如果市场上都是复杂的企业级工具,那就开发一个针对个人用户的简化版;如果市场上都是很正式的高端葡萄酒,那就开发一种便宜的、针对年轻人的、更休闲的酒精饮料;如果市场上都是提供长篇Blog服务的网站,那就开发一个很简单的、每次只能写140个字的网站;如果市场上都是技术性的、廉价的电子设备,那就开发人性化的、高价的电子设备。
总之,你要做的不是添加功能,而是做一个市场定位不同的产品。
这主要有两个原因:
首先,你不太可能通过一个更多功能的新产品,战胜现有厂商。因为你开发出全面胜过别人的产品,需要很多时间;而且,等你开发出新功能,别人可能又做出了改进,或者拷贝了你的新功能。
其次,比起新功能,消费者更容易为一个特殊定位的产品掏钱。
所以,更好的策略是,开发一个简化的产品,突出某种不同的市场定位,争夺现有厂商的低端用户。这样的话,你不用开发一个全功能的产品,节省了时间,而且由于设计目标不同,更容易做出颠覆式创新(disruptive innovation)。
下面是开发新产品时,几点可行的做法:
(1)你不是做一个比竞争对手"更好"的产品,而是做一个"不同"的产品。
(2)你只提供部分功能,但是很好地满足了用户的需求。
(3)如果新产品的市场反响不好,增加新功能并不能解决问题。你应该重新定位你的产品,想想它能向消费者提供哪些不同的价值。
(4)在产品设计和推广的每一个环节,都突出它的不同定位。
(完)
前几天为了和一个名师联系,但是由于台湾的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和端口即可。
这样设置好,就可以翻墙了。如果地址被封,就再去获取网桥地址了。
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-certs、cached-consensus、cached-descriptors,保存这三个文件以备不时之需,应该也是有作用的。
04月 5th, 2008 by MikeZhang
今天偶然间看到网上Andrew的一文“大声疾呼:请中国的Tor中继服务提供者仅把自己设置为”中间人””后,深有感触。虽然实际使用中我并没有发现国内tor的relay服务器被出用最终出口的情况,但只要是公开的relay服务器肯定有可能被利用来做最终出 口。如果最终出口在大-陆-网络中的话,的确就失去意义了。虽然可能不会被找到访问者,但多少也有可能为tor的relay服务运行者带来多多少少地麻 烦。所以在大-陆-网络中设置仅以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的服务即可。
如果你把debug的log打开,应该可以看到都是一些类似如下的日志记录:
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(): on
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.on
这样就一切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 da
## so it shouldn’t expose the operator to abusecomplaints.
主要意思就是说以Bridgerelays模式运行后,你的torrelay服务器就不会在公开的relay目录里显示出来了,这样可以防止被当地ISP根据公开的relay目录来block,当然你也只能作一个幕后英雄了。:-)不过此种情况实在太适合我们目前的情况了,我把我的tor relay服务器调整成这种模式后,所以我也宁可当一个幕后英雄。
非常感谢Andrew在其blog上的文章给我的启发。
今天发现,在 enable 了 flyspell-mode 以后,autocomplete 不能正常工作了, 查了一下,发现是 autocomplete 的一个 known issue.
下面的内容摘自: , 描述了这一问题,并给出了解决方法:
flyspell-mode
enabledA 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)
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; |