Shell's Home

Aug 23, 2011 - 1 minute read - Comments

第一个debian官方包请求出来

贝壳的第一个为debian官方贡献的包出炉了,地址在这里。之前也发过一个ITP,结果发现莫名其妙有人在做了。不知道为什么没有在wnpp中发现,结果弄的好不尴尬。 大概说一下,为debian官方贡献打包,你需要了解这个包的基本情况。例如用哪种语言写的,有什么依赖关系,是什么授权,等等。尤其是授权,debian有所谓的dsfg方针(不知道的看这里,这里,这里)。如果你打出来的包包含dsfg不许可的内容,你的包会被紧急移除,直到修复这个问题。尤其值得注意的是,debian要求文件级的授权,就是说,即使有一个文件不符合授权要求,整个包也会不通过,哪怕包本身声明为开源授权。之前ibus还是fctix,因为用了拼音加加的词库,就享受了一把这个待遇。另外,如果可以的话,最好征求一下上游维护者的意见(一般就是作者)。因为debian的bug系统中的问题是你需要解决的,而这些问题通常没有上游维护者是很难搞定的。当然,如果你觉得自己搞的定,或者可以出了问题再联系,那也可以。 当你搞明白这些问题后,通常需要先发一个ITP(Intent To Adoption)出来,表示你要打包,别人不要抢。通常是用reportbug来进行提交,汇报wnpp(Work-Needing and Prospective Packages)这个包的bug。然后程序会问你确定?确定的话,会要求你选择是哪种报告,其中就有ITP。当你的ITP通过后,你会收到一个bugnumber,这个bugnumber会在changelog中用到。 另外说明一下bts(bug tracking system)的基本用法。你需要给control@bugs.debian.org发送一封邮件,内容是bts的控制指令,每行一条。碰到无法识别的指令时,bts停止解析。通常习惯在最后写一个thanks来停止解析,也表示礼貌。指令系统可以参考[3]。 然后开始干活。干活的方法参考Debian 新维护人员手册。其中注意在changelog中填入你刚刚申请到的ITP,这样当包通过后,会自动关闭你的ITP。提交的包需要是lintian clean的,即自动检查程序没有发现错误。通常你可以在本地系统安装lintian进行检查。 当你完成打包工作(没法详述,太复杂了,自己看文档吧),你需要上传到mentors系统,然后让DD审查你的包。你首先要在http://mentors.debian.net拥有一个账户,这个账户的email将来会用于给你发送bug通知之类的东西。当你完成账户创建,你会在页面上看到要求上传一个gpgkey。gpg创建key都会吧?记得做4096位密钥。另外填写姓名的时候,用最好真实姓名作为名称,网名进nickname,尤其是大部分中国人都有一个拼音姓名和一个英文姓名的时候。。。 然后,你的主页上有一个说明,会让你复制一些数据到你的~/.dput.cf中。dput是用来上传源码包的工具。如果你按照说明去复制,那么你就可以用dput debexpo.changes来上传你的包。其中有几点需要注意的,一个是debexpo不能丢,否则会默认传到ftp.debian.org上去,然后失败。另外changes和dsc必须经过你上传那个公钥对应的私钥的签署,否则签名验证失败,你的包上传行为就会失败。如果你的系统中有多个private key,那么dpkg-buildpackage会不知道如何打包。用-k参数加上你的私钥id,就可以指定使用哪个私钥进行签署。 当你的包完成上传后,你可以在my packages下面看到。注意服务器检查结果,本地通过lintian的包在远程还是可能爆出错误,所以再检查一下。 如果一切都没有问题。你可以将package中的Needs a sponsor改为Yes,然后等DD注意到你的包。当然,还可以向debian-mentors@lists.debian.org发送一封RFS(Request For Sponsor)的邮件,提醒DD的关注。具体的内容模板在成功上传的邮件中会提示你,一般是http://mentors.debian.net/package/rfs/[package name]这种格式。打开url,里面就是你的RFS邮件规范的目标地址,标题,还有内容。 OK,最后总结一下,整个过程中我们用到了三个系统。第一个是debian bts,通过提起bug来表示你准备打包。第二个是mentors.debian.net,通过注册来上传包。第三个是debian-mentors@lists.debian.org,通过maillist来提醒DD检查你的包。过程有一点小繁琐,不过熟悉之后还不算繁琐。如果真的觉得繁琐,debian在包检测和打包过程中的一堆事情更是会烦死人的。 Reference: [1].Debian 缩略语http://www.cnblogs.com/lidaobing/archive/2010/05/21/1740508.html [2].软件如何进入 Debianhttp://www.cnblogs.com/lidaobing/archive/2010/05/02/1726138.html [3].Introduction to the bug control and manipulation mailserverhttp://www.debian.org/Bugs/server-control

Aug 18, 2011 - 1 minute read - Comments

一次系统和数据迁移

在文件系统选型后,贝壳骤然发现用ext3保存媒体文件是一件很傻的事情。耗费空间多,性能差,安全性低。根据文章结论,其实最好的文件系统是xfs。同时,贝壳的mini-itx空间基本满了(/home分区75-80%)。所以,贝壳准备买一块新的硬盘,然后将数据迁移过去。 硬件选择上,贝壳询问了熟悉的硬件商。他说日立没货,WD的盘问题比较多,推荐希捷的。而且只有绿盘,具体型号是ST2000DL003-9VT166,SataIII,常规转速5900。ST的2T盘入手后,贝壳做了一下基础测试,hdparm分数是,原本的WD硬盘90M/s,新的ST硬盘70M/s,公司的硬盘99M/s。看来硬盘性能还是WD的比较好一点,当然,也可能是因为新硬盘本身就是低档硬盘。 贝壳的第一选择,是按照原本的U盘安装设置,安装debian系统。不过前后两次都可耻的失败了,主要原因是mini-itx对U盘启动的支持并不是很好。被迫,用新买的大型电脑安装,又失败。原因是6.0的安装镜像对boot.img.gz方式的U盘启动支持不良。算了,先装5.0升级。没想到,这个原因直接导致了贝壳两次系统安装完毕后无法引导升级。为什么?因为硬盘的尺寸刚刚好比2T大了点。gurb升级到grub2的时候,为了让你支持全部空间,很好心的帮你升级到了gpt。然而gpt需要一个分区来保存一些信息,新多出来的空间又刚好不足以保存这个数据。因此,grub-pc就升级失败,而且救都没法救——因为没空间了。 两次折腾下来,贝壳基本搞明白了为什么。然而要解决这个问题,就要手工分区,计算大小,产生lvm,设定,然后debootstrap,再设定。或者就直接使用debian 6.0的安装镜像。这个时候,悲崔的事情来了——U盘安装那篇文章的上一节,就说明了如何直接使用usb启动iso,直接cat iso > /dev/sdX就可以了。早知道这么简单,何必折腾那么一大套呢,哎。 debian 6.0的安装系统比5.0的好了很多,磁盘分区支持gpt,直接就生成了bios_grub分区。lvm2的支持增加了vg级别的控制,而不仅仅只能控制lv的生成和删除。同时增加了软raid的支持。这就很好的解决了贝壳当前的问题。 贝壳的分区方案是,gpt分区表,一个bios_grub分区,一个ext2的boot分区,一个lvm分区。lvm上面分8G的root,ext4格式。4G的swap,可以适应当前内存和升级到4G的内存(linux swap推荐是,4G以下两倍于内存,4G以上和内存一致)。1.7T的home,xfs格式。剩余268G。为什么要剩余?因为xfs只能扩展不能缩小,如果我需要扩展root和swap,或者需要产生新的lv来做虚拟机,不留下一定空间会出问题的。如果home不足,我再扩展150G基本可以解决问题。 分区和安装都很顺利,然而approx对新的系统基本没有缓冲作用。我略微想了一下,大概明白了为什么——原有系统是用i386架构和amd64内核,而新系统则是架构内核都是amd64。或者通俗来说,原系统是64位内核下的32位混合系统,而新系统是彻底的64位系统。32位的包对64位的系统一点用都没有,所以approx原有的包都白缓存了。 好吧,瑕不掩瑜,这次升级基本还是成功的。安装对应软件包,复制数据(推荐首次cp -a,速度快,后面用rsync保证同步),修改属主(否则很多程序无法启动)。尤其需要注意,mldonkey在downloads.ini中,不但保存了以哪个用户启动,同时也保存了用户id。新系统中用户名和id对应关系会发生变化,因此要修改正确。基本——事情就完了。 一个小细节是,uwsgi由于amd64升级,所以无法使用。贝壳解决了一下问题,重新编译这个包。另外,debian官方的包出来了,目前处于sid状态,大家可以等着什么时候进入testing状态了。

Aug 17, 2011 - 1 minute read - Comments

除虫故事(三)

第三个bug是刚出的,贝壳刚刚从现场回来,提交了bug系统关闭申请。 问题是这样的,我们有一套系统,为客户提供从web访问某台windows的能力,作为管理系统使用。这个系统的后台使用了三四个不同的程序,通过管道通讯。目标设备上有一个组件,要适应2000/2003/2008的32位和64位环境,非常复杂。最近,贝壳将这套系统的目标设备的组件进行了重编译,提供了64位版本。然后测试发现,32位系统不工作了,64位系统正常。 第一反应是什么?一定是组件有问题?贝壳在服务器上,直接使用连接程序去连接,结果是成功的。这个表明组件应当是正常的,或者部分正常。问题就在web页面到连接程序的过程中某处。 负责web界面到连接程序的工程师同事接手了下一步排查,他也是一头雾水。系统看来一切正常,连接程序明明可以工作,为什么从web页面调用就会失败呢?而且只有32位会失败。web页面对CPU字长(而且是目标设备的CPU字长)并不敏感阿,这个听起来不合理。 测试过程中,测试部门的同事偶然的看了一下日志系统,发现了问题。我们的连接程序会写出日志,默认情况下这个日志的属主应当是web.web的,而当时的日志是root.root的,而且权限是644。所以当连接程序被直接调用,当前id是root,就可以连接成功。而连接程序被web调用,当前id是apache,日志写出就会失败,程序就挂了,目标设备会失去反应。 出现这个错误的原因也很直观,在某次调试后,有人删除了原始的日志,并且直接执行了连接程序。但奇怪的是,同样是连接程序挂掉,为什么64位就可以继续执行呢?我们讨论不出为什么,只有基本猜测,64位设备是2008,rdp服务版本比较高,所以相对健壮。 所以,实际的错误是两个。一个是日志权限导致的连接程序不工作。另一个是64位下不正常的连接程序依旧可以工作。 好吧,总结一下这个奇怪的问题中的教训。 1.隔离最小差异。要验证是否是组件升级导致问题,一定要进行旧组件测试,然后再测试新组件。万不可假定旧组件可以正常运行,直接测试新组件,从而将非组件问题带入排查。 2.单元测试隔离。每个部分都要做单元测试,如果测试通过却无法连接,那就是环境问题。再查不出,再检查通讯/调用记录。 3.通讯系统关联错误。当两个程序通过通讯工作,其中一个程序死亡时。另一个程序应当能够检测并且报错退出,而不是出现各种异常反应。 4.日志底线设计。程序一定要写日志,如果日志写不出,就写系统日志,再写不出,设法报全局错误。

Aug 16, 2011 - 1 minute read - Comments

ACC lead to no core temp reading?

I bought a Phenom II X4 955 CPU month ago, recently I find that HWMonitor can’t read core temp, just motherboard temp. I googled it and find this article. This article said that ACC is a tech will make AMD X3 work like X4 byunlock cores in BIOS. But CPU core temp sensors will not work, even use a real four cores CPU. 贝壳一个月前买了一块羿龙IIX4955(黑盒),但是最近发现HWMonitor读不出核心温度,只有主板温度。放狗搜了一下,找到这篇文章。根据这篇文章说,ACC是一种能够让AMD三核CPU像四核一样工作的技术,只要在BIOS中打开unlock cores选项就好。但是这个会使得CPU的核心温度传感器不工作,即使你真的有四个核,而不是仿冒四核。

Aug 15, 2011 - 2 minute read - Comments

linux下的文件系统选型

贝壳原来一直认为文件系统可以随便选,结果最近吃了两次苦头。一个是btrfs对虚拟机支持不良,另一个是特定情况下xfs性能比ext3高20倍。痛定思痛,打算列一下文件系统选型的方法和依据,欢迎拍砖。  下面我列一下纳入参考的文件系统,当然,ntfs就不要出来搞基了,玩嵌入式/光盘live之类的朋友也不要来凑热闹了阿。btrfs(简介), ext3, ext4(简介), jfs(简介), reiserfs, xfs,基本涵盖常用文件系统。最下面加入ntfs和zfs对比,实际上不参与选型。以下进制换算为1024,大小依次为KB,MB,GB,TB,PB,EB,ZB。 --------------- --------- -------------- ---------------- ---------------- ---------------- ------------------ --------- ----------- ------------ 文件系统 btrfs ext3 ext4 jfs reiserfs reiser4 xfs ntfs zfs 最大卷容量 16 EB 32 TB 1 EB (16TB) 32 PB 16 TB ?? 16 EB 256 TB 16 EB 最大文件容量 16 EB 2 TB 16 TB 4 PB 8TB 8TB 8 EB 16 TB 16 EB 目录结构 B tree list/tree list/Htree B tree B+ tree dancing B\* tree B+ tree B+ tree hash table 文件分配 extents bitmap/table bitmap/extents bitmap/extents bitmap ?

Aug 11, 2011 - 1 minute read - Comments

硬盘底座入手

贝壳买的新硬盘底座入手了,质感不错,很沉,只是在插入硬盘的时候对准不是很方便,总是要对一下才能对准。而且硬盘插上去有点摇晃,如果长时间使用还是会伤硬盘的。不过针对短时间使用,底座正是一个好解决方案。 硬盘底座,就是将硬盘插上去,然后接入电脑的器件。现在大部分硬盘底座都是sata接口的,以前有IDE接口的,贝壳试过,不稳。IDE本身就不支持热插拔,硬做上去当然好不到哪里去。通常而言,硬盘底座/移动硬盘/sata热插拔是三种相关又各有特点的解决方案。底座的目标是使得硬盘可以更换,使用底座的人,多数希望在一台电脑上更换使用一个接一个的硬盘,对硬盘没有特殊要求。移动硬盘,基本就是把底座的硬件和硬盘捆绑到一起。使用移动硬盘的人,是希望一个硬盘在一台台的电脑上使用,对电脑没有特殊要求。而sata热插拔是强调热,即可以不关机接入设备,对台式机用处不大。通常是现场空间不足了,不能关机增加存储设备造成的需求,对插拔次数支持并不好。有资料说,普通sata接口大概能承受50次的插拔。普通硬盘安装而言,50次是一个非常足够的数目了,但是移动硬盘使用的话,几天就用光了。 底座支持两种接口,usb2.0和esata。前者的速率是480bps,后者速率是3.0Gbps,合前者最高60M/s,后者最高375M/s。一块民用硬盘的突发速率往往高达150M/s,usb对于普通台式机而言显然是远远不足了。而且esata直接挂入硬盘控制设备下面,而USB则是挂入USB控制器链,效率上说差了一点不说,而且esata是作为普通硬盘对等管理的。 贝壳本次的方案,是通过一根sata 2 esata接线,将mini-itx主板上的一路未使用的sata引出机箱,连接到底座上。但是linux下要支持esata,必须在BIOS中将SATA设备模式改为AHCI,而后重启进入系统,可以看到设备变了。当然,这个改变对于windows系统来说是个灾难,但是linux系统完全不在乎这个事情。 debox:\~\# lspci | grep -i sata 00:1f.2 SATA controller: Intel Corporation N10/ICH7 Family SATA AHCI Controller (rev 01) debox:\~\# lsmod | grep ahci ahci 25089 2 libahci 22767 1 ahci libata 149043 2 ahci,libahci 这次更改造成的一个额外效果就是,机器上的普通sata硬盘速度也上升了。从原来的71M/s到了115M/s,提升相当惊人。

Aug 10, 2011 - 1 minute read - Comments

读一读我的blog用户

好吧,应该是viewer,姑且称为user。谢谢你们的关注,这个blog才撑的下去。坚持写blog,尤其是技术blog,是个很辛苦的事情。查证技术很花时间,也没什么回报,一不留神还会成了各大互联网公司的免费写手。不过看看每个月的ip和pv,好吧,还是值得的。 说是读一读,当然,我不会有你们的名单。我做的是审计,可不代表我会审查来的每个人。但是我的blog里面安装了统计系统,google还有个webmaster。我们来看看数据报表。 首先是,大概1/3的我的读者是geek,或者足够geek,其余是麻瓜。各种windows系统占了2/3,我觉得普通blog不会出现这个比例… 然后,firefox家族占了一半不到一点的流量,chrome占1/4,一点的safari,其余的IE。感谢党,感谢国家,感谢CCAV,这样的比例让我在抛弃IE的时候决定不会太艰难。 来源,google不计,第一是baidu,其次twitter,然后豆瓣。google不计是因为通过google过来的人都算不出来…. 爬虫上说,google占了一半,其次是sogou(这个混帐爬虫占了1/3的流量却没带来几个ip/pv)。然后是Yahoo和baidu,两个没差多少。 google reader订阅数是180,平均每周更新3.3篇,我还算努力吧? 最后是很丢脸的ip/pv,上个月ip2700/pv8900,本月预期ip3300/pv8600。

Aug 9, 2011 - 1 minute read - Comments

linux下多种文件系统在小规模追加写下的性能

因为公司需要,所以贝壳最近做了一个比较。多种文件系统,在小规模写下的性能。 首先要说明的一点是,贝壳的blog为了保持便于传播,因此惯例是不贴图。这次的图,全部在blog同空间的相册上,通过引用方式放原始连接,可以保持原味查看。我知道中国不少站长复制粘帖大法厉害,不过大家手下留情,可以的话自己找个图床,贝壳可以提供所有原始图片。万一相册过载,blog也会跟着挂掉,谢谢谢谢。 这次的内容,对于有些类型的应用很有价值,具体哪些——懂行的自然了解,就不多嘴了。测试的目标,是测试在同样的环境下,不同文件系统对于散碎的写文件的支撑能力。测试方法如下。 首先,贝壳写了一个程序,可以开N个子进程。每个进程打开4个文件,分别写出16, 32, 64, 256字节大小的块。间隔m秒写一次。当磁盘吞吐耗尽的时候,大量的线程会排队在iowait上,因此造成iowait和loadavg快速上升。当loadavg明显超过CPU数时,宣告文件系统压力达到极限。具体测试方法,使用自己设计的压力系统对磁盘造成压力,然后通过压力读取系统读取系统参数,输出到文件。通过一个filter重新组织文件,计算移动平均数等。最后通过gnuplot输出图像。由于具体有些涉及公司业务,贝壳避嫌,就不贴出源码了。draw.plot的代码在最后。 这个业务情况的核心问题是,对同一个文件,在一段时间内会写多次。正常情况下,这些数据会堆积在系统的Dirty区域,直到dirty_ratio的限制到了,或者dirty_expire_centisecs的限制到了,系统才会开始强制写出。否则每隔dirty_writeback_centisecs的时间,系统会写出部分数据。虽然理论上说,一个磁盘的IOPS应当在每秒600-700次上下,但是实际上并不是只能支撑150个并发的。然而设计的好的文件系统,支撑并发数会比设计的差的文件系统明显高。 这个测试环境和实际的另一个差异,在于读写平衡上。这个业务和大部分的日志系统是很类似的(其实我们系统的业务就是日志)。但是商业用日志系统的特点是在高散碎文件写的情况下还有高随机读。这点在测试中并没有涉及,测试是单纯的大量文件追加写,请读者自行注意。 首先是400进程,间隔1秒写出,测试对象是ext3, ext4, ntfs, jfs, xfs, btrfs,基本涵盖常见的linux文件系统。ntfs不属于常见的linux文件系统,本轮只做对比测试。首先可以看到的是ext3糟糕到吐血的表现,磁盘写io只有500上下,400个进程最多有280多个在排队。这货不是坑爹呢么。ext4的结果就正常很多,io在100上下,开始的高开是因为前一个测试的静默时间不足。jfs的结果很搞笑,队列load倒是不高,可是Dirty缓存一路上涨,让人不禁怀疑到底有没有写出。xfs的表现中规中矩,半分钟一次写出,和贝壳机器上的dirty_expire_centisecs相吻合,Dirty也不高。btrfs和jfs的情况类似。 上一轮中,筛掉ntfs和ext3,其余进行1000进程,间隔1秒写出测试。测试对象是,ext4, [jfs](), xfs, btrfs。这次ext4也表现出了坑爹的一面,Dirty最高250M多,load也明显超过了2,写io大约在700上下,就此出局。btrfs这次的Dirty控制还不错,在25-40M徘徊,写出也不多。看似情况略好,实际上暴露出btrfs一个非常大的弱点,突发响应能力差,服务不稳定。一次集中写出,就能让排队数飞速上涨。jfs虽然曲线类似,但是队列可从没有超过1。综合考虑,后期平均load也明显超过了2,一样出局。xfs还是一样中规中矩的写出,非常低的io和Dirty。jfs依然是高速上涨的Dirty和超级低的io。 测试到这里,只剩下了jfs和xfs。jfs的特点是大量使用Dirty,平均io很低。xfs的特点是Dirty使用比较低,io输出比较平均。不过我们的服务器内核对xfs的支持比jfs要好一点,所以使用xfs已成定局,下面就是测试两者的极限性能而已。 第三轮的参数是2000个进程,0.75秒间隔。jfs和xfs表现非常相似,让贝壳差点怀疑自己是测试错了东西。核查之后,确实没有。所以就下狠手,测试了一把高压力的。 第四轮的参数是3200个进程,0.5秒间隔。从绝对量上,大概是基础测试的16倍。在jfs测试开始后的三分钟内,load上升到了60,宣告出局,因此贝壳这里没有jfs的图像。但是xfs还是完美的顶住了压力。Dirty已经上涨到了80-120M,平均io也到了300。然而平均load只有1左右,最高load也只有1.4。 最终测试的参数是4000个进程,0.5秒间隔,基础测试的20倍。xfs的表现万分惊艳,平均io300-400,Dirty100-160M,平均load大约是1,最高也只有2。也就是说,到最后贝壳还是没有测试出xfs的最高压力。 另外,贝壳也通过iozone对两者进行了测试,结论是,xfs在读写性能上比ext3高一些,但是在随机读写上大幅低于ext3。无论哪个数据,都无法出现这种20倍以上差距的现象。因此贝壳又对文件系统选择发生了兴趣,具体写在下一篇blog上。 从最终结论上说,我们确定了xfs比ext3的巨大提升(20倍以上),并准备对xfs进行可用性测试。如果您有什么经验,欢迎和我联系。 -------------draw.plot------------- set terminal png size 1920,1080 set output "out.png" set xdata time set timefmt "%H:%M:%S" set y2tics set origin 0,0 set size 1,1 set multiplot set origin 0,0.5 set size 1,0.5 plot 'out.dat' using 1:2 with lines title 'Buffer', 'out.dat' using 1:3 with lines title 'Cached', 'out.

Aug 8, 2011 - 1 minute read - Comments

从C++的一个特性到设计原则再到哲学

最近在看C++的设计和演化,里面讲到算符重载。关于这个,Effactive C++里面明确说明,不要试图重载&&和||算符。因为这个重载造成的结果和默认不符(Not same with the default)。 &&和||有什么特殊?熟悉C的朋友考虑这么一个问题。if(i && ++i)的作用是什么?基本来说,这个语句是判断i是否为0或者-1的,并且有个额外效果就是对i进行自增。但是,如果i == 0,则不进行自增,这就是&&的短路求值原则。这个原则产生了一系列写法,例如sh中常见的[ -z “\$ABC” ] && { … }。 不过当重载了&&或者||后,就破坏了短路求值原则。因为C系列语言是应用序语言,参数先求值。所以后参数*一定*会被求值,无论前参数的值是多少。 更加悲崔的是,这个破坏了最小惊讶原则,或者叫做知识内隐原则。当你使用一个知识的时候,你会根据自己的经验对这个知识做内隐的预期。例如,虽然螺丝有左螺纹也有右螺纹,然而你在拧螺丝的时候,多数预期是顺时针拧紧。不论其理由,这个已经成为常态。同样,有下压把手的门是扇页门,画着杯子的店家是咖啡店和茶馆,画着裙子的厕所是女厕,这些都是你对知识内隐的预期。破坏这个预期,相当于把螺丝改为反向,下压把手的门改成移门,画着杯子的店家是古董店,男厕画裙子一样,会让人感到不知所措。大家会莫名其妙的绕出去,确认门上画的确实是裙子,走进去再看到男厕,感到世界莫名其妙。 同样的道理,如果一个对象使用了&&重载,程序员唯一能够快速发现的机会就是在调试时单步了&&的语句。如果他运气不好,可能在数个小时内都找不到理由,直到反汇编目标代码为止。 那C++为什么设计算符重载?那是设计给需要的算符用的。其实C++一直是一个矛盾的设计,一方面他认为,程序员是不可信的,所以C++里面有隔离保护系统,例如私有成员函数和变量。另一方面,他又认为程序员应当对自己的行为负责,因此他设计了复杂的算符重载,复杂的继承系统,并期待程序员能够按照正确的方法使用。这是一个奇妙的,矛盾的设计思路,反映设计者自身的冲突(例如多人设计),或者C++设计者的实用主义倾向(选择最实用的设计)。python语言的思路相对统一,他认为程序员应当为自己的行为负责,所以python的隔离系统都是伪系统。而java的思路也相对统一,他认为程序员是不可信的,所以java才会搞出复杂的架构哲学。

Aug 4, 2011 - 1 minute read - Comments

估算(一)

出租车价又涨了,贝壳好奇出租车上面水到底多深,就找几个师傅了解了一下行情,大家看看吧。 首先是油价,目前是7块多,不到8块,按照7.5算。出租车都不太新,每百公里油耗不小,按照8-10算不过分。一般出租,只要在市区跑着,平均速度大约是40公里/小时。司机都是24小时轮班制的,做一休一。平均做一天,大概上缴330-380不等的出租车管理费。以上就是大致的原始数据。 一天24小时,大约要跑960公里。乘上油耗,大约是86.4升的油。折合价格,大概是650上下。这是工作一天的油价。 师傅做一休一,一个月只能做15天。按照税前4500的工资算,一天要赚300才能做平。对于老驾驶员,还做一休一来说,这个价格不算太高。去掉三金和税,还剩下3650。 一天管理费350,一个月师傅这里能缴5250的管理费。但是三金就要缴掉2000,还剩下大概2000是真正的管理费。 我们综合来算,一天的成本是1300。 平均里程费用的问题,其实有点复杂。不考虑夜程,大概可以用3.5算。大概原理是这样的。 3公里以内,14元。就算正好3公里,费用还是4元多。不足3公里平均费用更高。 3-10公里,一公里2.4。最低值平均费用4.6,最高值平均费用3.1,最终得到的平均费用都介于两者之间,里程越长,平均费用越低。 10公里以上,一公里3.6元。总平均费用会从3.1逐步上升到3.5左右的样子。 从区间函数变化可以发现,出租车费用最低的区段大约在9-11公里之间。6公里以内的费用最高,12公里以上的费用就平均了。注意,以上计算都是时间-距离折算计算,即时间延误被乘以系数加到距离上了。实际出租车计价表也是采用的这种算法。 中途插播一句,如果是多人短途,例如三四个人2公里多。或者8-10公里的地理距离,价格在28-35上下,都是比较合算的坐法。出租替代公交的成本不高。 1300的成本,除以3.5的公里费用,得到371公里。加上各种余量考虑,出租车司机一天最高驾驶1000公里,实际400公里有客就可以收回成本,即空载率不应低于40%,否则就亏本了。 我们观察成本,发现一半多的大头多来自油价。难怪每次油价变化出租车师傅都一脸郁闷。 对抗油价变化的方法也很简单,就是等车,减少空乘移动。从上面数据可以看出,每公里载客可以赚入2.8元,一天的除油费成本650。如果每次载客结束都是当场熄火等待乘客,只要232公里就可以收回成本。所以我们经常可以看到机场或者各个地方的司机师傅,排长队等车。而且油价越高,师傅移动拉客的成本越高,越趋向于等车。 一个师傅每个月缴2000的管理费,上海大约是5万到10万辆出租,一辆出租两位师傅轮流开。一个月给各个出租公司上缴的管理费大约是2亿到4亿。 出租公司要负责车辆管理,叫车电话服务,人力资源,还有无线电调度,是有一定开销的。车辆管理的费用浮动,不大好算,然而普通人的车辆,一次养护成本大约是1200,一年一次。我们假定出租公司成本翻倍,一辆一个月200,全上海的车辆维护大约是1000-2000万。叫车电话,调度管理按照1:100的管理比例,需要500人持续管理。按照合三金工资4000(对于无技术的接线员来说,会比需要技术,连班转的出租师傅工资低)计算,大约是200W一个月。无线电调度不是很清楚,应该没有特别高的成本——除了牌照一类的问题外。 满打满算,各家公司的总开销,加上正常盈利,一个月5000万已经足够。那么2-4亿中的其余部分到哪里去了呢?是成为了出租公司盈余,还是成为政府管理拍照费用,这就不得而知了。 以上数据,都是2011年5-7月间,和各个出租师傅聊天时提到的。大部分数据都是经过一位以上师傅的口中说出,有一定准确性。然而由于仅听取了同一利益倾向的所有当事人,所以数据可能有一定误差。