2023-06-06

似曾相识的「歧视」

国泰航空的「歧视」风波,眼下也快要平息了,差不多到了可以说几句的时候了。
我没有看过所谓的现场视频或录音,听说是「偷录」的,不过因为并不是私密场合,所以似乎并不是重点。毕福剑可能有不同看法。
这件事,让我想起上次的宝马冰淇淋事件。上一次的舆论场,有一些不一样。

所以说啊,人是很奇怪的动物。明明脑袋是司令部,但是它又听屁股的指挥。两件事情之所以出现了舆论上的差别,在我看来,主要是还是跟站队有关。
我也觉得去拿免费冰淇淋丢人,所以我不觉得这个事件与我有关系,那么我同情宝马。
我也可能是飞机上的乘客,而且我的某外语也可能不够好,所以我觉得自己完全有可能被迫成为当事人,于是我怒斥国泰。
在我看来,最主要的差别,就是这个。历来如此。比如温州动车追尾……

这种想法也不奇怪,反而很正常,很自然。它出于人类率真的天性,我觉得没有必要去批判。人嘛,重要的能力就是共情。要能共情,首先就要有代入。冷血石头心,但又能够正确处世的,那是AI,不是人。
不过呢,最近这些事情的问题之处就在于:该XX的时候不XX,不该XX的时候死命XX。
我还记得我小学的时候,大约也就三、四年级。一天早上,因为说了脏话,被家长一通教训,心中颇是不痛快。到了学校,上早自习,老师还没来。有人开灯,有人关灯,乱搞一通。于是我跟着其他人一起破口大骂,也不知道骂的谁。场面闹哄哄,压根没人听清我骂了什么,所以没有任何受害者。但总之一舒心中积郁,那畅快无比的感觉,记了三十多年。

要问我的意见?依我看,把这种事情录下来也就罢了,发到别人手机上,试图拉来些网络暴民来达到出气的目的,这种做法本身是很卑劣的行为,我反正是做不出来。在我看来,这种行为与被欺负了的小学生找社会上的大哥「扎起」,然后去对方学校门口等放学逮人一样幼稚。
我要是在现场,要么选择「关我鸟事睡觉去」,要么义正词严地指出问题来,不会有第三种做法。你们要是没有惹到我,那就是关我屁事。背着我咒我死的人多了去了,可能有八千万减一那么多,我管不过来。你们要是惹到我了,我就会明确地让你知道我的不爽,管你下周一来不来我单位找我。也许当场骂两句根本没用,但你还真以为现在这样就有用?

话说回来,现在国泰道歉了开人了,该不会有人天真地以为事态会变好吧?应该不会有人这么蠢吧?
「歧视」就是一种现象,原因是什么?逼我删帖的人心中不会没点逼数。因为心理上没有得到平衡,才会产生歧视。如果不是为了在自己心中觉得高人一等,何必非要去故意踩人一头?本来就是公平的环境被打破后的结局,而如此操作,只会形成更大的不忿。或许始作俑者现在也并不想如此,但自作孽不可活,操弄了天大的风浪,眼下还是祈祷更管用。算了,不多说了,各位自己开心,随意就好。
对了,如果我儿子骂脏话,我把他胖揍一顿,以后说不定能偷录到更精彩的脱口秀。 

2023-05-12

你至少可以选择

首先声明,这不算是一篇正经的Blog。不过因为始作俑者选择了类似「骂并拉黑」的这种看似主张自己的合法权益实则抢占道德制高点的鸡贼做法,所以我也要以彼之道还施彼身。

原始的文章参见这里: https://huangxin.dev/partly-technical/in-response-to-jsdelivr-icp-license-revokement

我其实只评论了一句:

说到「滥用」,更应该谴责的是权力被滥用。痛骂弱者总是相对容易的。如果你不敢连权力一起骂,那起码可以对自己的无能为力表示一下不满和不甘。

我本以为,这已经算是足够温和的批评了。
「更应该」、「相对容易」、「如果」、「一起」、「起码」、「可以」、「表示」……
这么多的委婉,甚至在我看来已经是软化了再软化的用语。
没想到的是,原文作者连这样一句批评,都收不下。

当然,没有几个普通人能够接纳下对自己的批评,起码怒气上冲的当下是很难接受的。
我一直记得dzxr的一句话:「如果他能做到XXX,那么他就不会是YYY了。」年轻的时候,难免做错事情,我也不能免俗。不过他的批评,我虽然很难受,但是我收下了,并且记到现在。

我的意思其实很简单——你不要拉偏架。胖虎揍大雄,就算各打五十大板,那也是在拉偏架。何况你连「各打五十大板」都没做到。轻描淡写一句「我们的系统的的确确有问题」 ,跟标黑加粗的「强烈谴责」,是一个意思吗?
在这里我也不想客气:从这个作者的一句「我们的系统」就可以看得出来,他把自己放在什么位置。
用一句我本来不想说的话来说:他的屁股本来就是歪的。
也许,他真的姓赵?也许,他本来就是既得利益人士?也许,他就是那个给墙壁开发控制台Web前端界面的堕落程序员?所以,他有这样的立场,也许完全不奇怪,甚至很可能是正常的。他站出来维护一句「我们的系统」,实属天经地义,万万没有什么可强烈谴责的。

但是,至少,你还可以选择,不是吗?
你说你没那个胆子,你孬种,你「在意的是个人和家庭的福祉」,「国家」甚至还成了你「赖以生存的一部分」。可是,你只敢忍气吞声的时候,你为什么又选择了「强烈谴责」呢?莫非是因为柿子只敢挑软的捏?
你完全可以说「对不起各位,那YOU KNOW WHO我得罪不起,所以在这篇文章中我只能骂你们」。这样的话,我起码知道你的心是正的。你的确有那个尺,那杆秤。什么是对,什么是不对,什么是错误,什么是罪恶,你心里门儿清,只是不敢说而已。你但凡说了类似这样的任何一句话,我都会欣赏你,默默地为你献上祝福,祝你好人一生平安。
然而,你并没有这样选择。你只是选择了站在强者一边。你选择了当一个骨川强夫,莫非你的嘴也是尖的?

在我看来,原文作者最合适的举动,就是把这篇文章好好编辑一下,去掉那些不合适的文字。老老实实地阐述事实,并提供给别人解决方案,让别人用Google搜过来的时候,能给别人提供一些帮助。很多的Web前端会由衷感激你的,只因为你在分享知识和经验,在做这样的善举。
而站在GFW的边上落井下石,对于Web前端开发人员没有任何好处。你的Chrome是从哪里来的?你用的Android SDK是从哪里来的?你吃饭的筷子都是人家给的,对砸你饭碗的人居然没有一丝怨恨?这样的生物我实在难以理解。不骂你,骂谁?无论是政府、国家还是「老大哥」,我也一个都不敢骂!但我至少不会去为虎作伥。

至少,我会选择——闭(上那张不会说话的)嘴。

2018-10-09

本博客暂停更新的通知

上一次更新到现在已经有10个月了。这话要是提起来也是挺惭愧的,然而:

  • 首先,Blogger平台越来越不适合写作了。不支持Markdown,虽然支持HTML,但要编辑一些版式(例如放源代码)也是相当的吃力。偏偏我近期能够往上放的内容更多地是一些技术性的文章。相比之下,在DropboxPaper上写作的效率要高很多。
  • 其次,国内的自由状况愈发不堪。虽然blogger并不在墙内,但仍然是公开的“场合”。我觉得可能快到了转入地下的临界点了。与其被动地被逼,不如主动地早做准备。
  • 最后,我最近的确也是缺少灵感,所以即使是生活类的Blog也写不出什么来。没有时间当然是一个理由,但要挤也是能挤出来的,主要还是自己写不出来,不能怪别人。

所以,在这里发这个通知,也告诉大家不用干等了——虽然其实没有什么人在等。也提示了以下几点:

  1. 我会转移到暗网。所谓暗网,不是一定指Tor或I2P,反正是普通人找不到的就对了。
  2. 我会在暗网开两个Blog,一个仍然会是我的Blog,另一个别指望能把它跟我联系起来。
  3. “暂停更新”,意味着原有内容仍然保留。将来是“彻底关闭”,还是恢复更新,交给上帝去安排吧。

2018-01-17

2018年,发现自己老了

公司最近在赶项目,周六跟晚上都在加班。一加班,跟年轻时候的差别就出来了。到了晚上脑子都转不太动了,提不起精神,需要的睡眠时间也挺长。所幸是还睡得着,要是失眠就更惨了。年轻的时候那种越到夜深干劲越足的情况是不可能再有了,就算是玩游戏也不可能有了。

说到玩游戏,忽然想起自己已经很久没有玩过了。年幼时央求父母买游戏卡带时说的那句「采蘑菇我可以玩到老」虽然是bullshit,但是像现在这样PC、游戏机、手机游戏统统没法玩的时候,在我成年以后还是罕有。用Raspberry搭建了一台FC/MD/SFC怀旧游戏机,然而却没有时间玩,我也真是醉了。

手机换了一台iPhone8+,不知怎么,却也懒得再去下载游戏来玩。之前在iPhoneSE上玩过的一些游戏,最后都因为觉得「太耗时间了」,「逼我每天都要抽空玩真是烦心」,而最终被卸载。以至于我现在也不想再去玩那些手机游戏了。

说起来,手机上的游戏似乎特别消耗时间。它千方百计地要让你每天都去玩一下,哪怕只是签个到,也要让你点开看一眼。我实在是不喜欢这种「被东西控制」的感觉。不过也是奇怪,年轻的时候似乎并不是这样觉得。也许那个时候我的「空闲时间」很多吧。

一转眼,已经是2018年了。在过去的一年里,拜年中那一段时间的爆发力所赐,总算是在Blog数量上创出了过去三年以来的新高。否则我都快觉得无颜面对竜堂家兄弟了。Chinese New Year 期间大家一起加油吧。

2017-12-27

Linux关机权限的特殊情况

很多Linux教程都说shutdown/reboot需要root权限。其实这不是完全正确的。

正常想来没错:shutdown/reboot如果可以不用root权限那还了得?然而其实至少在RHEL 7.2上并不绝对是这样子。当出现以下的特殊情况时:
1.是当前唯一登录的用户;
2.直接调用reboot,或shutdown带了now参数;
3.登录会话来自本地物理终端。
同时满足以上条件的话,就可以无需root权限以任何用户的身份关机或重启服务器。

我用RHEL 7.2默认安装的「基础设施服务器」进行的测试。Debian 9没有这个问题。我想这样的做法大概思路是:「如果你都摸到物理服务器边上,急着要马上关机,并且我认为这不会影响到其他人,那么当然可以让你关机,因为就算不让你关机你也可以拔电源线对吧?」

当然,这种想法应该没有考虑到服务器上运行爬虫之类的情况。我没有做更多测试,也许如果有一个别人的daemon进程就会使得结果不一样。不过我想这个事情可以提醒我们的是:Linux的事情不要想当然,也不要网上说什么都信。不要把一切都交给系统默认安全性设置,对于普通用户还是乖乖地把权限控制严格点比较好。

2017-06-22

防贼不编年史

Chapter One
很早的时候,赛博世界还只有病毒,没有贼。
那时候,有的病毒还可以和人类和睦相处,称之为“良性病毒”。
我有一个游戏,从别人那边复制过来的时候,就是带毒的。文件型病毒,文件体被加了密,还给搬到了隐藏扇区。不过游戏本身挺有意思,The Incridible Machine,第一代。于是我每次就把BIOS里的硬盘给Disable掉,然后再玩。慢虽然慢点,但只要记得玩过之后重启,就不会有什么问题。

Chapter Two
尽管兜里没什么钱,但Internet时代还是到来了。
网管差点把我从网吧赶了出去。因为他终于“逮到”我在用SuperRabbit。他已经连续好几天都把时间花在恢复系统设置上了。我想日后硬盘还原卡卖得这么好,其中应该有我一份功劳。
“机器狗”真不是我放的。

Chapter Three
CIH爆发了。
买了刷ROM机器的人都发了笔小财。
其他人:哇,没想到病毒也可以这么凶残!
我倒是没什么感觉,因为我那个时候还在用着一块80486。

Chapter Four
IDT-C6的发热好低,主频超到100MHz也不用风扇。
哇,有好多同学都安装了冰河哎!
咦,这位同学在玩美少女梦工场3呢。我只有2。
“同学你好,你的游戏可以也copy给我一份吗?”
“哎哎,不要关机!……”

Chapter Five
不知道从什么时候开始……
几乎所有的IT公司,都以在你的IE上装一个插件或工具栏为荣。
几乎所有的安装包,都会附带一两种“小东东”。
刚开始我还真没太放在心上,甚至对某些还持欢迎态度。然后,我的机器越来越慢了。
做毕业设计时,我接触到了ActiveX。

Chapter Six
工作了。从K6-2一下子跳到Pentium 4的感觉真好。
“见鬼,这浏览器上什么时候多了这么些鬼东西?上网助手?中文实名?卸掉!就是它搞得我们的OCX不能用了。”
“你要记得安装Windows 2000 SP4补丁,不然我们的程序用不了。”
对了,有个新软件叫VMware,真好玩!

Chapter Seven
我开始小心翼翼地上网浏览,对于弹出的OCX安装提示统统点“否”,后面视情况而定。因为我知道一旦安装了之后别人能做些什么事情。然而,有些人我是注定帮不了他们:
“你的IE上装这么多工具栏干什么?”——“不然我怎么上网?”
Google的网址是三达不溜点……”——“别说了我记不住。”
愿上帝保佑他们,A门。

Chapter Eight
换工作了,当小头头了,总算有双核电脑用了。VMware可以有自己单独的CPU了。
真不敢相信,以前在一台768MB的P4笔记本上跑了一个Oracle8i+两个Lotus Domino R5+一个Resin+Word+若干IE,去招标现场做演示的时候,机器到底是怎么撑下来的。
借着新工作接触到了IceSword。妖魔鬼怪你们都现出原形罢!
测试人员:不好了,机房又爆发“震荡波”了。

Chapter Nine
我开始仔仔细细地打补丁,开启Windows Update,总是保持自动更新。
而很多同事都是直接关掉了事:“工作到一半老是跳出来叫我更新,太烦!”
愿上帝保佑他们,A门。

Chapter Ten
我发现同事们总算愿意给机器打补丁了。
同事:这个东西叫360,打补丁蛮快的。
我:我也来试试。咦,这个KB360018怎么这么奇怪?

Chapter Eleven
不知道从什么时候开始,软件安装开始必须得小心了。
因为一不小心你就会安装上好几个不请自来的软件,电脑上会变成软件博物馆。送来给我“修一下”的电脑无一不是如此。连我自己有时候不小心也会中招。
有人建议我把家里电脑换成Linux,不过我觉得对父母吩咐到位了,一般还是没事。毕竟我有TeamViewer

Chapter Twelve
不知道从什么时候开始,国产软件慢慢地不能用了。
其实不是不能用,是不敢用了。因为开始流行一种东西叫做“全家桶”。腾讯、百度、迅雷、阿里、360、金山……。所有的这些曾经为我服务过的软件,仿佛都得了癌症。你不知道他们在背后干些什么,但是你的电脑的确越来越慢,行为越来越不正常了,而且你的hosts总是失效得很快。于是干脆就不用了。
不用了,然后也并没有什么事情发生。并没有像有的人以为的那样会社会大乱,民不聊生。人民照样活得很好。

Chapter Thirteen
一夜之间,我的密码就不再是“我”的密码了。
许多年前,我自己写的同学录,为了避免被SQL injection,就把服务端存储的密码改成了MD5 Hash。
后来,知道了世界上有种东西叫做“彩虹表”,于是我学会了salt
再后来,我看到了王小云教授的论文,于是我Hash算法至少会是SHA256。
然而,这么多年过去了,这帮狗日的居然还在服务器上存明文密码。谁要硬说这里面没有阴谋,我只能说你的心挺大。

Chapter Fourteen
没想到,我的QQ也被盗了!
我已经很多年没用过QQ了。但是因为我太太的手机上有游戏用我的QQ账号登录着,所以我觉得企鹅还不敢回收我的账号。
突然间它就变了一个名字,列表里的好友也变成了一堆海南人。我还能再登进去,密码并没有被改。所以我一直到现在也没想通是怎么回事。
我把个人状态改成了“明文密码好”,然后就把这个QQ号扔那里了,就像它从未存在过。

Chapter Fifteen
那个周末,当我还在外地顶着紫外线用流量上网的时候,全世界有许多人已经了。
贼要的是Bitcoin
当第二天IT问我笔记本装没装补丁的时候,我微笑着告诉他“Linux”。
不过我马上又想起来Heartbleed的事情我还没处理,于是我又有点笑不出来了。
我也想要别人的Bitcoin。

2017-06-13

银联钱包你真垃圾,我一点都不欢迎你

5月30日一下飞机,我就在虹桥T2的廊桥里面看到了银联云闪付62折的大幅营销海报。“去看看有没有便宜可占”,当时我这样对太太说。然后我们就各忙各的,这事几乎给忘了。

昨天太太跟我说,超市里面银联云闪付满79减30,所以她在自己的iPhone6+上装了个银联钱包。我想起了在机场看到的东西,就也去AppStore上搜了一下。有两个东西,一个叫“银联钱包”,一个叫“云闪付”,都是“中国银联”出品的,评分还真是一样低。我有点纳闷,好吧两个都下了,反正AppStore上至少没木马。

安装好之后把玩了一会儿,“云闪付”一来就叫我登录,而“银联钱包”至少让我看到里面有些什么功能了,里面也有“云闪付”的功能,那么好,“云闪付”你滚蛋吧。

其实我知道Apple Pay本来就是所谓的“银联云闪付”,我只是想知道银联这次在玩什么花样。结合新闻我有点弄明白了:大概闪付需要芯片,很多地方只肯买扫描枪,所以银联这次也搞了个跟支付宝有点像的扫二维码支付。这就必须要App支持,光靠Apple Pay还不行。

好吧,我觉得至少比起阿里粑粑这种流氓公司而言,银联我还可以尝试一下。于是我准备注册了……

我真的没想把本文写成吐槽文。不过正式开始用的第一眼我就被雷到了。拜托!中国银联!这是iOS,是哪个老师教你“自己开发密码键盘会更安全”的?你说出来我们来轮他。

先得注册。我在界面上看到了可以用“手机号”、“邮箱”或“用户名”来注册。我并不是一个暴露狂,所以我准备以用户名来注册。点开App上的注册,发现只能用手机号注册。我不死心,换到PC上在Web下注册。一开始Web页面看起来也只能用手机号注册,不过当我F12之后,就发现还有一个DIV被display:none了。
呵呵,我心想:“就这也能难住老子?”
看来还是绕不开。

然后还有这个令我一看到就恶心得头皮发麻的“请点此安装”。
我用的是Chrome,要我换用Edge甚至是IE我都可以接受。不过要我安装OCX那就太过分了,。有的Web页面如果用手机浏览器打开,就不会提示安装控件了。我抱着姑且试一试的态度,用手机试了一下:
Chrome是这样,Safari也是这样。
好吧,反正就是必须得要手机号对吧。那我还是回手机App上去注册吧。

在App上输入手机号码,通过短信发了验证码给我,验证通过了,接下来让我输入密码。这明显的大爷作风嘛。我很想问银联你是不是并不在乎有没有用户来注册?老子是国企多一个少一个无所谓?你们知道像美团之类的App在这一步是怎么做的吗?
我又要吐槽了。最低6位虽然太少,但我可以理解。最多不能超过16位是个什么意思?你们如果后台数据库里面保存的真的是密码的Hash值而不是原文,你管我密码最大有多长?你们知道Twitter允许的密码最大有多长吗?你们可以自己去试一下。
明文密码!我一直不厌其烦地在Twitter和Google+上强调这个事情:只要没有特别的理由就限制密码的最大长度,那后台保存明文密码的可能性就一下子变得高了起来。不要跟我讲什么16位现在还足够安全。关键是撞库!撞库!撞库!
我一直是坚持“为每个服务使用独立随机密码”这个原则的。我宁愿忘掉密码,宁愿冒本地密码本被人搞走的风险,我也不会把心放在Server管理人员身上。原因很简单:做过这行你就知道了。
所以,我开启了密码生成器,去掉“符号”的勾,选择了长度为“16”,然后得到了一串随机密码。知道我前面为什么吐槽自己做的密码键盘吗?你既然决定了自己做密码输入控件,就很可能不会支持复制粘贴。
在我比较辛苦地输入完密码之后,出来一个这个。
估计我以前在什么时候注册过银联的账号吧。有句妈卖批我不知当讲不当讲?!我输入手机号码的时候你不告诉我,我输入验证码的时候你不告诉我,我输入密码的时候你不告诉我,等我把这些都搞完了你就告诉我这个?!
抱着一丝希望,我点下了“是我的,立即登录”按钮,App跳回到了最开始的登录界面,输入我刚才生成的随机密码(是的我又辛苦了一遍),说我密码错。这次我真的骂人了。
好吧,看来我只能选择“忘记密码”了。
在又通过短信验证了一遍手机号之后,给我看的是这个界面。
我曾经在Blog中讲过,“密保问题”并不是一个好的设计。不幸的是,银联这里选的是所有密保问题中最糟糕的那几种之一。如果真的用家人生日做密保问题的答案,安全性极其脆弱,有等于无。如果用别的答案,又极容易忘记。
偏偏这里不回答还不行,又没有提供“忘记答案”的选项,实际上是把这条路给堵死了。然而手机短信验证的安全级别明显比密保问题要高。取信低安全等级的验证结果而忽视高安全等级的验证结果,最后只能请求人工服务,这是极差的用户体验,也是极蠢的产品设计。

如果我记不起这个以前注册的账号的密码,我可能就只能打电话给银联了,而且可能这帮官腔佬最后还不肯替我解决。不过很幸运,我用一个旧密码最后成功登录了进去——看来我注册的时代还不太“古老”。
然后我又被雷到了。登录成功之后,App给我看了这个:
是的,没有“跳过”或者“稍后设置”的选择,这一步是必须的。
设置手势密码之后才可以设置TouchID。好在根据太太的经验,登录进去了之后是可以把手势密码功能给关掉。不过问题又来了,要进入“安全设置”你必须要:
到这一步,我彻底放弃了。
极其差劲的技术运用,极其糟糕的用户体验。难怪AppStore上绝大多数评价都只给了一星,而近期的五星好评全像是刷出来的。我估计如果AppStore不是规定最低是一星,很多人连这一颗星都不想给。
说实话,我不相信这种程度的技术能够保障我的资金和信息安全,给我天天打62折我也不敢用。算了。卸载。再见!


2017-05-31

淘宝天猫都碰不得啊

前言
六一儿童节快到了,给儿子买点什么礼物好呢?虽然前不久刚买了一架UH-60和一把Glock17,但我还是想买点对儿童稍微有点教育意义的东西。思来想去,觉得地球仪不错。正好暑假也准备带家人出国去转转。若是连自己去了哪里却一点概念都没有,那岂不是很遗憾?

平时工作也算得上忙,所以我就偷懒打算在网上购物。碰巧近来网购的体验还不错,正所谓好了伤疤忘了痛,我又开始在淘宝上逛了。

其实以前我是很吃过几次亏的,所以也曾经痛下决心告诉自己大部分东西都不能在淘宝上买了。但前不久那次买玩具的感受实在是不错:我擦!居然有金属的Dragunov?这次一翻地球仪,我更是震惊了:我擦!居然还有磁悬浮的?!

所以说啊,人必须时刻保持冷静,才能抵挡诱惑。头脑发热之下,我真的就下单买了个所谓的“磁悬浮地球仪”。带着残存的一丝丝理智,我选了一家天猫店下单。我觉得吧,C2C的淘宝不靠谱,B2C的天猫大概好一点,至少出了问题比较好解决。事后证明,我这想法也对也不对。

糟糕
等待收货的过程还是蛮引人遐想的。然而收到货一拆包装,首先心里凉了一半:包装倒没有什么特别的问题,不过产品外包装上连半个汉字都没见到,没有品名,没有厂家名称,没有商标,连个LOGO都没有。好在我是懂英文,加上有个图片,还能看出来没发错货。
打开盒子,里面除了地球仪和一些填充物,就只有一张非常简单的“说明书”。合格证、保修卡,什么都没有。这它妈的不就是传说中的“三无产品”吗?
好吧,网购的东西,要求别那么高,毕竟地球仪才是主要的。我对它有着不小的期待,因此心里倒也没怎么在意那些“细枝末节”的事情。看了看说明书,通上电源,开始折腾。折腾着折腾着,汗就下来了。
要完成所谓的“悬浮”,好困难啊!

虽然买之前看过一些评论,算是心里有所准备,但还是没想到这么麻烦。送的那个什么“悬浮棒”根本就不好使。还是有个评论里面说用中性笔的办法比较管用。好不容易能够比较顺利地“悬浮”上了,然而只要有一点点扰动,平衡立马就被打破,通常的结局就是地球仪被“铛”的一声吸到顶上。而且就算是很小心地退开,一般也坚持不了几分钟。我发现这大概跟加工精度有关系,因为顶上的磁体是斜的,而我无法去校正。
并且,产品说明里面提到的自动旋转,似乎也无法达到。球体也就是左右来回转,每次角度也就是几十度。我定睛看着它,发现角度在越来越大,正当我满心希望它最终能转一个整圈的时候。“铛”,它又被吸到顶上去了。

这它妈让人怎么用?我不可能每天都花一两个小时的时间在折腾这东西上。睡觉时还不能开着,不然保管神经衰弱。要是只能摆着或吸到顶上,那几十块的普通地球仪岂不是更好?我干嘛买个这么贵的银样蜡枪头?
不行,退货!

退货
在淘宝上买东西,顺利的话一切都好。然而一旦买到糟糕的玩意儿需要退货,那麻烦就来了。我以前的糟糕的购物经历无一不源自于此,这次当然也不例外。当我以“质量问题”为原因要求退货时,卖家拒绝了。我对此也并不意外——反正最糟糕也就是哪样,总不可能直接投降吧。

卖家拒绝的理由看起来很好笑——产品有正规工厂专利进货发票。这话好眼熟啊!对了,我以前在某个论坛上看卖家们交流心得时提到过,如果被投诉三无产品,就这样应对,只要你拿得出发票来,淘宝小二可不管它是不是真的……。呵呵,这样的发票当然可以买。有些买的发票连税务局那边都能过,何况淘宝。淘宝的处理方式很简单,C说你卖的是假货,你B有发票吗?噢,有,那C你去证明B卖的是假货……
我去你妈的。

这个时候我看到了一个“极速维权”的按钮。我点了一下,叫我提交证明。
我能怎么证明呢?我只能把上面那两张图片传了上去。产品不能正常使用,我能怎么证明?上传一段小电影吗?搞笑。我都能想得到接下来的过程,无非就是叫C去找质监局,出具鉴定证明。普通消费者常常到了这一环节就望而却步了。较真的可能会去工商局投诉,然而一般也是了无下文。

要说起来,这个环节是很给“天猫”加分的地方。我刚上传了照片不久,天猫说因为我是“信誉良好”的顾客,所以给我先行赔付了。的确也是马上就是进入到退货发物流的环节了。听明白了吧——东西真不真我不表态,但是我相信你!
很多时候,事情就这么摆平了。你要认真按“假一罚N”地去索赔,那可就没这么容易了。职业打假人毕竟是少数。这一招就叫做“分化瓦解”、“团结大多数,孤立一小撮”。

给东西重新装箱的时候,我又留意了一下这东西的做工,才发现其实粗糙得很,根本不值169元这个价钱。所谓专利号,搜了一下是宁波一家公司的,跟淘宝商家八竿子打不着。如果光看成本,20元都不一定有。尽管到淘宝上买东西没一个不是想贪便宜,但你一定要相信,卖家不会让你真正占到便宜的。

运费
我记得,我上次在Blog上吐槽淘宝的事情,最后问题也是出在退货的运费上。这次又是“也不例外”。可见,如果那里的确有一个坑,你再走几次也还是会掉进去的。

天猫很“贴心”地提供了“上门取件”服务,还可以约时间。说实话,当时我真的有点小“感动”,几乎就要拍手叫好了。

取件的人来的时候,我在上班,是我太太处理的。取完件我立马就收到了退款。然而收快递的人跟我太太说,运费本来是7元,但是要收11元,因为“你的东西超宽了”。
好吧。我心想,反正质量问题的退货运费是应该由卖家承担的。所以我也就没有坚持太多。收快递的人(我不想用“快递员”一词称呼他,因为我对他有意见,我觉得他不配)叫我支付宝直接付掉,我打开手机的淘宝App,的确有付款按钮。我点开看,7元。

怎么回事?也许是对方还没提交新的价格。我就又做了一些手头的工作。一个小时以后再去看,还是7元。
7元就7元,我心想,也许系统不觉得我的东西“超宽”。付完款没多久,太太说快递员打电话来,叫补4元运费,给了支付宝地址。
妈的,现在想起来补运费了?

结束
问个问题:太监下面有什么?
太监下面没有了!
居然什么都没有了?

质量问题导致的退货,运费不是由卖家承担吗?如何承担?要我“垫付”已经是足够糟糕的体验了,然而现在是要我去找卖家聊IM来“讨”吗?
我最憎恨的就是这种“干点什么都要IM”的事情。而前几次还算“愉快”的购物体验,也正因为我“不用到IM上做任何事情”。

好吧,既然天猫觉得这个事情“到此为止”了,那我对你淘宝/天猫也就“到此为止”吧!
其实总结下来,写了这么多,无非是想让自己记清楚这些个教训。有钱留着去国外花,别它妈犯贱去交智商税。

2017-05-25

将C++11新特性用于代码优化

关于C++11的科普,在这里就不详细进行了,可以参考维基百科页面。即使是中文页面,我认为写得足够详细和系统了。

总之,C++11对原始的C/C++作出了在我看来是不算小的改动。有一些概念,放在以前的时代是绝对真理,在C++11推出之后,可能需要重新了解一下了。VS2013对C++11的支持并不算“完美”,不过大部分“有用”的特性还是到位了。这里就以它为例,来谈谈如何把C++11的新特性应用到你的软件开发工作中来提升性能和开发效率。

本文提到的C++11的这些新特性,我大致把它们分为两类:一类是可以直接提升代码的性能表现的,我列在“性能优化”部分;另一类虽然不能直接提升代码的性能,但可以提升开发效率,便于更快地开发出可维护性更好的代码,我列在“非性能优化部分”。

另外,受作者水平所限,本文并不是对C++11在这些方面的完整的参考内容,仅仅作为一个引导来阅读吧。


性能优化部分

右值引用和move语义
C++11引入了右值引用,支持了move语义。在我看来,这个变化的意义可能是C++11里面最大的一个。右值引用和move语义是什么,这里不展开。通俗一点地讲,这个特性使得程序员可以在必要的时候自行决定到底是深拷贝还是浅拷贝。对于大量的数据“搬运”操作,可以节省下不少时间。对于性能优化来说,意义重大。

其实就算没有右值引用,在C++11之前的时代也可以做类似的优化。C++程序员只要对于自己的资源管理类显式地提供深/浅拷贝版本的函数即可。不过这样一来代码工作量会比较大,程序会变得比较复杂,并且始终不是一个规范。现在这一切都不是问题了。

对于STL自己的类/容器,VS2013已经做了足够的优化。例如,你可以通过:
string strA = std::move(strB);
来把strB的字符串动态内存部分直接给到strA,速度比简单的赋值要快不少。当然,strB就不再具有有意义的值了(这里例子中会变成空字符串)。当你push_back或insert一个string到容器里面的时候,如果string其实是一个临时变量,那么用move语义你也可以得到相当明显的性能提升。

如果例子里面string换成一个map<string, string>,那么提升会更明显。总之,内存的分配和释放,以及memcpy操作统统被避免了。所以,理论上需要传递的东西越多,你得到的性能提升就会越显著。

就地部署(emplace)
C++11对于常见的STL容器,都提供了一种能提升性能的数据置入方法,称之为“就地部署”。通过用就地部署取代原来的push_back或insert之类的操作,不再需要先构造再传递,而是由容器直接调用目标对象的构造函数来完成数据填充。

在某些情况下(T提供了对应的构造函数时),这样可以避免一次拷贝构造的开销。而最差的情况(T没有提供对应的构造函数),也最多不过就是与push_back和insert效果一模一样而已。所以我建议所有能用上就地部署的地方,都统统用上,无需太多考虑。

并且,就地部署与move语义相互并不冲突,而且是互有补充。move语义解决深拷贝慢的问题,就地部署试图减少哪怕是浅拷贝的执行次数。两者配合起来效果更加完美。

散列表
在C++11里,不再需要通过第三方库来引入散列表(或者叫哈希表)了。STL正式支持了四种散列表的实现,全部都冠以“unordered_”的前缀,以便与一些第三方实现相区别。

对于大多数用map/set实现的代码,只要简单替换容器就可以得到性能上的提升。map/set基于红黑树(自平衡二叉树),时间复杂度至少是log(N)。散列表版本的map/set提供常数级的时间复杂度,随着数据量的增大,无论是写入还是读取的性能都超过了红黑树版本的map/set。

我个人的测试结论是:同是set<string>,即使是小数据量,散列表版读取代价也只是红黑树版的约60%;小数据量下,红黑树版写入略快,但在容器内数据量达到“万”级别的时候,散列表的写入速度也开始超越红黑树版(Release版测试结论,Debug版在“百”级别即发生超越现象)。

所以我认为,只有在数据量很小,并且写入与读取的概率大致相当时,使用红黑树版map/set才在性能上可能有明显收益。其余情况,都建议采用散列表版本map/set。当然,如果T是自定义类,并且你不愿意为它写散列函数,那就算了。


非性能优化部分

完美转发
C++11中所谓“完美转发”的特性,其实是配合右值引用来使用的。如果为了支持右值引用,而不得不让自己的代码量变大一倍,那有些人可能就要望而却步了。完美转发其实是借用了模板技术,使得你可以只写一份代码,就可以兼顾(常量)左值引用与右值引用的情况。工作量更少,代码更简洁,出错的概率也就更低。

不过,采用模板技术的缺点就是:编译期展开。这一方面降低了编译器的效率,另一方面会导致头文件的包含关系变得不太容易整理。除此之外,还有一种我称之为“不完美转发”的替代解决方案,本质上是在性能上作出一定程度上还算可以接受牺牲,来换取代码简洁性,取得一个还算OK的平衡。我会另外写一篇Blog来介绍一下它。

类型推导
“类型推导”也就是所谓的auto类型。这个东西使用起来基本没有门槛。很多人可能最开始接触C++11就是通过它了。

这个的确是一个好东西,用来写STL的iterator类型再合适不过了。因为我们本来也不怎么关心iterator的具体类型。不过,仍然不建议滥用。如果到处都是auto,阅读你代码的人会经常性地需要回顾才能知道一个变量的类型,特别是在你没有用匈牙利命名法的时候更是如此。

所以,我的建议是:当你觉得一个变量的类型写起来很麻烦,而你其实并不关心它的时候,放心地用auto。并且,auto变量的作用域不要太大,if/for/while循环内的局部变量用它是最合适的。

基于范围的for循环
很多语言早就可以这样写了。而C++11现在也可以这样写了:
for (auto& stk : stocklist)
相比起:
for (auto pIter = stocklist.begin(); pIter != stocklist.end(); ++pIter)
孰优孰劣一目了然。何况后者通常还需要跟一句:
auto stk = (*pIter);
不过,如果是一个map,你可能经常要取pIter->first/second之类。或者你打算在循环里面对pIter做erase操作,那还是用传统方式比较好。

空指针
用nullptr取代NULL。我觉得最大的好处就是nullptr的颜色没有NULL扎眼。不过,由于NULL也表示0,有的时候也表示无效句柄。我觉得对于所有指针类型的NULL,置换成nullptr可能会对阅读代码有一定帮助。

角括号
C++11的编译器现在可以识别>>到底是两个模板类的嵌套,还是>>运算符。因此写代码的时候就不特意空上一格,写多层模板类嵌套的时候就更美观一点。

不过,多层模板类嵌套,本来就不可能“美观”到哪里去。起码我是不建议太多此类的代码实践的。

初始化列表
vector可用这样的方式来进行初始化:
vector<int> vecX = { 1, 2, 3, 4 };
的确是比以前省事了。也就是说,C-Style数组的存在意义又少了一层。

统一初始化
struct可以被这样初始化:
struct C
{
    int a;
    int b;
    int c;
};
C c{1, 2, 3};
class的public成员也可以。
在某些喜欢使用各种结构体的代码中,这个特性可以让你少写一大堆构造函数。

通用智能指针
std::shared_ptr<T>,强在可以指向任意对象,缺点也由此而生:由于引用计数保存在shared_ptr中,因此对智能指针的赋值操作是线程不安全的。这个问题,有一篇Blog论述,我觉得写得不错,就直接引用不细讲了。从原理和测试数据来看,我认为这篇Blog是靠谱的。

所以,虽然shared_ptr很强大,但使用场合需要注意:单线程随便用。多线程下,赋值过程要注意。单对单没啥问题,最好不要出现左值右值交叉的情况(一个线程在A=B,另一个线程在B=C)。若因业务需求无法避免的话,要考虑当作临界资源加锁保护。实在不行,就写一个专用智能指针,把引用计数放在T里面,就不会有问题了。

正则表达式
与散列表类似,不再需要第三方实现,现在C++11也直接支持正则表达式了。我以前要找一个Unicode支持得好的Regex库真的是苦水一堆,现在有了官方支持真的是太好了。

2017-05-23

招行网银在Win10下糟糕的支付体验

我这人不用QQ,不用微信,微博借王维林也成功销号。然而,支付宝因为早年上淘宝购过物,搞过那个什么实名认证,我评估后认为不用比用下去可能更不安全,所以账号勉强留了下来。不过我也给自己定下了两条规矩:

  1. 不绑定银行卡的快捷支付。
  2. 不在里面保留超过200元人民币的余额(含余额宝)。

这两条规矩,使得我的支付宝平时基本上当作零钱包来使用,正式的支付只用在PC+网银上。这样,即使失窃,损失也很有限。再说,花钱方便是方便什么?方便你「败家」而已嘛。

因为我自己定的这些规矩违反某些方面的利益,所以经常给我形成一些耐性上的挑战。昨天我就又遇到了一次,来自招行网银+Win10。
没有足够的余额,又不开快捷支付的话,在支付宝上支付一笔淘宝订单就只能通过网银了。我以前一直用招行网银,虽然它对Chrome和x64很不友好,但我还是耐着性子开x86 IE来在这种j「特殊场合」将就一下。反正也就是最后一步嘛,登录Alipay集中支付一下就好。但昨天在Win10机器上我又发现了新的问题。

Edge不支持
Edge登录支付宝是挺顺利的,但招行网银的页面一打开,直接说这是「使用陈旧技术的页面」,估计是因为ActiveX。要想跨Browser提交表单估计还是做不到的,所以最后还是只有在Win10下打开Internet Explorer。

无管理员权限登录会失败
IE下几经折腾,可以打开招行的网银专业版了。然而插入UKey之后一登录就跳出Dialog让我输Key的密码。在确认不是钓鱼软件的情况下,连输4次后,专业版登录界面弹出提示说证书签名有问题云云。
我估计这问题就是因为权限不到位,果然给了管理员权限后就能正常登录了。然而专业版登录界面是从IE页面上Call出来的,这就意味着我得给IE管理员权限才行。这样的话风险就有点高,还好可以手动做单次授权。

以前我一直觉得,金融行业在IT技术应用上普遍保守,而在国内放眼看来,招行在技术方面还算是相对进取的。现在看来情况已经反转了。x64都普及多久了?IE份额离开绝对优势地位都多久了?Win10正式版都上市多久了?到现在还在用着ActiveX。招行里面搞技术的人这些年都不知道在干啥。曾经引以为傲的服务水平也许还没下滑,但也绝对不算突出了。我是不是该换一家主力银行了?