Browsed by
作者:陈皓

芝兰生于深谷,不以无人而不芳 君子修身养德,不以穷困而改志
C语言的整型溢出问题

C语言的整型溢出问题

整型溢出有点老生常谈了,bla, bla, bla… 但似乎没有引起多少人的重视。整型溢出会有可能导致缓冲区溢出,缓冲区溢出会导致各种黑客攻击,比如最近OpenSSL的heartbleed事件,就是一个buffer overread的事件。在这里写下这篇文章,希望大家都了解一下整型溢出,编译器的行为,以及如何防范,以写出更安全的代码。

什么是整型溢出

C语言的整型问题相信大家并不陌生了。对于整型溢出,分为无符号整型溢出和有符号整型溢出。

对于unsigned整型溢出,C的规范是有定义的——“溢出后的数会以2^(8*sizeof(type))作模运算”,也就是说,如果一个unsigned char(1字符,8bits)溢出了,会把溢出的值与256求模。例如:

unsigned char x = 0xff;
printf("%d\n", ++x);

上面的代码会输出:0 (因为0xff + 1是256,与2^8求模后就是0)

对于signed整型的溢出,C的规范定义是“undefined behavior”,也就是说,编译器爱怎么实现就怎么实现。对于大多数编译器来说,算得啥就是啥。比如:

signed char x =0x7f; //注:0xff就是-1了,因为最高位是1也就是负数了
printf("%d\n", ++x);

上面的代码会输出:-128,因为0x7f + 0x01得到0x80,也就是二进制的1000 0000,符号位为1,负数,后面为全0,就是负的最小数,即-128。

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (32 人打了分,平均分: 4.91 )
Loading...
从Code Review 谈如何做技术

从Code Review 谈如何做技术

(这篇文章缘由我的微博,我想多说一些,有些杂乱,想到哪写到哪)

这两天,在微博上表达了一下Code Review的重要性。因为翻看了阿里内部的Review Board上的记录,从上面发现Code Review做得好的是一些比较偏技术的团队,而偏业务的技术团队基本上没有看到Code Review的记录。当然,这并不能说没有记录他们就没有做Code Review,于是,我就问了一下以前在业务团队做过的同事有没有Code Review,他告诉我不但没有Code Review,而且他认为Code Review没用,因为:

1)工期压得太紧,时间连coding都不够,以上线为目的,

2)需求老变,代码的生命周期太短。所以,写好的代码没有任何意义,烂就烂吧,反正与绩效无关。

我心里非常不认同这样的观点,我觉得我是程序员,我是工程师,就像医生一样,不是把病人医好就好了,还要对病人的长期健康负责。对于常见病,要很快地医好病人很简单,下猛药,大量使用抗生素,好得飞快。但大家都知道,这明显是“饮鸩止渴”、“竭泽而渔”的做法。医生需要有责任心和医德,我也觉得程序员工程师也要有相应的责任心和相应的修养。东西交给我我必需要负责,我觉得这种负责和修养不是”做出来“就了事了,而是要到“做漂亮”这个级别,这就是“山寨”和“工业”的差别。而只以“做出来”为目的标准,我只能以为,这样的做法只不过是“按部就班”的堆砌代码罢了,和劳动密集型的“装配生产线”和“砌砖头”没有什么差别,在这种环境里呆着还不如离开。

老实说,因为去年我在业务团队的时候,我的团队也没有做Code Review,原因是多样的。其中一个重要原因是,我刚来阿里,所以,需要做的是在适应阿里的文化,任何公司都有自己的风格和特点,任何公司的做法都有他的理由和成因,对于我这样的一个初来者,首要的是要适应和观察,不要对团队做太多的改动,跟从、理解和信任是融入的关键。(注:在建北京团队和不要专职的测试人员上我都受到了一些阻力),所以跟着团队走没有玩Code Review。干了一年后,觉得我妥协了很多我以前所坚持的东西,觉得自己的标准在降低,想一想后背拔凉拔凉的,所以我决定坚持,而且还要坚持高标准。

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (124 人打了分,平均分: 4.85 )
Loading...
C语言结构体里的成员数组和指针

C语言结构体里的成员数组和指针

单看这文章的标题,你可能会觉得好像没什么意思。你先别下这个结论,相信这篇文章会对你理解C语言有帮助。这篇文章产生的背景是在微博上,看到@Laruence同学出了一个关于C语言的题,微博链接。微博截图如下。我觉得好多人对这段代码的理解还不够深入,所以写下了这篇文章。

zero_array

为了方便你把代码copy过去编译和调试,我把代码列在下面:

#include <stdio.h>
struct str{
    int len;
    char s[0];
};

struct foo {
    struct str *a;
};

int main(int argc, char** argv) {
    struct foo f={0};
    if (f.a->s) {
        printf( f.a->s);
    }
    return 0;
}

你编译一下上面的代码,在VC++和GCC下都会在14行的printf处crash掉你的程序。@Laruence 说这个是个经典的坑,我觉得这怎么会是经典的坑呢?上面这代码,你一定会问,为什么if语句判断的不是f.a?而是f.a里面的数组?写这样代码的人脑子里在想什么?还是用这样的代码来玩票?不管怎么样,看过原微博的回复,我个人觉得大家主要还是对C语言理解不深,如果这算坑的话,那么全都是坑。

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (60 人打了分,平均分: 4.80 )
Loading...
无插件Vim编程技巧

无插件Vim编程技巧

相信大家看过《简明Vim教程》也玩了《Vim大冒险》的游戏了,相信大家对Vim都有一个好的入门了。我在这里把我日常用Vim编程的一些技巧列出来给大家看看,希望对大家有用,另外,也是一个抛砖引玉的过程,也希望大家把你们的技巧跟贴一下,我会更新到这篇文章中。另外,这篇文章里的这些技巧全都是vim原生态的,不需要你安装什么插件。我的Vim的版本是7.2

浏览代码

首先,我们先从浏览代码开始。有时候,我们需要看多个文件,所以,传统的做法是,我们开多个tty终端,每个tty里用Vim打开一个文件,然后来回切换。这很没有什么效率。我们希望在一个Vim里打开多个文件,甚至浏览程序目录。

浏览目录的命令很简单:(你也可以直接vim一个目录)

:E

注意,是大写。于是,你会看到下面这样的界面:

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (35 人打了分,平均分: 4.57 )
Loading...
Python修饰器的函数式编程

Python修饰器的函数式编程

Python的修饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator搞混了,其实这是完全不同的两个东西。虽然好像,他们要干的事都很相似——都是想要对一个已有的模块做一些“修饰工作”,所谓修饰工作就是想给现有的模块加上一些小装饰(一些小功能,这些小功能可能好多模块都会用到),但又不让这个小装饰(小功能)侵入到原有的模块中的代码里去。但是OO的Decorator简直就是一场恶梦,不信你就去看看wikipedia上的词条(Decorator Pattern)里的UML图和那些代码,这就是我在《 从面向对象的设计模式看软件设计》“餐后甜点”一节中说的,OO鼓励了——“厚重地胶合和复杂层次”,也是《 如此理解面向对象编程》中所说的“OO的狂热者们非常害怕处理数据”,Decorator Pattern搞出来的代码简直就是OO的反面教程。

Python 的 Decorator在使用上和Java/C#的Annotation很相似,就是在方法名前面加一个@XXX注解来为这个方法装饰一些东西。但是,Java/C#的Annotation也很让人望而却步,太TMD的复杂了,你要玩它,你需要了解一堆Annotation的类库文档,让人感觉就是在学另外一门语言。

而Python使用了一种相对于Decorator Pattern和Annotation来说非常优雅的方法,这种方法不需要你去掌握什么复杂的OO模型或是Annotation的各种类库规定,完全就是语言层面的玩法:一种函数式编程的技巧。如果你看过本站的《函数式编程》,你一定会为函数式编程的那种“描述你想干什么,而不是描述你要怎么去实现”的编程方式感到畅快。(如果你不了解函数式编程,那在读本文之前,还请你移步去看看《函数式编程》) 好了,我们先来点感性认识,看一个Python修饰器的Hello World的代码。

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (22 人打了分,平均分: 5.00 )
Loading...
如何用最有创造力的方式输出42

如何用最有创造力的方式输出42

酷壳似乎好长时间没有像《编程真难啊》或是《老手是这样教新手编程的》或是像《如何写出无法维护的代码》这样“严肃正经”的文章了,所以,赶在大家还没有向我扔臭鸡蛋前奉献一篇。这篇文章来自CodeGolf.StackExchange上的《Most creative way to display 42》—— 请以最有创造力的方式输出42。于是出现了下面的这些答案(注:精彩的总是留在最后面)

人生和宇宙终级问题的答案:42

这里,需要介绍一下为什么要输出42。这时因为42是我们人生,世界乃至整个宇宙的终级答案。这要从《银河系漫游指南》(英文名:The Hitchhiker’s Guide to the Galaxy)说起。这本书是著名英国科幻小说作家Douglas  Adams所著5本银河系漫游指南系列科幻喜剧系列小说中的第一本,改编自他本人为英国广播公司第四电台(BBC Radio 4)所写的广播剧剧本。该书1979年10月12日首次由麦克米伦出版公司(Pan Books)出版,次周成为英国图书销量榜冠军,前3个月内销售超过25万本。截至2005年,这本小说已被翻译成超过30种语言在全世界发行,并且被改编为电视剧、电影、舞台剧等多种艺术形式的作品。

这本小说中小说中充满尖锐的讽刺和隐喻,被西方科幻爱好者奉为“科幻圣经”。其中有两个关键词,一个是Don’t Panic,一个是42影响力很大,而其中关于42的故事简介是这样的:

百万年前,老鼠其实是一种超智慧生物,它们建造了一部超级电脑深思Deep Thought,它们问超级电脑,生命、宇宙以及任何事情的终极答案(Answer to Life, the Universe, and Everything)什么,经过了750万年的计算,深思告诉老鼠的后人答案是42,深思解释它只能计算出答案是什么,但答案的原因必须由另一部更高智能的电脑才能解释,而该部电脑就是地球。经过了800万年,就在结果要出来的五分钟前,地球却因为挡在预定兴建的星际间高速公路的路线,被Vogons给毁灭,电脑没有给出最后的结果。

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (25 人打了分,平均分: 4.60 )
Loading...
由苹果的低级Bug想到的

由苹果的低级Bug想到的

2014年2月22日,在这个“这么二”的日子里,苹果公司推送了 iOS 7.0.6(版本号11B651)修复了 SSL 连接验证的一个 bug。官方网页在这里:http://support.apple.com/kb/HT6147,网页中如下描述:

Impact: An attacker with a privileged network position may capture or modify data in sessions protected by SSL/TLS

Description: Secure Transport failed to validate the authenticity of the connection. This issue was addressed by restoring missing validation steps.

也就是说,这个bug会引起中间人攻击,bug的描述中说,这个问题是因为miss了对连接认证的合法性检查的步骤。

这里多说一句,一旦网上发生任何的和SSL/TL相关的bug或安全问题,不管是做为用户,还是做为程序员的你,你一定要高度重视起来。因为这个网络通信的加密协议被广泛的应用在很多很多最最需要安全的地方,如果SSL/TLS有问题的话,意味着这个世界的计算机安全体系的崩溃。

Bug的代码原因

Adam Langley的《Apple’s SSL/TLS bug 》的博文暴出了这个bug的细节。(在苹果的开源网站上,通过查看苹果的和SSL/TLS有关的代码变更,我们可以在文件sslKeyExchange.c中找到下面的代码)

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (43 人打了分,平均分: 4.84 )
Loading...
可视化编程

可视化编程

本文来自《Visual Programming Languages – Snapshots》,作者Eric Hosick收集了一堆关于可视化编程的工具,好多我都听都没听说过,我一股脑的全转过来,给大家看看,算是开开眼界了。本文也是参考了Wikipedia的 Visual Programming Language 词条。

另外,在原文有很多评论,其中也有很多正文没有提到的,你可以前去围观一下。

SketchPad

Maybe the first. 1963.

图片来源, Wikipedia官方网站

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (16 人打了分,平均分: 4.75 )
Loading...
从“黑掉Github”学Web安全开发

从“黑掉Github”学Web安全开发

Egor Homakov(Twitter: @homakov 个人网站: EgorHomakov.com)是一个Web安全的布道士,他这两天把github给黑了,并给github报了5个安全方面的bug,他在他的这篇blog——《How I hacked Github again》(墙)说明了这5个安全bug以及他把github黑掉的思路。Egor的这篇文章讲得比较简单,很多地方一笔带过,所以,我在这里用我的语言给大家阐述一下黑掉Github的思路以及原文中所提到的那5个bug。希望这篇文章能让从事Web开发的同学们警惕。关于Web开发中的安全事项,大家可以看看这篇文章《Web开发中的你需要了解的东西

OAuth简介

首先,这个故事要从Github OAuth讲起。所以,我们需要先知道什么是OAuth。所谓OAuth就是说,第三方的应用可以通过你的授权而不用知道你的帐号密码能够访问你在某网站的你自己的数据或功能。像Google, Facebook, Twitter等网站都提供了OAuth服务,提供OAuth服务的网站一般都有很多开放的API,第三方应用会调用这些API来开发他们的应用以让用户拥有更多的功能,但是,当用户在使用这些第三方应用的时候,这些第三方的应用会来访问用户的帐户内的功能和数据,所以,当第三应用要干这些事的时候,我们不能让第三方应用弹出一个对话框来问用户要他的帐号密码,不然第三方的应用就把用户的密码给获取了,所以,OAuth协议会跳转到一个页面,让用户授权给这个第三方应用以某些权限,然后,这个权限授权的记录保存在Google/Facebook/Twitter上,并向第三方应用返回一个授权token,于是第三方的应用通过这个token来操作某用户帐号的功能和数据时,就畅通无阻了。下图简单地说明了Twitter的OAuth的授权过程。

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (44 人打了分,平均分: 4.57 )
Loading...
分布式系统的事务处理

分布式系统的事务处理

当我们在生产线上用一台服务器来提供数据服务的时候,我会遇到如下的两个问题:

1)一台服务器的性能不足以提供足够的能力服务于所有的网络请求。

2)我们总是害怕我们的这台服务器停机,造成服务不可用或是数据丢失。

于是我们不得不对我们的服务器进行扩展,加入更多的机器来分担性能上的问题,以及来解决单点故障问题。 通常,我们会通过两种手段来扩展我们的数据服务:

1)数据分区:就是把数据分块放在不同的服务器上(如:uid % 16,一致性哈希等)。

2)数据镜像:让所有的服务器都有相同的数据,提供相当的服务。

对于第一种情况,我们无法解决数据丢失的问题,单台服务器出问题时,会有部分数据丢失。所以,数据服务的高可用性只能通过第二种方法来完成——数据的冗余存储(一般工业界认为比较安全的备份数应该是3份,如:Hadoop和Dynamo)。 但是,加入更多的机器,会让我们的数据服务变得很复杂,尤其是跨服务器的事务处理,也就是跨服务器的数据一致性。这个是一个很难的问题。 让我们用最经典的Use Case:“A帐号向B帐号汇钱”来说明一下,熟悉RDBMS事务的都知道从帐号A到帐号B需要6个操作:

  1. 从A帐号中把余额读出来。
  2. 对A帐号做减法操作。
  3. 把结果写回A帐号中。
  4. 从B帐号中把余额读出来。
  5. 对B帐号做加法操作。
  6. 把结果写回B帐号中。

为了数据的一致性,这6件事,要么都成功做完,要么都不成功,而且这个操作的过程中,对A、B帐号的其它访问必需锁死,所谓锁死就是要排除其它的读写操作,不然会有脏数据的问题,这就是事务。那么,我们在加入了更多的机器后,这个事情会变得复杂起来:

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (62 人打了分,平均分: 4.79 )
Loading...