Strict mode – JavaScript

ECMAScript 5的严格模式是Javascript中的一种限制性更强的变种方式。严格模式不是一个子集:它在语义上与正常代码有着特意的差异。不支持严格模式的浏览器与同支持严格模式的浏览器行为上也不一样, 所以不要在未经严格模式特性测试情况下使用严格模式。严格模式可以与非严格模式共存,所以脚本可以逐渐的选择性加入严格模式。严格模式在语义上与正常的JavaSript有一些变化。 首先,严格模式会将JavaScript陷阱直接变成明显的错误。其次,严格模式修正了一些引擎难以优化的错误:同样的代码有些时候严格模式会比非严格模式下更快。 第三,严格模式禁用了一些有可能在未来版本中定义的语法。如果你想让你的JavaScript代码在严格模板下运行,可以参考转换成严格模式。
开启严格模式
严格模式可以应用到整个script标签或某个别函数中。不要在封闭大括弧( {} )内这样做;在这样的上下文中这么做是没有效果的。 例如,eval 代码,Function 代码,事件处理属性,传入 setTimeout方法的字符串 等等包括整个脚本中开启严格模式都会如预期一样工作。
为某个script标签开启严格模式
为整个script标签开启严格模式, 需要在所有语句之前放一个特定语句 “use strict”; (或 ‘use strict’;)

// 整个语句都开启严格模式的语法
"use strict";
var v = "Hi! I'm a strict mode script!";

这种语法存在陷阱,有一个大型网站已经被它坑倒了:不能盲目的拼合非冲突代码。如果串联一个严格模式的脚本和一个非严格模式的脚本:整个拼合后的脚本代码看起来成了严格模式。反之亦然:非严格串联严格看起来像是非严格的。拼合全为严格模式的脚本或全为非严格模式的都没问题,只有在拼合严格模式与非严格模式有可能有问题。建议按一个个函数去开启严格模式(至少在学习的过渡期要这样做).
您也可以将整个脚本的内容用包裹在一个函数里面,并在外部函数中使用严格模式。这样做就可以消除拼接的问题,但是这就意味着您必须要在函数作用域外声明一个全局变量。
为某个函数开启严格模式
同样的,各某个函数开启严格模式就放一句 “use strict”; (或 ‘use strict’;) 在函数体所有语句之前。

function strict()
{
// 函数级别严格模式语法
'use strict';
function nested() { return "And so am I!"; }
return "Hi! I'm a strict mode function! " + nested();
}
function notStrict() { return "I'm not strict."; }

严格模式有哪些不同
严格模式同时改变了语法及运行时行为。变化通常分为这几类:将问题直接转化为错误(如语法错误或运行时错误), 简化了如何为给定名称的特定变量计算,简化了 eval 以及 arguments, 将写”安全“JavaScript的步骤变得更简单,以及改变了预测未来ECMAScript行为的方式。
将拼写错转成异常
在严格模式下, 先前被接受的拼写错误将会被认为是异常. JavaScript被设计为能使新人开发者更易于上手, 所以有时候会给本来错误操作赋予新的不报错误的语义(non-error semantics). 有时候这可以解决当前的问题, 但有时候却会给以后留下更大的问题. 严格模式则把这些失误当成错误, 以便可以发现并立即将其改正.
首先,严格模式下无法再意外创建全局变量。在普通的JavaScript里面给一个拼写错误的变量名赋值会使全局对象新增一个属性并继续“工作”(仅管后面可能出错:在现在的JavaScript中有可能)。严格模式中意外创建全局变量被抛出错误替代:

"use strict";
mistypedVariable = 17; // 抛出 ReferenceError

其次, 严格模式会使引起静默失败(silently fail,注:不报错也没有任何效果)的赋值操作抛出异常. 例如, NaN 是一个不可写的全局变量. 在正常模式下, 给 NaN 赋值不会产生任何作用; 开发者也不会受到任何错误反馈. 但在严格模式下, 给 NaN 赋值会抛出一个异常. 任何在正常模式下引起静默失败的赋值操作 (给不可写属性赋值, 给只读属性(getter-only)赋值赋值, 给不可扩展对象(non-extensible object)的新属性赋值) 都会抛出异常:

"use strict";
// 给不可写属性赋值
var obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // throws a TypeError
// 给只读属性赋值
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError
// 给不可扩展对象的新属性赋值
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // throws a TypeError

第三, 在严格模式下, 试图删除不可删除的属性时会抛出异常(之前这种操作不会产生任何效果):

"use strict";
delete Object.prototype; // throws a TypeError

第四, 严格模式要求一个对象内的所有属性名在对象内必须唯一. 正常模式下重名属性是允许的, 重名的最后一个属性决定其属性值. 因为只有最后一个属性有效, 当修改代码要改变属性值而却不是修改的最后一个重名属性的时候, 这种重复就成了bug的温床. 在严格模式下, 重名属性被认为是语法错误:

"use strict";
var o = { p: 1, p: 2 }; // !!! 语法错误

第五, 严格模式要求函数的参数名唯一. 在正常模式下, 最后一个重名参数名会掩盖之前的重名参数. 之前的参数仍然可以通过 arguments[i] 来访问, 还不是完全无法访问. 然而, 这种隐藏豪无意义或者并不是故意为之 (比如, 就是一个打字错误), 所以在严格模式下重名参数被认为是语法错误:

function sum(a, a, c) // !!! 语法错误
{
"use strict";
return a + b + c; // 如果代码运行到这里,将会有一个bug
}

第六, 严格模式禁止八进制数字语法. ECMAScript并不包含八进制语法, 但所有的浏览器都支持这种以零(0)开头的八进制语法: 0644 === 420 还有 “\045” === “%”. 有些新手开发者认为数字的前导零没有语法意义, 所以他们会用作对齐措施 — 但其实这会改变数字的意义! 八进制语法很少有用并且可能会错误使用, 所以严格模式下八进制语法会引起语法错误:

"use strict";
var sum = 015 + // !!! 语法错误
197 +
142;

简化变量的使用
严格模式简化了代码中变量名字映射到变量定义的方式. Many compiler optimizations rely on the ability to say that variable X is stored in that location: 这对全面优化JavaScript代码至关重要. JavaScript有些情况会使得代码中名字到变量定义的基本映射只在运行时才产生. 严格模式移除了大多数这种情况的发生, 所以编译器可以更好的优化严格模式的代码.
首先, 严格模式禁用 with. with 所引起的问题是块内的任何名称可以映射(map)到with传进来的对象的属性, 也可以映射到包围这个块的作用域内的变量(甚至是全局变量), 这一切都是在运行时决定的: 在代码运行之前是无法得知的. 严格模式下, 使用 with 会引起语法错误, 所以就不会存在 with 块内的变量在运行是才决定引用到哪里的情况了:

"use strict";
var x = 17;
with (obj) // !!! 语法错误
{
// 如果没有开启严格模式,with中的这个x会指向with上面的那个x,还是obj.x?如果不运行代码,我们无法知道,因此,这种代码让引擎无法进行优化,速度也就会很慢了.
x;
}

一种取代 with 的简单方法是,将目标对象赋给一个短命名变量,然后访问这个变量上的相应属性.
第二, 严格模式下的 eval 不在为上层范围(surrounding scope,注:包围eval代码块的范围)引入新变量. 在正常模式下, 代码 eval(“var x;”) 会给上层函数(surrounding function)或者全局引入一个新的变量 x . 这意味着, 一般情况下, 在一个包含 eval 调用的函数内所有没有引用到参数或者局部变量的名称都必须在运行时才能被映射到特定的定义 (因为 eval 可能引入的新变量会覆盖它的外层变量). 在严格模式下 eval 仅仅为被运行的代码创建变量, 所以 eval 不会影响到名称映射到外部变量或者其他局部变量:

var x = 17;
var evalX = eval("'use strict'; var x = 42; x");
assert(x === 17);
assert(evalX === 42);

相应的, 如果函数 eval 在被严格模式下的eval(…)以表达式的形式调用时, 其代码会被当做严格模式下的代码执行. 当然也可以在代码中显式开启严格模式, 但这样做并不是必须的.

function strict1(str)
{
"use strict";
return eval(str); // str中包含的代码肯定会在严格模式下运行
}
function strict2(f, str)
{
"use strict";
return f(str); // f是个处于严格模式下的函数,或者f为eval且str中的适当位置处添加了"use strict"的情况下,str中的代码才会在严格模式下运行
}
function nonstrict(str)
{
return eval(str); // 只有在str中的适当位置处添加了"use strict",str中的代码才会在严格模式下运行
}
strict1("'Strict mode code!'");
strict1("'use strict'; 'Strict mode code!'");
strict2(eval, "'Non-strict code.'");
strict2(eval, "'use strict'; 'Strict mode code!'");
nonstrict("'Non-strict code.'");
nonstrict("'use strict'; 'Strict mode code!'");
Thus names in strict mode eval code behave identically to names in strict mode code not being evaluated as the result of eval.

第三, 严格模式禁止删除plain names. delete name 在严格模式下会引起语法错误:

"use strict";
eval("var x; delete x;"); // !!! 语法错误

让eval和arguments变的简单
严格模式让arguments和eval少了一些奇怪的行为。两者在通常的代码中都包含了很多奇怪的行为: eval to add or remove bindings and to change binding values, and arguments by its indexed properties aliasing named arguments. Strict mode makes great strides toward treating eval and arguments as keywords, although full fixes will not come until a future edition of ECMAScript.
首先, 名称 eval 和 arguments 不能被绑定(be bound)或赋值 in language syntax. 以下的所有尝试将一起语法错误:

"use strict";
eval = 17;
arguments++;
++eval;
var obj = { set p(arguments) { } };
var eval;
try { } catch (arguments) { }
function x(eval) { }
function arguments() { }
var y = function eval() { };
var f = new Function("arguments", "'use strict'; return 17;");

第二, strict mode code doesn’t alias properties of arguments objects created within it. 在正常模式下, 在第一个参数为 arg 的函数中, 设置 arg 的值会同时设置 arguments[0], 反之亦然(除非没有参数或者 arguments[0] 被删除了). 严格模式下, 在函数中的 arguments 对象存储其被调用时候的原始值. arguments[i] 不在追踪相应名称参数的值的变化, 名称参数也不在追踪相应的 arguments[i].

function f(a)
{
"use strict";
a = 42;
return [a, arguments[0]];
}
var pair = f(17);
assert(pair[0] === 42);
assert(pair[1] === 17);

第三点,不再支持arguments.callee属性.在非严格模式中,arguments.callee指向当前正在执行的函数. 这个用处很弱: 直接用名字就可以了! 此外, arguments.callee substantially hinders optimizations like inlining functions, because it must be made possible to provide a reference to the un-inlined function if arguments.callee is accessed. 严格模式下函数中的 arguments.callee 是一个不可删除属性, 被设置或读取都会跑出异常:

"use strict";
var f = function() { return arguments.callee; };
f(); // throws a TypeError

“Securing” JavaScript
Strict mode makes it easier to write “secure” JavaScript. Some websites now provide ways for users to write JavaScript which will be run by the website on behalf of other users. JavaScript in browsers can access the user’s private information, so such JavaScript must be partially transformed before it is run, to censor access to forbidden functionality. JavaScript’s flexibility makes it effectively impossible to do this without many runtime checks. Certain language functions are so pervasive that performing runtime checks has considerable performance cost. A few strict mode tweaks, plus requiring that user-submitted JavaScript be strict mode code and that it be invoked in a certain manner, substantially reduce the need for those runtime checks.
First, the value passed as this to a function in strict mode isn’t boxed into an object. For a normal function, this is always an object: the provided object if called with an object-valued this; the value, boxed, if called with a Boolean, string, or number this; or the global object if called with an undefined or null this. (Use call, apply, or bind to specify a particular this.) Automatic boxing is a performance cost, but exposing the global object in browsers is a security hazard, because the global object provides access to functionality “secure” JavaScript environments must restrict. Thus for a strict mode function, the specified this is used unchanged:

"use strict";
function fun() { return this; }
assert(fun() === undefined);
assert(fun.call(2) === 2);
assert(fun.apply(null) === null);
assert(fun.call(undefined) === undefined);
assert(fun.bind(true)() === true);

Second, in strict mode it’s no longer possible to “walk” the JavaScript stack via commonly-implemented extensions to ECMAScript. In normal code with these extensions, when a function fun is in the middle of being called, fun.caller is the function that most recently called fun, and fun.arguments is the arguments for that invocation of fun. Both extensions are problematic for “secure” JavaScript, because they allow “secured” code to access “privileged” functions and their (potentially unsecured) arguments. If fun is in strict mode, both fun.caller and fun.arguments are non-deletable properties which throw when set or retrieved:

function restricted()
{
"use strict";
restricted.caller; // throws a TypeError
restricted.arguments; // throws a TypeError
}
function privilegedInvoker()
{
return restricted();
}
privilegedInvoker();

Third, arguments for strict mode functions no longer provide access to the corresponding function call’s variables. In some old ECMAScript implementations arguments.caller was an object whose properties aliased variables in that function. This is a security hazard because it breaks the ability to hide privileged values via function abstraction; it also precludes most optimizations. For these reasons no recent browsers implement it. Yet because of its historical functionality, arguments.caller for a strict mode function is also a non-deletable property which throws when set or retrieved:

"use strict";
function fun(a, b)
{
"use strict";
var v = 12;
return arguments.caller; // throws a TypeError
}
fun(1, 2); // doesn't expose v (or a or b)

Paving the way for future ECMAScript versions
Future ECMAScript versions will likely introduce new syntax, and strict mode in ECMAScript 5 applies some restrictions to ease the transition. It will be easier to make some changes if the foundations of those changes are prohibited in strict mode.
First, in strict mode a short list of identifiers become reserved keywords. These words are implements, interface, let, package, private, protected, public, static, and yield. In strict mode, then, you can’t name or use variables or arguments with these names.

function package(protected) // !!!
{
"use strict";
var implements; // !!!
interface: // !!!
while (true)
{
break interface; // !!!
}
function private() { } // !!!
}
function fun(static) { 'use strict'; } // !!!

Two Mozilla-specific caveats: First, if your code is JavaScript 1.7 or greater (you’re chrome code, or you’ve used the right, won’t be able to use let/yield as identifiers. Second, while ES5 unconditionally reserves the words class, enum, export, extends, import, and super, before Firefox 5 Mozilla reserved them only in strict mode.
Second, strict mode prohibits function statements not at the top level of a script or function. In normal code in browsers, function statements are permitted “everywhere”. This is not part of ES5 (or even ES3)! It’s an extension with incompatible semantics in different browsers. Future ECMAScript editions will hopefully specify new semantics for function statements not at the top level of a script or function. Prohibiting such function statements in strict mode “clears the deck” for specification in a future ECMAScript release:

"use strict";
if (true)
{
function f() { } // !!! syntax error
f();
}
for (var i = 0; i < 5; i++)
{
function f2() { } // !!! syntax error
f2();
}
function baz() // kosher
{
function eit() { } // also kosher
}

This prohibition isn’t strict mode proper, because such function statements are an extension of basic ES5. But it is the recommendation of the ECMAScript committee, and browsers will implement it.
浏览器的严格模式
浏览器并未真的实现严格模式,所以请不要盲目的依赖严格模式。 Strict mode changes semantics. Relying on those changes will cause mistakes and errors in browsers which don’t implement strict mode. Exercise caution in using strict mode, and back up reliance on strict mode with feature tests that check whether relevant parts of strict mode are implemented. Finally, make sure to test your code in browsers that do and don’t support strict mode. If you test only in browsers that don’t support strict mode, you’re very likely to have problems in browsers that do, and vice versa.

墨菲定律

“墨菲定律”是一种心理学效应,由”爱德华·墨菲(Edward A. Murphy)工程师提出的,主要内容,一、任何事都没有表面看起来那么简单;二、所有的事都会比你预计的时间长;三、会出错的事总会出错;四、如果你担心某种情况发生,那么它就更有可能发生。墨菲定律的原句是这样的:如果有两种或两种以上的方式去做某件事情,而其中一种选择方式将导致灾难,则必定有人会做出这种选择。

墨菲定律的原句已经派生出以下的版本:

1.别试图教猫唱歌,这样不但不会有结果,还会惹猫不高兴。
2.别跟傻瓜吵架,不然旁人会搞不清楚,到底谁是傻瓜。
3.不要以为自己很重要,因为没有你,太阳明天还是一样从东方升上来。
4.笑一笑,明天未必比今天好。
5.好的开始,未必就有好结果;坏的开始,结果往往会更糟。
6.你若帮助了一个急需用钱的朋友,他一定会记得你——在他下次急需用钱的时候。
7.有能力的——让他做;没能力的──教他做;做不来的──管理他。
8.你早到了,会议却取消;你准时到,却还要等;迟到,就是迟了。
9.你携伴出游,越不想让人看见,越会遇见熟人。
10.你爱上的人,总以为你爱上他是因为:他使你想起你的老情人。
11.你最后硬着头皮寄出的情书;寄达对方的时间有多长,你反悔的时间就有多长。
12.东西越好,越不中用。
13.一种产品保证60天不会出故障,等于保证第61天一定就会坏掉。
14.东西久久都派不上用场,就可以丢掉;东西一丢掉,往往就必须要用它。
15.你丢掉了东西时,最先去找的地方,往往也是可能找到的最后一个地方。
16.你往往会找到不是你正想找的东西。
17.你出去买爆米花的时候,银幕上偏偏就出现了精彩镜头。
18.另一排总是动的比较快;你换到另一排,你原来站的那一排,就开始动的比较快了;你站的越久,越有可能是站错了排。
19.一分钟有多长? 这要看你是蹲在厕所里面,还是等在厕所外面。
20、计划没有变化快。
21、欠账总是要还的。
22、做恶总是要遭报应的,不是不报,只是时间未到。
23、该来的总是要来的。
24、明天又是一个新的开始。
25、你越是害怕的事物,就越会出现在你的生活中。
26、往往等公车太久没来,就走了的人,刚走公车就来了。
27、关键时刻掉链子。
28、越想要什么就越不能得到什么。
29、人出来混,总是要还的。
30、怕什么,来什么。
31、若想人不知除非己莫为。

CDM、LDM与PDM的区别

概念数据模型设计与逻辑数据模型设计、物理数据模型设计是数据库及数据仓库模型设计的三个主要步骤。

在数据仓库领域有一个概念叫conceptual data model,中文一般翻译为“概念数据模型”。

概念数据模型是最终用户对数据存储的看法,反映了最终用户综合性的信息需求,它以数据类的方式描述企业级的数据需求,数据类代表了在业务环境中自然聚集成的几个主要类别数据。

概念数据模型的内容包括重要的实体及实体之间的关系。在概念数据模型中不包括实体的属性,也不用定义实体的主键。这是概念数据模型和逻辑数据模型的主要区别。

概念数据模型的目标是统一业务概念,作为业务人员和技术人员之间沟通的桥梁,确定不同实体之间的最高层次的关系。

在有些数据模型的设计过程中,概念数据模型是和逻辑数据模型合在一起进行设计的。

在数据仓库领域有一个概念叫logical data model,中文一般翻译为“逻辑数据模型”。

逻辑数据模型反映的是系统分析设计人员对数据存储的观点,是对概念数据模型进一步的分解和细化。逻辑数据模型是根据业务规则确定的,关于业务对象、业务对象的数据项及业务对象之间关系的基本蓝图。

逻辑数据模型的内容包括所有的实体和关系,确定每个实体的属性,定义每个实体的主键,指定实体的外键,需要进行范式化处理。

逻辑数据模型的目标是尽可能详细的描述数据,但并不考虑数据在物理上如何来实现。

逻辑数据建模不仅会影响数据库设计的方向,还间接影响最终数据库的性能和管理。如果在实现逻辑数据模型时投入得足够多,那么在物理数据模型设计时就可以有许多可供选择的方法。

在数据仓库领域有一个概念叫physical data model,中文一般翻译为“物理数据模型”。

物理数据模型是在逻辑数据模型的基础上,考虑各种具体的技术实现因素,进行数据库体系结构设计,真正实现数据在数据库中的存放。

物理数据模型的内容包括确定所有的表和列,定义外键用于确定表之间的关系,基于用户的需求可能进行发范式化等内容。在物理实现上的考虑,可能会导致物理数据模型和逻辑数据模型有较大的不同。

物理数据模型的目标是指定如何用数据库模式来实现逻辑数据模型,以及真正的保存数据。

关于参数化查询的几点不足

参数化查询一般是防止SQL注入的万能型解决方案,查询参数的做法是在准备查询语句时,在对应参数的地方使用参数占位符,在执行这个参选准备好的查询时提供一个参数,但是这个查询参数总是被视为一个字面值,这将导致下列问题。

  1. 多个值的列表不可以当成单一参数。如:SELECT * FROM [表] WHERE ID IN (?);
  2. 列名、列名无法做为参数:SELECT * FROM ? ORDER BY ?;
  3. SQL关键字不能做为参数:SELECT * FROM [表] ORDER BY ID ?;

据说只有程序猿才能看懂的小幽默

1.老婆给当程序员的老公打电话:下班顺路买十个包子,如果看到卖西瓜的,买一个。当晚老公手捧一个包子进了家门…老婆怒道:你怎么只买一个包子?!老公甚恐,喃喃道:因为我真看到卖西瓜的了。”

2.一程序员去面试,面试官问:”你毕业才两年,这三年工作经验是怎么来的?!”程序员答:”加班。”

3.宝宝数学很好,2岁就可以从1数到10了。后来,我告诉他0比1还小。今天吃饺子,我说:”宝宝,你数数你想吃几个饺子?””0,1,2,3。”一边说着一边拿起一个饺子,”这是第0个。”老婆怒吼:”下一代还是做程序员的命!”

4.某程序员对书法十分感兴趣,退休后决定在这方面有所建树。于是花重金购买了上等的文房四宝。 一日,饭后突生雅兴,一番磨墨拟纸,并点上了上好的檀香,颇有王羲之风范,又具颜真卿气势, 定神片刻,泼墨挥毫,郑重地写下一行字:hello world。

5.问:程序员最讨厌康熙的哪个儿子。答:胤禩。因为他是八阿哥(bug)

6.程序猿要了3个孩子,分别取名叫Ctrl、Alt 和Delete,如果他们不听话,程序猿就只要同时敲他们一下就会好的…

7.如果没能一次成功,那就叫它1.0版吧。

8.今天在公司听到一句惨绝人寰骂人的话:”你TM就是一个没有对象的野指针!”

9.莫愁前路无知己,总有bug跟着你。

10.如果世界让程序员落魄,程序员就让世界沉默

11.开源客栈日暮,入栈不知归路。debug无尽头,误入代码深处,单步,单步,发现bug无数。

12.横眉冷对万行码,俯首甘为码字牛。问君能有几多愁,恰似调完代码改需求。

13.bug知时节,上线乃发生。随风潜入夜,404无声。野径云俱黑,孤窗火独明。晓看公司处,一只程序猿。

14.程xx遭遇车祸成植物人,医生说她活下来的希望只有万分之一,唤醒更为渺茫。她的同事和亲人没放弃,并根据程xx对testing痴迷的作风,每天都在她身边念:”你测的模块上线后回滚了…”奇迹发生了,程xx醒来第一句话:确认那模块是我测的?

15.两个程序员,

A:哥们,最近手头紧,能借点钱?
B:成啊,要多少?
A:一千成不?
B:咱俩谁跟谁!给你凑个整,这一千零二十四,拿去吧。
16.一个程序员在海滨游泳时溺水身亡。他死前拼命的呼救,当时海滩上有许多救生员,但是没有人救他。因为他一直大喊”F1!””F1!”,谁都不知道”F1″究竟是什么意思。

17.

1)程序员其实可痛苦的了……需求一做一改,一个月就过去了;嚎~需求再一改一调,一季度就过去了;嚎~
2)、程序员最痛苦的事儿是啥,知道不?就是,程序没做完,需求又改了;
3)、程序员最最痛苦的事儿是啥,知道不? 就是,系统好不容易做完了,方案全改了;
4)、程序员最最最痛苦的事儿是啥,知道不? 就是,系统做完了,狗日的客户跑了;
5)、程序员最最最最最痛苦的事儿是啥,知道不? 就是,狗日的客户又回来了,程序给删没了!
18.有一天一个程序员见到了上帝.

上帝: 小伙子,我可以满足你一个愿望.
程序员: 我希望中国国家队能再次打进世界杯.
上帝: 这个啊!这个不好办啊,你还说下一个吧!
程序员: 那好!我的下一个愿望是每天都能休息6个小时以上.
上帝: 还是让中国国家打进世界杯.
19.做了几年程序员,厌烦了,想换行了。于是天天猛敲回车键。

20.问:一对程序员恋人面对面坐着工作,你猜他们在做什么?答:面向对象编程。

21.十年生死两茫茫,写程序,到天亮。 千行代码,Bug何处藏。 纵使上线又怎样,朝令改,夕断肠。 领导每天新想法,天天改,日日忙。 相顾无言,惟有泪千行。 每晚灯火阑珊处,程序员,又加班,工作狂.

22.世界上最远的距离,是我在if里你在else里,虽然经常一起出现,但却永不结伴执行

23.十行代码九个警告八个错误竟然敢说七日精通六天学会五湖四海也不见如此三心二意之项目经理简直一等下流。

24.程序猿:我的第一个问题是,对于我第二个和第三个问题,你可不可以只用’能’和’不能’来回答?

老板:”OK!”
我的第二个问题是,如果我的第三个问题是我能不能涨工资?那么你对于我的第三个问题的答案能不能和第二个问题的答案一样?
老板:。。。。。。
25.《程序员的雨巷》开着MyEclipse,独自彷徨在悠长、悠长又寂寥的雨巷,我希望逢着一个和我一样的调试代码的姑娘。她是有需求一样的凌乱,设计一样的荒唐,测试一样的忧愁, 在代码里哀怨,哀怨又彷徨;她彷徨在这寂寥的雨巷。

26.一女同学在食堂吃饭时,一程序猿凑到旁边,”同学,我能和你说话不,我已经一个月没和女生说话了。

27.一同学问我,软件外包是什么。解释了几句还没明白,遂想了一下:包工头知道吧?顿悟!

28.正在码代码ing,医院回来的同事一脸的苦逼样子,问他怎么了?他回答:得了类风湿性关节炎了,我怕会遗传给下一代啊。我一脸的问号:谁说类风湿性关节炎能遗传的?丫一脸诧异:类不是继承的吗?

29.真的勇士,敢于直面惨淡的warning、敢于正视淋漓的error。

30.某小偷潜入某IT公司欲行窃,没想到始终有人,他只好等啊等啊等,结果始终有一大拨人在加班。过了一个月,小偷终于逮到机会溜出来,同伙问:去哪了?小偷:在IT公司呆了一个月。同伙:收获不错吧?小偷苦笑:别TM提了,三十个大夜下来,我现在已经学会写程序了。

31.一同事最近bug特别多,假装关切问他有多少个bug,他回答:10。过几日,再问,他回答:10。我:”这么多天过去了,怎么一点变化都没有?”,他:”哪里没有变化啊,以前是十进制,现在变成十六进制。

32.我很奇怪客栈这个词。难道后入住的必须先退房吗?

33.假如生活欺骗了你,找50个程序员问问为什么编程;假如生活让你想死,找50个程序员问问BUG改完了没有;假如你觉得生活拮据,找50个程序员问问工资涨了没有;假如你觉得活着无聊,找50个程序员问问他们一天都干了什么!

34.话说,决定一个程序员跳槽与否的关键因素是他前同事的现工资~

35.程序员最憋屈的事情就是:你辛辛苦苦熬夜写了一个风格优雅的源文件,被一个代码风格极差的同事改了且没署名,以至于别人都以为你是写的。。。

36.昨天晚上做梦梦见我得到了九阴真经的武功秘籍,打开第一页一看,我X,赫然写着口诀”hello world!”

37.前端工程师说,我去交友网站找女朋友去了。朋友问,找到了么?工程师说,找到了他们页面的一个bug……

38.十年生死两茫茫,百度兴,谷歌亡。微博火,推特无处话凄凉。纵使相逢应不识,MSN死,微信狂。人人佳缘喜还乡,京东刘,泡妞强。淘宝在,海淘忙。视频互相打,论坛靠色狼,陌陌帮上床。聊到马云断肠处,余额宝,怕是活不长。

39.程序员被叫去修电脑,正确的回答方式是:『哦,不好意思啊,我是一个程序员,我并不会修电脑,我其实只会把电脑搞出问题来,老实说,你电脑上的这些问题都是我们程序员搞出来的』

40.时至今日都是我咎由自取,找不到对象就是找不到对象,与任何人无关。程序员生涯的苦文明用语,造就了我娇羞内向,不问红尘的脾气,导致今日岌岌可危的地步,我今天愿意承担一切后果。其实,我很感谢你们让我跌倒在今天,而不是在我依旧文明用语丝的将来,我必须重新梳理自己,坦然面对并修复bug!本码农,生活中写就了一段满是bug的代码,我辜负了老板和老板的老板

41.我应聘了一个大型IT公司的”网络攻击研究部经理” 职务, 面试官问我: 你觉得自己为什么适合这份工作? 我: 我黑进你们的系统, 给我自己发了面试通知.

42.老婆让我教她编程,想看看网页是怎么做的,于是我教她用JQuery, PHP 做些简单的小程序。在动手写出些Hello World的小程序后,老婆说:”编程也不是很难嘛,但是你们这些程序员太装逼了,无论前端还是后端的程序,代码里到处都是”$”,你们是想钱想疯了是吧?

43.有个学生在人人发状态:”找不到对象找不到对象找不到对象找不到对象找不到对象”。我回复:”请确定该对象存在,并正确拼写其名称和路径名”。另一个学生回复:”真的无法获取对象就去声明一个基类吧!

44.昨晚梦见男朋友和别的女人在逛街,梦里我的第一反应是查源代码…结果调试半天查不出来为什么显示的是那个女人不是我,最后含泪把那个女人给注释掉了,再一运行就是我男朋友自己逛街了…醒来囧字脸呆了很久…囧rz

45.一个合格的程序员是不会写出 诸如 “摧毁地球” 这样的程序的,他们会写一个函数叫 “摧毁行星”而把地球当一个参数传进去。

46.如果你的朋友是it民工的,年底吃饭聚餐就不要AA制了,你请他吧,主动买单是不错的选择。千万不要当着他的面提年终奖,出国旅游,买房买车等等。生活不易,需要互相扶持前行。

47.设计师看了程序实现出的界面内心百感交集,就像把女儿嫁给了小混混,最后生出了一窝小流氓似的。

48.真正的程序员喜欢兼卖爆米花,他们利用CPU散发出的热量做爆米花,可以根据米花爆裂的速度听出正在运行什么程序。

49.祝大家在以后的日子里. 男生象Oracle般健壮; 女生象win7般漂亮; 桃花运象IE中毒般频繁; 钱包如Gmail容量般壮大, 升职速度赶上微软打补丁 , 追女朋友像木马一样猖獗, 生活像重装电脑后一样幸福, 写程序敲代码和聊天一样有激情。

50.老板说了一个笑话,全办公室哄堂大笑,有抹眼泪的,有捂肚子的,有捶桌子的。只有小猿没笑,我边笑边问他:你怎么不笑呀?他说:我已经辞职了!

51.程序员最讨厌的四件事:写注释、写文档、别人不写注释、别人不写文档 …

52.一个士兵爱上一个公主,公主告诉他,如果他愿意连续100个晚上守在她的阳台下,她就接受他。于是士兵照做了,他等了一天,两天,三天……直到第九十九天,士兵离开了。为什么士兵不再坚持最后一天?答案很凄美——因为那个士兵是程序员,他从0开始数的.

53.一晚下班回家,一民警迎面巡逻而来。突然对我大喊:站住!

民警:int类型占几个字节?
我:4个。
民警:你可以走了。
我感到很诧异。
我:为什么问这样的问题?
民警:深夜还在街上走,寒酸苦逼的样子,不是小偷就是程序员……

SQL Server——自定义的fn_Split函数

修正SQL2000超长ntext的bug。

CREATE FUNCTION [dbo].[Fn_split] (@expression NTEXT,
                                  @delimiter  NVARCHAR(2) = ',')
RETURNS @expressionstable TABLE (
  [DUMMY] NVARCHAR(4000))
AS
  BEGIN
      DECLARE @currentindex INT
      DECLARE @nextindex INT
      DECLARE @returntext NVARCHAR(4000)
      DECLARE @datalength INT
      IF @expression IS NULL
        BEGIN
            INSERT INTO @expressionstable
                        ([DUMMY])
            VALUES      (NULL)
        END
      ELSE
        BEGIN
            SELECT @datalength = Datalength(@expression) / 2
            IF @datalength = 0
              INSERT INTO @expressionstable
                          ([DUMMY])
              VALUES      ('')
            ELSE
              BEGIN
                  SELECT @currentindex = 1
                  WHILE( @currentindex <= @datalength )
                    BEGIN
                        SELECT @nextindex = Charindex(@delimiter, Substring(@expression, @currentindex, 4000))
                                            + @currentindex
                        /*关键在于Charindex第二个参数最长为8000,所以每次需重新截取下一部分*/
                        IF( @nextindex = @currentindex )
                          SELECT @nextindex = @currentindex + @datalength
                        SELECT @returntext = Substring(@expression, @currentindex - 1, @nextindex - @currentindex)
                        INSERT INTO @expressionstable
                                    ([DUMMY])
                        VALUES      (@returntext)
                        SELECT @currentindex = @nextindex + 1
                    END
              END
        END
      RETURN
  END
CREATE FUNCTION [dbo].[Fn_split] (@str       VARCHAR(MAX),
                                  @separator VARCHAR(10))
RETURNS TABLE
AS
    RETURN
      (SELECT T0.DUMMY
       FROM   ( (SELECT [DUMMY] = CONVERT(XML, '<DUMMY>'
                                             + Replace(@str, @separator, '</DUMMY><DUMMY>')
                                             + '</DUMMY>')) T1
                OUTER APPLY (SELECT DUMMY = N.v.value('.', 'NVARCHAR(4000)')
                             FROM   T1.[DUMMY].nodes('/DUMMY') N(v)) T0 ))

用法:

SELECT * FROM fn_split('1,2,3,4,5', ',');

重弹Transact-SQL的随机数

Transact-SQL的随机数主要有:

RAND:返回一个介于 0 到 1(不包括 0 和 1)之间的伪随机 float 值。如果未指定 seed,则 SQL Server 数据库引擎随机分配种子值。 使用同一个种子值重复调用 RAND() 会返回相同的结果。对于一个连接,如果使用指定的种子值调用 RAND(),则 RAND() 的所有后续调用将基于使用该指定种子值的 RAND() 调用生成结果。

NEWID:创建 uniqueidentifier 类型的唯一值。NEWID 对每台计算机返回的值各不相同。

CHECKSUM:返回按照表的某一行或一组表达式计算出来的校验和值,用于生成哈希索引。CHECKSUM 值取决于排序规则。使用不同排序规则存储的相同值将返回一个不同的 CHECKSUM 值。(竟然可以把字符串转为数字!!!)

因为RAND()使用同一个种子值重复调用 RAND() 会返回相同的结果,所以会造成了一个后果,SELECT到所有列全部是同一个值,如果这个值需要同其它值进行计算,那就无法真正的随机了。

此时就需要CHECKSUM(NEWID())甚至RAND(CHECKSUM(NEWID()))出场了。

具体怎么用,多试就知道了。