垃圾回收站

October 16, 2007

男人四十个性感时刻

[ 分类: 情感 ] 由 弗里曼·潘 发表于 1:05 am 评论( 0 )
其实,很多男人并不知道自己在生活中也会有性感的一刻。在异性突然被击中而心动不已的时候,他还是那么自然地以他惯常的姿态侃侃而谈,而他自己并不知道。现在,让我们告诉男人们,女人所定格的几个男人让她们迷恋的性感瞬间,并最终被他所征服呢–


  1.不说话的时候。
  
  沉默但目光专注地看你说话的男人,一定内心丰富,女孩最心仪这一刻的男人,因为他身上似乎有一种至命的磁场,让你觉得他酷极了。
  
  2.含着半口饮料微笑。
  
  为了回应你,他哪怕嘴里含着咖啡或者美酒,也不急着咽下,先反馈给你一个积极友好的笑容,这样尊重女性的绅士举止,当然会让你心头顿生暖意与好感。
  
  3.果决而内疚地摁灭烟头。
  
  只是因为你的出现,正在抽烟的他,立即用这一动作欢迎你,无声,但那动作非常男性化,这比为你脱外套拉椅子,更贴心也更有说服力。
  
  4.”我干,你随意”。
  
  酒桌上说这话的男人,豪爽,但不乏柔情,非常善解人意,仿佛可以为你赴汤蹈火,但背影一点也不冰冷。
  
  5.”不要在风口接电话”。
  
  他在街头用手机给远方的女友打电话时说了这么一句话,风吹着他的脸,他眯着的眼,很迷人吧!
  
  6.一下子强有力地把你拽到怀里。
  
  一切不容置疑,男人的霸气通过一种温暖的手段淋漓尽致地表现出来,你绝对拒绝不了。
  
  7.镜子子前拉一下领带。
  
  这时的男人很认真,而且有种片刻的孩子气,这很会激发女性的温存欲望。
  
  8.下楼时吹了口哨。
  
  那是一小节美妙但已成他记忆一部分的旋律,女性喜欢考究男人的唇齿,而那一刻,他会满足你的。
  
  9.无辜地耸耸肩膀。
  
  女人喜欢看男人这时的身体语言,每一个细节都令你怜惜疼爱。
  
  10.嚼口香糖
  
  嚼口香糖的男人,有些玩世不恭,特别是NBA的球星,总是忙里偷闲地嚼着口香糖,一种无所谓的感觉,带点男人的”痞”。
  
  11.在海滩上躺着晒太阳的男人。
  
  古胴色皮肤,迷离的双眼,你是不是有种”活埋”他的冲动?
  
  12.突然把车开到你身边,摇下车窗对你笑,这是许多浪漫故事的开头。
  
  13.在寒风中不停跳着等人,双手插在口袋里,领子高高竖起。这一刻,你是否希望你就是他要等的人。
  
  14.弯腰轻抚一只摇尾巴的狗。
  
  有爱心的男人,看起来特别舒服。
  
  15.双手从背后变出一朵玫瑰的时候,你一定会认为他是最好的魔术师。也许他改变不了风向,但可以改变你的心情。
  
  16.他顽皮地跑,因为他手里拿着你吃剩的蛋糕,他总喜欢分享你的剩菜。
  
  17.他做俯卧撑的时候,脸上都是性感的汗珠。很有男人味。
  
  18.抱着篮球向你走来。
  
  19.就职演说前的停顿,目光扫视全场。
  
  大气的男人,很有慑服力。
  
  20.坏坏地注视着你,光明正大地暖昧。
  
  这种目光恭维,是种深刻的激光式的抚摸。
  
  21.灿烂地笑,关键是露出两排洁白清新的牙齿。
  
  女人的唇,男人的齿,都是性感利器。
  
  22.额纹,这是思考或疑问时的皱纹,35岁以上男人,如果没有额纹,那就是如同外婆没有白发。眉宇处如果有个昂扬的”川”字,那就更有内容了。
  
  23.奔跑或大步流星。
  
  因为豪迈,也是自信。
  
  24.男人刮胡子时。
  
  白色泡沫,非常有遐想空间,青亮的下巴,如果还有美人沟的话,那是种会让女人发出尖叫的性感。
  
  25.正在换灯泡或钉钉子的男人。
  
  动手能力强的男人,有种让踏实的感觉。
  
  26.教孩子读书弹琴的时候(正式教师除外)。
  
  所以许多贵夫人会与其孩子的钢琴教师发生不伦之恋,原因就在此。
  
  27.摘下手套与你握手,热情,但手心不湿。
  
  28.愉快地答应你去摘星或赴汤蹈火的时候。
  
  29.扔掉自己外套,几乎是扑向你的时候。
  
  30.男人快速做出决定的时候。
  
  女人最怕男人拖泥带水,当然,床上活动除外。
  
  31.男人戴安全帽的时候。一种奇怪的俊朗。
  
  32.接吻的男人。
  
  那一刻有种贪婪的魅力,仿佛要一手遮天,独吞天下。
  
  33.单手持枪射击的男人。
  
  如果他是光头,效果会更好。
  
  34.自嘲,而且会让你一笑。
  
  35.穿着一条不用皮带的牛仔裤,当然,腹肌要发达。
  
  36.咬紧牙关的时候,那是一张充满张力的刚毅的脸。
  
  ”用力”是男人的”第三”性征。
  
  37. 好心地勾引你的时候。
  
  不会勾引的男人是残缺的。
  
  38. 亢奋得发抖到缺氧的男人。
  
  这时,你一定会产生一种崇高理想:为他灭火!
  
  39. 他打赌,他又输了,这一刻,他非常可爱,他是你胜利的成果。
  
  同女人打赌,明智的男人都会选择输。
  
  40. 说他并不爱你的时候,这份魅力,最具毒性,小心为是。

字符串的驻留(String Interning)

[ 分类: .NET ] 由 弗里曼·潘 发表于 12:23 am 评论( 0 )

  关于字符串的驻留的机制,对于那些了解它的人肯定会认为很简单,但是我相信会有很大一部分人对它存在迷惑。在开始关于字符串的驻留之前,先给出一个有趣的Sample:

static void Main(string[] args)
{
string str1 = “ABCD1234″;
string str2 = “ABCD1234″;
string str3 = “ABCD”;
string str4 = “1234″;
string str5 = “ABCD” + “1234″;
string str6 = “ABCD” + str4;
string str7 = str3 + str4;

Console.WriteLine(”string str1 = \”ABCD1234\”;”);
Console.WriteLine(”string str2 = \”ABCD1234\”;”);
Console.WriteLine(”string str3 = \”ABCD\”;”);
Console.WriteLine(”string str4 = \”1234\”;”);
Console.WriteLine(”string str5 = \”ABCD\” + \”1234\”;”);
Console.WriteLine(”string str6 = \”ABCD\” + str4;”);
Console.WriteLine(”string str7 = str3 + str4;”);

Console.WriteLine(”\nobject.ReferenceEquals(str1, str2) = {0}”, object.ReferenceEquals(str1, str2));
Console.WriteLine(”object.ReferenceEquals(str1, \”ABCD1234\”) = {0}”, object.ReferenceEquals(str1, “ABCD1234″));

Console.WriteLine(”\nobject.ReferenceEquals(str1, str5) = {0}”, object.ReferenceEquals(str1, str5));
Console.WriteLine(”object.ReferenceEquals(str1, str6) = {0}”, object.ReferenceEquals(str1, str6));
Console.WriteLine(”object.ReferenceEquals(str1, str7) = {0}”, object.ReferenceEquals(str1, str7));

Console.WriteLine(”\nobject.ReferenceEquals(str1, string.Intern(str6)) = {0}”, object.ReferenceEquals(str1, string.Intern(str6)));
Console.WriteLine(”object.ReferenceEquals(str1, string.Intern(str7)) = {0}”, object.ReferenceEquals(str1, string.Intern(str7)));
}

 接下来我们来逐句地分析这段代码:

string str1 = “ABCD1234″;
string str2 = “ABCD1234″;
object.ReferenceEquals(str1, str2)= True;
object.ReferenceEquals(str1, “ABCD1234″)) = True;


  首先我们创建了两个完全相同的字符串(ABCD1234),并将他们分别赋予了两个字符创变量–str1和str2.然后把它们传给了 object.ReferenceEquals.我们知道object.ReferenceEquals是用于确定两个变量是否具有相同的引用–换句话说,当两个变量引用的是同一块托管推的内存快的时候,返回True,否则返回False.

  令我们感到奇怪的是,当我们分别创建的引用类型两个变量–string是引用类型。照理说CLR会在托管堆(Managed Heap)中为它们分配两段内存快,他们不可能具有相同的引用才对,但是为什么object.ReferenceEquals 方法会返回True呢。而对于第二个比较–一个字符串变量和一个和他具有相同内容的字符串(”ABCD1234″;)直接进行比较,按照我们对CLR内存的分配的一般理解,应该是CLR首先会在托管堆中为这段字符串(”ABCD1234″)分配内存快,然后把相对应的引用传递给 object.ReferenceEquals方法(由于分配在托管堆的这段字符串并没有被任何变量引用,所以当垃圾回收的时候会被回收掉),所以无论如何也不应该返回True.

  我们先把问题留到最后,接着分析我们的Sample.上面们对字符串变量之间以及变量与字符串之间进行了比较,如果我们对一个字符串变量和一个动态创建的字符串(通过+Operator把两个字符串连接起来)进行比较,结果又会如何呢?我们来看看下面的伪代码演示:

string str3 = “ABCD”;
string str4 = “1234″;
string str5 = “ABCD” + “1234″;
string str6 = “ABCD” + str4;
string str7 = str3 + str4;
object.ReferenceEquals(str1, str5) = True
object.ReferenceEquals(str1, str6) = False
object.ReferenceEquals(str1, str7)) = False


  在上面的例子中,我们用三种不同的方式创建了3个字符串变量(str5,str6,str7)–string+string;string+ variable;variable+variable.然后分别和我们已经创建的、和它们具有相同字符串”值”的变量(str1)作比较。同样令我们感到奇怪的是第一个返回True,而后两个则为False.带着这些疑惑我们来看看对于string这一特殊的类型说采用的特殊的使用机制。

  1. System.String虽然是一个引用类型,但是它具有其自身的特殊性。我们最容易想到的是它创建的特殊性–一般的对象在创建的时候需要通过new 关键字调用对应的构造函数来实现;而创建一段string不需要这么做–我们只需要把对应的字符换赋给给对应的字符串变量就可以了。之所以存在着这种差异,是因为他们在创建过程中使用的IL指令时不同的–一般的引用对象的创建是通过newobj这样一个IL指令来实现的,而创建一个字符串变量的IL指令则是ldstr (load string)。(象C#,VB.NET这样的语言毕竟是高级语言,进行了高度的抽象,站在这样的角度分析问题往往不能够看到其实质,所以有时候我们把应该从交底层上面找突破口–比如分析IL,Metadata…);

 2.由于String是我们做到频率最高的一种类型,CLR考虑性能的提升和内存节约上,对于相同的字符串,一般不会为他们分别分配内存块,相反地,他们会共享一块内存。

CLR实际上采用这个的机制来实现的:CLR内部维护着一块特殊的数据结构–我们可以把它看成是一个Hash table,这个Hash table维护者大部分创建的string(我这里没有说全部,因为有特例)。这个Hash table的Key对应的相应的string本身,而Value则是分配给这个string的内存块的引用。当CLR初始化的时候创建这个Hash table.一般地,在程序运行过程中,如果需要的创建一个string,CLR会根据这个string的Hash Code试着在Hash table中找这个相同的string,如果找到,则直接把找到的string的地址赋给相应的变量,如果没有则在托管堆中创建一个string,CLR 会先在managed heap中创建该strng,并在Hash table中创建一个Key-Value Pair–Key为这个string本身,Value位这个新创建的string的内存地址,这个地址最重被赋给响应的变量。这样我们就能解释上面的疑问了。

string str1 = “ABCD1234″;
string str2 = “ABCD1234″;
object.ReferenceEquals(str1, str2)= True;
object.ReferenceEquals(str1, “ABCD1234″)) = True;


  当创建str1的时候,CLR现在我们上面提到的Hash table中找”ABCD1234″这样的一个string,没有找到,则在托管堆中为这个string分配一块内存,然后在Hash table为该string添加一个Key-Value Pair.接着创建str2,CLR仍然会在Hash table找ABCD1234这样的一个string,这回它会找到我们新创建的这个Entry,所以这个Key-Value Pair中Value(string的地址)会赋给str2.因为str1和str2 具有相同的引用,所以调用object.ReferenceEquals返回True.同理当我们对str1和”ABCD1234″进行比较的时候, str1直接传入该方法,放传入”ABCD1234″这个字符串的时候,CLR同样会在Hash table找ABCD1234这样的一个string,相同的Entry被找到,这个Entry(Key-Value Pair)的Value(string的地址)被传到object.ReferenceEquals,所以他们仍然相同的引用,结果返回True.

  3.并非所有的情况下字符串的驻留都会起作用。对于对一个动态创建的字符串(比如string+variable;variable+variable),这种驻留机制便不会起作用。因为对于这样的字符串,是不会被添加到内部的Hash table中的。但是对于string+string则不同,因为当这样的语句被编译成IL的时候,编译器是先把结构计算出来,然后再调用ldstr指令 –而对于string+variable;variable+variable这种情况,所对应的IL指令是Concat.所以对于string+ string字符串的驻留仍然有效。

  比如对于以下一段代码:

static void Main(string[] args)
{
string str1 = “ABC”;
string str2 = str1 + “123″;
string str3 = “ABC” + “123″;
}


  对应的IL Code是:

.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 26 (0×1a)
.maxstack 2
.locals init ([0] string str1,
[1] string str2,
[2] string str3)
IL_0000: nop
IL_0001: ldstr “ABC”
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldstr “123″
IL_000d: call string [mscorlib]System.String::Concat(string,
string)
IL_0012: stloc.1
IL_0013: ldstr “ABC123″
IL_0018: stloc.2
IL_0019: ret
} // end of method Program::Main


  所以现在我们就可以解释第二个疑问了。

  虽然对于对一个动态创建的字符串(比如string+variable;variable+variable),驻留机制便不会起作用。但是我们可以手工的启用驻留机制–那就是调用定义的System.String中的静态方法Intern.这个方法接受一个字符串作为他的输入参数,返回的经过驻留处理的string.他的实现机制是:如果能在内部的Hash Table中找到传入的string,则返回对应的string引用,否则就在Hash Table添加该string对应的Entry,并返回string的引用。所以下面的代码就不难解释了。

Console.WriteLine(”\nobject.ReferenceEquals(str1, string.Intern(str6)) = {0}”, object.ReferenceEquals(str1, string.Intern(str6)));
Console.WriteLine(”object.ReferenceEquals(str1, string.Intern(str7)) = {0}”, object.ReferenceEquals(str1, string.Intern(str7)));