Browsed by
分类:编程语言

一些文章资源和趣闻

一些文章资源和趣闻

下面是我这段时间来收集的一些有意思的东西。本站这样的文章还很多,如这个这个这个

Javascript Garden,这是学习Javascript最好的网站了。http://bonsaiden.github.com/JavaScript-Garden,这个文档由两具StackOverflow的人写成, Ivo Wetzel(Writing) 和 Zhang Yi Jiang (Design),表示敬意。

想看看Web开发有哪些技术吗?你得看看这个网站:http://stackparts.com/,他对目前几乎所有Web上用得到的技术都分了个类。下面是个抓图。

Mozilla的安全编程规范 https://wiki.mozilla.org/WebAppSec/Secure_Coding_Guidelines Downloads associated to Software development

PHP,Perl, Ruby, Python语法比较http://hyperpolyglot.org/scripting?utm_source

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (8 人打了分,平均分: 5.00 )
Loading...
深入理解C语言

深入理解C语言

Dennis Ritchie  过世了,他发明了C语言,一个影响深远并彻底改变世界的计算机语言。一门经历40多年的到今天还长盛不衰的语言,今天很多语言都受到C的影响,C++,Java,C#,Perl, PHP, Javascript, 等等。但是,你对C了解吗?相信你看过本站的《C语言的谜题》还有《谁说C语言很简单?》,这里,我再写一篇关于深入理解C语言的文章,一方面是缅怀Dennis,另一方面是告诉大家应该如何学好一门语言。(顺便注明一下,下面的一些例子来源于这个slides

首先,我们先来看下面这个经典的代码:

int main()
{
    int a = 42;
    printf(“%d\n”, a);
}

从这段代码里你看到了什么问题?我们都知道,这段程序里少了一个#include <stdio.h> 还少了一个return 0;的返回语句。

不过,让我们来深入的学习一下,

  • 这段代码在C++下无法编译,因为C++需要明确声明函数
  • 这段代码在C的编译器下会编译通过,因为在编译期,编译器会生成一个printf的函数定义,并生成.o文件,链接时,会找到标准的链接库,所以能编译通过。
  •  但是,你知道这段程序的退出码吗?在ANSI-C下,退出码是一些未定义的垃圾数。但在C89下,退出码是3,因为其取了printf的返回值。为什么printf函数返回3呢?因为其输出了’4′, ‘2’,’\n’ 三个字符。而在C99下,其会返回0,也就是成功地运行了这段程序。你可以使用gcc的 -std=c89或是-std=c99来编译上面的程序看结果。
  • 另外,我们还要注意main(),在C标准下,如果一个函数不要参数,应该声明成main(void),而main()其实相当于main(…),也就是说其可以有任意多的参数。

我们再来看一段代码:

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (41 人打了分,平均分: 4.34 )
Loading...
API设计:用流畅接口构造内部DSL

API设计:用流畅接口构造内部DSL

感谢@weidagang (Todd)向酷壳投递本文。

程序设计语言的抽象机制包含了两个最基本的方面:一是语言关注的基本元素/语义;另一个是从基本元素/语义到复合元素/语义的构造规则。在C、C++、Java、C#、Python等通用语言中,语言的基本元素/语义往往离问题域较远,通过API库的形式进行层层抽象是降低问题难度最常用的方法。比如,在C语言中最常见的方式是提供函数库来封装复杂逻辑,方便外部调用。

不过普通的API设计方法存在一种天然的陷阱,那就是不管怎样封装,大过程虽然比小过程抽象层次更高,但本质上还是过程,受到过程语义的制约。也就是说,通过基本元素/语义构造更高级抽象元素/语义的时候,语言的构造规则很大程度上限制了抽象的维度,我们很难跳出这个维度去,甚至可能根本意识不到这个限制。而SQL、HTML、CSS、make等DSL(领域特定语言)的抽象维度是为特定领域量身定做的,从这些抽象角度看问题往往最为简单,所以DSL在解决其特定领域的问题时比通用程序设计语言更加方便。通常,SQL等非通用语言被称为外部DSL(External DSL);在通用语言中,我们其实也可以在一定程度上突破语言构造规则的抽象维度限制,定义内部DSL(Internal DSL)。

本文将介绍一种被称为流畅接口(Fluent Interface)的内部DSL设计方法。Wikipedia上Fluent Interface的定义是:

A fluent interface (as first coined by Eric Evans and Martin Fowler) is an implementation of an object oriented API that aims to provide for more readable code. A fluent interface is normally implemented by using method chaining to relay the instruction context of a subsequent call (but a fluent interface entails more than just method chaining).

下面将分4个部分来逐步说明流畅接口在构造内部DSL中的典型应用。

1. 基本语义抽象

如果要输出0..4这5个数,我们一般会首先想到类似这样的代码:

//Java
for (int i = 0; i < 5; ++i) {
    system.out.println(i);
}

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (14 人打了分,平均分: 3.36 )
Loading...
一些文章和各种资源

一些文章和各种资源

下面是近期收录的一些文章和资源,希望对你有用。

系统方面

Mozilla's Gecko rendering engine main flow
Mozilla's Gecko rendering engine main flow
好烂啊有点差凑合看看还不错很精彩 (18 人打了分,平均分: 5.00 )
Loading...
千万不要把 bool 设计成函数参数

千万不要把 bool 设计成函数参数

我们有很多Coding Style 或 代码规范。但这一条可能会经常被我们所遗忘,就是我们经常会在函数的参数里使用bool参数,这会大大地降低代码的可读性。不信?我们先来看看下面的代码。

当你读到下面的代码,你会觉得这个代码是什么意思?

widget->repaint(false);

是不要repaint吗?还是别的什么意思?看了文档后,我们才知道这个参数是immediate, 也就是说,false代表不立即重画,true代码立即重画。

Windows API中也有这样一个函数:InvalidateRect,当你看到下面的代码,你会觉得是什么意思?

InvalidateRect(hwnd, lpRect,  false);

我们先不说InvalidateRect这个函数名取得有多糟糕,我们先说一下那个false参数?invalidate意为“让XXX无效”,false是什么意思?双重否定?是肯定的意思?如果你看到这样的代码,你会相当的费解的。于是,你要去看一下文档,或是InvalidateRect的函数定义,你会看到那个参数是 BOOL bErase,意思是,是否要重画背景。

这样的事情有很多,再看下面的代码,想把str中的”%USER%”替换成真实的用户名:

str.replace("%USER%", user, false);   // Qt 3

TNND,那个false是什么意思?不替换吗?还是别的什么意思,看了文档才知道,false代码大小写不敏感的替换。

其实,如果你使用枚举变量/常量,而不是bool变量,你会让你的代码更易读,如:

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (27 人打了分,平均分: 4.30 )
Loading...
C语言中史上最愚蠢的Bug

C语言中史上最愚蠢的Bug

本文来自“The most stupid C bug ever”,很有意思,分享给大家。我相信这样的bug,就算你是高手你也会犯的。你来看看作者犯的这个Bug吧。。

首先,作者想用一段程序来创建一个文件,如果有文件名的话,就创建真正的文件,如果没有的话,就调用?tmpfile()?创建临时文件。他这段程序就是HTTP下载的C程序。code==200就是HTTP的返回码。

else if (code == 200) {     // Downloading whole file
    /* Write new file (plus allow reading once we finish) */
    g = fname ? fopen(fname, "w+") : tmpfile();
}

但是这个程序,只能在Unix/Linux下工作,因为 Microsoft 的?tmpfile()的实现?居然选择了 C:\ 作为临时文件的存放目录,这对于那些没有管理员权限的人来说就出大问题了,在Windows 7下,就算你有管理员权限也会有问题。所以,上面的程序在Windows平台下需要用不同的方式来处理,不能直接使用Windows的tmpfile()函数。

于是作者就先把这个问题记下来,在注释中写下了FIXME:

else if (code == 200) {     // Downloading whole file
    /* Write new file (plus allow reading once we finish) */

    // FIXME Win32 native version fails here because
    //   Microsoft's version of tmpfile() creates the file in C:\
    g = fname ? fopen(fname, "w+") : tmpfile();
}

然后,作者觉得需要写一个跨平台的编译:

FILE * tmpfile ( void ) {
#ifndef _WIN32
    return tmpfile();
#else
    //code for Windows;
#endif
}

然后,作者觉得这样实现很不好,会发现名字冲突,因为这样一来这个函数太难看了。于是他重构了一下他的代码——写一个自己实现的tmpfile() – w32_tmpfile,然后,在Windows 下用宏定义来重命名这个函数为tmpfile()。(陈皓注:这种用法是比较标准的跨平台代码的写法)

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (37 人打了分,平均分: 4.73 )
Loading...
你会做Web上的用户登录功能吗?

你会做Web上的用户登录功能吗?

Web上的用户登录功能应该是最基本的功能了,可是在我看过一些站点的用户登录功能后,我觉得很有必要写一篇文章教大家怎么来做用户登录功能。下面的文章告诉大家这个功能可能并没有你所想像的那么简单,这是一个关系到用户安全的功能,希望大家能从下面的文章中能知道什么样的方法才是一个好的用户登录功能。以下内容,转载时请保持原文一致,并请注明作者和出处

用户名和口令

首先,我们先来说说用户名和口令的事。这并不是本站第一次谈论这个事了。如何管理自己的口令让你知道怎么管理自己的口令,破解你的口令让你知道在现代这样速度的计算速度下,用穷举法破解你的口令可能会是一件很轻松的事。在这里我想告诉从开发者的角度上来做设计这个用户名和口令的事。下面一几件规则:

  • 限制用户输入一些非常容易被破解的口令。如什么qwert,123456, password之类,就像twitter限制用户的口令一样做一个口令的黑名单。另外,你可以限制用户口令的长度,是否有大小写,是否有数字,你可以用你的程序做一下校验。当然,这可能会让用户感到很不爽,所以,现在很多网站都提供了UX让用户知道他的口令强度是什么样的(比如这个有趣的UX),这样可以让用户有一个选择,目的就是告诉用户——要想安全,先把口令设得好一点。
  • 千万不要明文保存用户的口令。正如如何管理自己的口令所说的一样,很多时候,用户都会用相同的ID相同的口令来登录很多网站。所以,如果你的网站明文保存的话,那么,如果你的数据被你的不良员工流传出去那对用户是灾难性的。所以,用户的口令一定要加密保存,最好是用不可逆的加密,如MD5或是SHA1之类的有hash算法的不可逆的加密算法。CSDN曾明文保存过用户的口令。(另,对于国内公司的品行以及有关部门的管理方式,我不敢保证国内网站以加密的方式保存你的口令。我觉得,做为一个有良知的人,我们应该加密保存用户的口令)
好烂啊有点差凑合看看还不错很精彩 (40 人打了分,平均分: 4.70 )
Loading...
C++11 中值得关注的几大变化(详解)

C++11 中值得关注的几大变化(详解)

源文章来自前C++标准委员会的 Danny Kalev 的 The Biggest Changes in C++11 (and Why You Should Care),赖勇浩做了一个中文翻译在这里。所以,我就不翻译了,我在这里仅对文中提到的这些变化“追问为什么要引入这些变化”的一个探讨,只有知道为了什么,用在什么地方,我们才能真正学到这个知识。而以此你可以更深入地了解这些变化。所以,本文不是翻译。因为写得有些仓促,所以难免有问题,还请大家指正。

Lambda 表达式

Lambda表达式来源于函数式编程,说白就了就是在使用的地方定义函数,有的语言叫“闭包”,如果 lambda 函数没有传回值(例如 void ),其回返类型可被完全忽略。 定义在与 lambda 函数相同作用域的变量参考也可以被使用。这种的变量集合一般被称作 closure(闭包)。我在这里就不再讲这个事了。表达式的简单语法如下,

[capture](parameters)->return_type {body}

原文的作者给出了下面的例子:

int main()
{
   char s[]="Hello World!";
   int Uppercase = 0; //modified by the lambda
   for_each(s, s+sizeof(s), [&Uppercase] (char c) {
    if (isupper(c))
     Uppercase++;
    });
 cout << Uppercase << " uppercase letters in: " << s <<endl;
}

在传统的STL中for_each() 这个玩意最后那个参数需要一个“函数对象”,所谓函数对象,其实是一个class,这个class重载了operator(),于是这个对象可以像函数的式样的使用。实现一个函数对象并不容易,需要使用template,比如下面这个例子就是函数对象的简单例子(实际的实现远比这个复杂):

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (21 人打了分,平均分: 4.38 )
Loading...
国内微博和Twitter的最大不同

国内微博和Twitter的最大不同

霍炬近两个月前写过一篇《microblogging和微博信息架构产品差距和影响》分析了国内微博和Twitter的差距,重点就是因为信息的平等性。我也一直在观察新浪微博,以及新浪和Twitter的一些功能上的差别。发现了一些东西,想在这里和大家分享一下。我的见解达不到像霍炬那样的层次,作为一个技术人员,我只能在产品功能上做些分析。欢迎大家指正。

现实状况

国内的微博就是新浪,Sohu微博,腾讯微博,以及饭否。我们不难发现:

  • 搜狐的和腾讯的就是Copy新浪的。在Following和Followed上大家都有自己所谓的“创新”
  • 饭否是在Copy Twitter,这点太明显了,不过,抄在了表面,而且相当的怪。

国内所有的这些以Twitter为蓝本干出来的这些东西,其和Twitter在核心功能上有这些差别:

  • Twitter的Retweet一点信息都加不上,国内的微博的转发需要加上自己的评论,也就形自己的信息。
  • Twitter的Reply只会有一个@原来的人,国内的Reply也很相似,只是勾上转发后就会把Reply的东西以“//@XXX”的方式成为自己的信息。
  • 饭否的做法比较怪,转发加原文(想做成新浪的样子),回复不加原文,只有@(Twitter)的样子,可见饭否的分裂。

SNS中的上下文

这段时间,我一直在想,新浪为什么要做成这样,为什么不做成Twitter那样,或者,为什么Twitter做成那样而不是新浪这样?从表面上看上去,新浪的“回复+转发”会带被回的信息,而Twitter的回复不带上下文,Twitter上一些我fo的人的话题完全看不懂,不像新浪的还能看到上文

老实说,在一开始,我还觉得新浪微博这种用法和技术上要比 Twitter 要强大,现在看来是我当时对Twitter并不熟悉。经过这段时间的观察。我恰恰发现新浪在转发和回复上都要带上原文其实是一件很没有技术含量的事。要说清这个事,请让我说一下评论和回复的事。

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (29 人打了分,平均分: 4.17 )
Loading...
对象的消息模型

对象的消息模型

[ ———— 感谢 Todd 同学 投递本文,原文链接 ———— ]

C++对象模型

话题从下面这段C++程序说起,你认为它可以顺利执行吗?

//C++
class A {
    public:
        void Hello(const std::string& name) {
           std::cout << "hello " << name;
         }
};
int main(int argc, char** argv)
{
    A* pa = NULL; //!!
    pa->Hello("world");
    return 0;
}

试试的确可以顺利运行输出hello world,奇怪吗?其实并不奇怪,根据C++对象模型,类的非虚方法并不会存在于对象内存布局中,实际上编译器是把Hello方法转化成了类似这样的全局函数:

void A_Hello_xxx(A * const this, const std::string& name) {
    std::cout << “hello “ << name;
}

对象指针其实是作为第一个参数被隐式传递的,pa->Hello(“world”)实际上是调用的A_Hello_xxx(pa, “world”),而恰好A_Hello_xxx内部没有使用pa,所以这段代码得以顺利运行。

对象的消息模型

如果是研究C++对象模型,上面的讨论可以到此为止,不过这里我想从另一个层面来继续探讨这个问题。OOP的先驱人物Alan Kay在总结Smalltalk的OO特征时强调:

阅读全文 Read More

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