<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CLURIES</title>
	<atom:link href="http://cdbit.com/feed" rel="self" type="application/rss+xml" />
	<link>http://cdbit.com</link>
	<description>程序员、宅男、数码产品深度中毒者</description>
	<lastBuildDate>Sun, 08 Apr 2012 03:13:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>说说TCP中的TIME_WAIT状态</title>
		<link>http://cdbit.com/read/talk-about-the-time_wait-state-in-tcp.html</link>
		<comments>http://cdbit.com/read/talk-about-the-time_wait-state-in-tcp.html#comments</comments>
		<pubDate>Sat, 31 Mar 2012 15:15:02 +0000</pubDate>
		<dc:creator>cluries</dc:creator>
				<category><![CDATA[Network]]></category>
		<category><![CDATA[TCP]]></category>
		<category><![CDATA[TIME_WAIT]]></category>
		<category><![CDATA[状态]]></category>
		<category><![CDATA[状态转换]]></category>

		<guid isPermaLink="false">http://cdbit.com/?p=119</guid>
		<description><![CDATA[状态的形成 TIME_WAIT是一个比较纠结的状态:有三个状态可以转换成为它,分别是FIN_WAIT_1 、 FIN_WAIT_2和CLOSING. 1:由FIN_WAIT_1进入TIME_WAIT状态 在FIN_WAIT_1状态时候,收到了对方同时带FIN标志和ACK标志的报文时，那么将会发送ACK,同时直接进入到TIME_WAIT状态，而无须经过FIN_WAIT_2状态。 2:由FIN_WAIT_2进入TIME_WAIT状态 在FIN_WAIT状态时候,接收到对方的FIN标志报文,那么将会发送ACK报文,同时进入TIME_WAIT状态. 3:由CLOSING进入TIME_WAIT状态 CLOSING这种状态比较特殊，实际情况中应该是很少见，属于一种比较罕见的例外状态。这种情况下只要接收到了对方发送的ACK,那么将会进入TIME_WAIT状态. &#160; 状态的作用 UNP上的对TIME_WAIT状态存在的理由列举有2条: 可靠的实现TCP全双工连接的终止 允许老的重复分节在网络中消逝 怎么解释TIME_WAIT状态可以可靠的实现TCP全双工连接的终止呢. 假设LAST_ACK丢失,被动关闭的一方将会重新发送他的最后的FIN,因此主动关闭的一方必须维护状态信息,用来允许它重新发送LAST_ACK.不然将会响应RST,而这个分解将会被被动关闭的一方解释为一个错误.如果TCP打算执行所有必要的工作来彻底终止两个方向上的数据流,他就必须正确处理连接终止序列4个分解中任何一个分节丢失的状况. 第二个理由,允许老的重复分节在网络中消逝. 假设某2个台机器在某端口之间已经建立了一个TCP连接,我们先关闭这个连接,一段时间以后,我们要在这2台机器上相同的端口重新建立一个连接,那么这个新建立的连接就是上一个连接的化身. TCP必须防止某个连接的老的重复分组在这个连接已经终止后重新出现,从而被误解成为属于同一个连接的某个新的化身. 为了做到这点,TCP将不给处于TIME_WAIT状态的连接发起新的化身.因为TIME_WAIT的状态持续时间一般为MSL的2倍,那么就足以让某个方向上的分组最多存活MSL后被丢弃,另外一个方向上的应答最多存活MSL后也被丢弃. 这样,我们就能保证每次成功建立一个TCP连接时,来自该连接先前化身的老的重复分组都已经消逝于网络中了.]]></description>
			<content:encoded><![CDATA[<h3><strong>状态的形成</strong></h3>
<p>TIME_WAIT是一个比较纠结的状态:有三个状态可以转换成为它,分别是FIN_WAIT_1 、 FIN_WAIT_2和CLOSING.</p>
<h4>1:由FIN_WAIT_1进入TIME_WAIT状态</h4>
<p>在FIN_WAIT_1状态时候,收到了对方同时带FIN标志和ACK标志的报文时，那么将会发送ACK,同时直接进入到TIME_WAIT状态，而无须经过FIN_WAIT_2状态。</p>
<h4>2:由FIN_WAIT_2进入TIME_WAIT状态</h4>
<p>在FIN_WAIT状态时候,接收到对方的FIN标志报文,那么将会发送ACK报文,同时进入TIME_WAIT状态.</p>
<h4>3:由CLOSING进入TIME_WAIT状态</h4>
<p>CLOSING这种状态比较特殊，实际情况中应该是很少见，属于一种比较罕见的例外状态。这种情况下只要接收到了对方发送的ACK,那么将会进入TIME_WAIT状态.</p>
<p>&nbsp;</p>
<h3><strong>状态的作用</strong></h3>
<p>UNP上的对TIME_WAIT状态存在的理由列举有2条:</p>
<blockquote>
<ul>
<li>可靠的实现TCP全双工连接的终止</li>
<li>允许老的重复分节在网络中消逝</li>
</ul>
</blockquote>
<p>怎么解释TIME_WAIT状态可以可靠的实现TCP全双工连接的终止呢.</p>
<p>假设LAST_ACK丢失,被动关闭的一方将会重新发送他的最后的FIN,因此主动关闭的一方必须维护状态信息,用来允许它重新发送LAST_ACK.不然将会响应RST,而这个分解将会被被动关闭的一方解释为一个错误.如果TCP打算执行所有必要的工作来彻底终止两个方向上的数据流,他就必须正确处理连接终止序列4个分解中任何一个分节丢失的状况.</p>
<p>第二个理由,允许老的重复分节在网络中消逝.</p>
<p>假设某2个台机器在某端口之间已经建立了一个TCP连接,我们先关闭这个连接,一段时间以后,我们要在这2台机器上相同的端口重新建立一个连接,那么这个新建立的连接就是上一个连接的化身.</p>
<p>TCP必须防止某个连接的老的重复分组在这个连接已经终止后重新出现,从而被误解成为属于同一个连接的某个新的化身.</p>
<p>为了做到这点,TCP将不给处于TIME_WAIT状态的连接发起新的化身.因为TIME_WAIT的状态持续时间一般为MSL的2倍,那么就足以让某个方向上的分组最多存活MSL后被丢弃,另外一个方向上的应答最多存活MSL后也被丢弃.</p>
<p>这样,我们就能保证每次成功建立一个TCP连接时,来自该连接先前化身的老的重复分组都已经消逝于网络中了.</p>
]]></content:encoded>
			<wfw:commentRss>http://cdbit.com/read/talk-about-the-time_wait-state-in-tcp.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>换个思路实现iOS的密码解锁界面</title>
		<link>http://cdbit.com/read/change-way-to-realize-ios-password-unlock-interface.html</link>
		<comments>http://cdbit.com/read/change-way-to-realize-ios-password-unlock-interface.html#comments</comments>
		<pubDate>Fri, 24 Feb 2012 01:08:40 +0000</pubDate>
		<dc:creator>cluries</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[UITextField]]></category>
		<category><![CDATA[UITextFieldDelegate]]></category>
		<category><![CDATA[思路]]></category>
		<category><![CDATA[界面]]></category>
		<category><![CDATA[解锁]]></category>

		<guid isPermaLink="false">http://cdbit.com/?p=86</guid>
		<description><![CDATA[一个耽搁了很长时间的项目，断断续续做了半年了吧，期间太多事情，二周都不写一句代码的事情经常出现，对这个项目的前景也越来越不看好。不过想到自己做了太多的半途而废的项目，不管怎么样，这个项目还是咬咬牙坚持下去吧。 于是，就这么一直坚持下来了，虽然现在时间更忙了，基本下班后就没时间写代码什么的。 最近，做到一个需要输入解锁密码的功能。 最开始想法是通过UITextFieldDelegate来实现，先回顾UITextFieldDelegate的定义： Managing Editing – textFieldShouldBeginEditing: – textFieldDidBeginEditing: – textFieldShouldEndEditing: – textFieldDidEndEditing: Editing the Text Field’s Text – textField:shouldChangeCharactersInRange:replacementString: – textFieldShouldClear: – textFieldShouldReturn: OK，看到这些，基本上是可以做出想要的效果了。 不过在实际的开发中，发现没那么简单，做出来的东西总不对，总是有问题不好解决。 然后又想到去监视键盘事件，不过觉得这样做会更麻烦。 正在烦躁中突然想到一个办法，把四个密码输入框的enable设置为NO，真正的密码输入的TextField其实是一个大小为0的不可见的一个TextField，然后每次输入一个字符后把响应的字符赋值到4个密码框中的一个，让看起来是输入到四个密码框中。 部分粗略代码如下： -(void) setTextFieldStyle:(UITextField*) textField { [textField setBorderStyle:UITextBorderStyleRoundedRect]; [textField setFont:[UIFont systemFontOfSize:32]]; [textField setTextAlignment:UITextAlignmentCenter]; textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter; textField.keyboardType = UIKeyboardTypeNumberPad; textField.secureTextEntry = YES; textField.enabled = NO; } -(BOOL) [...]]]></description>
			<content:encoded><![CDATA[<p>一个耽搁了很长时间的项目，断断续续做了半年了吧，期间太多事情，二周都不写一句代码的事情经常出现，对这个项目的前景也越来越不看好。不过想到自己做了太多的半途而废的项目，不管怎么样，这个项目还是咬咬牙坚持下去吧。</p>
<p>于是，就这么一直坚持下来了，虽然现在时间更忙了，基本下班后就没时间写代码什么的。</p>
<p>最近，做到一个需要输入解锁密码的功能。</p>
<p>最开始想法是通过UITextFieldDelegate来实现，先回顾UITextFieldDelegate的定义：</p>
<pre class="code">
Managing Editing
– textFieldShouldBeginEditing:
– textFieldDidBeginEditing:
– textFieldShouldEndEditing:
– textFieldDidEndEditing:
Editing the Text Field’s Text
– textField:shouldChangeCharactersInRange:replacementString:
– textFieldShouldClear:
– textFieldShouldReturn:
</pre>
<p>OK，看到这些，基本上是可以做出想要的效果了。</p>
<p>不过在实际的开发中，发现没那么简单，做出来的东西总不对，总是有问题不好解决。</p>
<p>然后又想到去监视键盘事件，不过觉得这样做会更麻烦。</p>
<p>正在烦躁中突然想到一个办法，把四个密码输入框的enable设置为NO，真正的密码输入的TextField其实是一个大小为0的不可见的一个TextField，然后每次输入一个字符后把响应的字符赋值到4个密码框中的一个，让看起来是输入到四个密码框中。</p>
<p>部分粗略代码如下：</p>
<pre>
-(void) setTextFieldStyle:(UITextField*) textField
{
    [textField setBorderStyle:UITextBorderStyleRoundedRect];
    [textField setFont:[UIFont systemFontOfSize:32]];
    [textField setTextAlignment:UITextAlignmentCenter];
    textField.contentVerticalAlignment	= UIControlContentVerticalAlignmentCenter;
    textField.keyboardType 		= UIKeyboardTypeNumberPad;
    textField.secureTextEntry 		= YES;
    textField.enabled 			= NO;
}

-(BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (range.location > 3) {
        m_erLabel.hidden = YES;
        return  NO;
    }         

    UITextField* field = (UITextField*)[self.view viewWithTag:(IPUT_TAG_ONE + range.location)];
    field.text 	       = string;
    m_erLabel.hidden   = YES;
    if (3 == range.location &#038;&#038; ![string isEqualToString:@""]) {
		NSString inputPassword = [textField.text stringByAppendingString:string];
		m_erLabel.hidden = NO;
		[self verify];
    }

    return YES;
}

-(void) textFieldDidBeginEditing:(UITextField *)textField
{
    textField.text = @"";
}

-(void) becomeFirst
{
    [self setIsAtFirstView:YES];
    [self clearAllInput];
    m_erLabel.hidden = YES;

    [m_trueInput becomeFirstResponder];
}
</pre>
<p>这样，一个简单的密码输入解锁界面就OK了。比开始的思路实现简单很多。</p>
<p>&#8211;EOF</p>
]]></content:encoded>
			<wfw:commentRss>http://cdbit.com/read/change-way-to-realize-ios-password-unlock-interface.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>升级VPS上的Nginx、PHP版本</title>
		<link>http://cdbit.com/read/upgrade-nginx-and-php-version-on-vps.html</link>
		<comments>http://cdbit.com/read/upgrade-nginx-and-php-version-on-vps.html#comments</comments>
		<pubDate>Thu, 16 Feb 2012 14:37:31 +0000</pubDate>
		<dc:creator>cluries</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[configure参数]]></category>
		<category><![CDATA[eAccelerator]]></category>
		<category><![CDATA[Linxu]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[vps]]></category>
		<category><![CDATA[扩展]]></category>

		<guid isPermaLink="false">http://cdbit.com/?p=82</guid>
		<description><![CDATA[今天又搞到一个VPS(大笑)。 在搭建必要的环境的时候突然想起自己博客所在的VPS所用Nginx和PHP版本都比较老了，正好前不久PHP又爆出一个很严重的&#8221;Hash冲突拒绝服务攻击的&#8221;漏洞，于是想升级到最新的版本。 PHP的升级要稍微麻烦一些，首先要找到配置目前的 PHP 的 ./configure的参数，根据PHP官方文档的方法，这个参数可以用下面方式获取： http://www.php.net/manual/zh/faq.build.php#faq.build.upgrade 要么在你当前的 PHP 的安装目录查看 config.nice 文件，如果没有，只要运行此脚本： phpinfo(); 在输出的顶端显示了用来配置此 PHP 的 ./configure参数。 不过个人觉得这个方法获取到的 configure参数是不完整的，不过还好我当初保存了 configure的参数，就为了方便以后升级。 PHP configure后直接make 和 make install后就可以完成升级，配置文件因为以前配置了，所以也不用去管，不过一些扩展如eAccelerator需要重新编译。 扩展的重新编译非常简单，直接切换到以前make的目录，也不用执行phpize了，直接make和make install就完成升级。配置文件和PHP一样，不用理会，直接使用以前的。 Nginx的升级比php简单很多，要确定当前运行的Nginx的 configure参数，运行下面的命令就可以得到。感谢twitter上的@vnline和@JavasBoy告诉我这个方法。 nginx -V 使用得到的configure参数配置新版本的代码，然后编译，就可以安装了。不过重新安装之前，需要关闭正在运行中的Nginx。 这样，Nginx和PHP的版本就升级完成了。]]></description>
			<content:encoded><![CDATA[<p>今天又搞到一个VPS(大笑)。</p>
<p>在搭建必要的环境的时候突然想起自己博客所在的VPS所用Nginx和PHP版本都比较老了，正好前不久PHP又爆出一个很严重的&#8221;Hash冲突拒绝服务攻击的&#8221;漏洞，于是想升级到最新的版本。</p>
<p>PHP的升级要稍微麻烦一些，首先要找到配置目前的 PHP 的 ./configure的参数，根据PHP官方文档的方法，这个参数可以用下面方式获取：</p>
<p><a href="http://www.php.net/manual/zh/faq.build.php#faq.build.upgrade" target="_blank">http://www.php.net/manual/zh/faq.build.php#faq.build.upgrade</a></p>
<blockquote><p>
要么在你当前的 PHP 的安装目录查看 config.nice 文件，如果没有，只要运行此脚本：</p>
<p>phpinfo();<br />
在输出的顶端显示了用来配置此 PHP 的 ./configure参数。
</p></blockquote>
<p>不过个人觉得这个方法获取到的 configure参数是不完整的，不过还好我当初保存了 configure的参数，就为了方便以后升级。</p>
<p>PHP configure后直接make 和 make install后就可以完成升级，配置文件因为以前配置了，所以也不用去管，不过一些扩展如eAccelerator需要重新编译。</p>
<p>扩展的重新编译非常简单，直接切换到以前make的目录，也不用执行phpize了，直接make和make install就完成升级。配置文件和PHP一样，不用理会，直接使用以前的。</p>
<p>Nginx的升级比php简单很多，要确定当前运行的Nginx的 configure参数，运行下面的命令就可以得到。感谢twitter上的@vnline和@JavasBoy告诉我这个方法。</p>
<pre class="code">
nginx -V
</pre>
<p>使用得到的configure参数配置新版本的代码，然后编译，就可以安装了。不过重新安装之前，需要关闭正在运行中的Nginx。</p>
<p>这样，Nginx和PHP的版本就升级完成了。</p>
]]></content:encoded>
			<wfw:commentRss>http://cdbit.com/read/upgrade-nginx-and-php-version-on-vps.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>C语言的sizeof和#pragma pack</title>
		<link>http://cdbit.com/read/c-sizeof-and-pragma-pack.html</link>
		<comments>http://cdbit.com/read/c-sizeof-and-pragma-pack.html#comments</comments>
		<pubDate>Thu, 09 Feb 2012 16:37:14 +0000</pubDate>
		<dc:creator>cluries</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[sizeof]]></category>
		<category><![CDATA[边界对齐]]></category>

		<guid isPermaLink="false">http://cdbit.com/?p=78</guid>
		<description><![CDATA[今天有人在某QQ群中问下面这个结构体有多大： #pragma pack(4) struct STV { char a; short int b; char c; }; 当时我第一反应是12，不过又总觉得有点不对劲，还是写了段代码测试下，发现结果居然是6. 嗯？6，难道编译器没看到这句话么：#pragma pack(4)？ 但是当我把结构体的定义修改为 #pragma pack(1) struct STV { char a; short int b; char c; }; 后，结果又变成了4，那么#pragma pack是在起作用的。然后又试着改为#pragma pack(8)和#pragma pack(16)，结果还是6. 心中大概有点明白为什么了。 google之，原来对于#pragma pack的处理方式是这样进行的： 当结构体中最长宽度的数据成员的宽度小于 n 时，按该成员宽度对齐； 当最长宽度的数据成员的宽度大于或等于 n 时，按 n 对齐。 结构体STV中成员宽度最大为2，所以当n=4，8，16的时候还是按照宽度2来对齐的。 &#8211;EOF]]></description>
			<content:encoded><![CDATA[<p>今天有人在某QQ群中问下面这个结构体有多大：</p>
<pre class="code">
#pragma pack(4)
struct STV
{
	char a;
	short int b;
	char c;
};
</pre>
<p>当时我第一反应是12，不过又总觉得有点不对劲，还是写了段代码测试下，发现结果居然是6.</p>
<p>嗯？6，难道编译器没看到这句话么：#pragma pack(4)？</p>
<p>但是当我把结构体的定义修改为</p>
<pre class="code">
#pragma pack(1)
struct STV
{
	char a;
	short int b;
	char c;
};
</pre>
<p>后，结果又变成了4，那么#pragma pack是在起作用的。然后又试着改为#pragma pack(8)和#pragma pack(16)，结果还是6.</p>
<p>心中大概有点明白为什么了。</p>
<p>google之，原来对于#pragma pack的处理方式是这样进行的：</p>
<blockquote><p>
<strong>当结构体中最长宽度的数据成员的宽度小于 n 时，按该成员宽度对齐；<br />
当最长宽度的数据成员的宽度大于或等于 n 时，按 n 对齐。</strong>
</p></blockquote>
<p>结构体STV中成员宽度最大为2，所以当n=4，8，16的时候还是按照宽度2来对齐的。</p>
<p>&#8211;EOF</p>
]]></content:encoded>
			<wfw:commentRss>http://cdbit.com/read/c-sizeof-and-pragma-pack.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>我的2011年</title>
		<link>http://cdbit.com/read/the-2011-summary.html</link>
		<comments>http://cdbit.com/read/the-2011-summary.html#comments</comments>
		<pubDate>Tue, 03 Jan 2012 13:24:45 +0000</pubDate>
		<dc:creator>cluries</dc:creator>
				<category><![CDATA[Live]]></category>
		<category><![CDATA[2011]]></category>

		<guid isPermaLink="false">http://cdbit.com/?p=70</guid>
		<description><![CDATA[2011年已经结束，元旦三天假期也已经过去，想想，还是零碎的总结下2011年。 2011年，工作上平均分配给了2个公司，于6月份离职SNSPLUS，进入另外一家公司。 2011年，我的本命年，因为没穿红内裤，损失不小。应该有4W人民币左右，不过还好的是家人朋友自己都身体健康、平平安安，就当舍财消灾了。 2011年，工作又回到C、C++上面来了，重新写C++让我觉得很高兴，年末碰到一个真正的技术上的大牛，虽然相处的时间不多，不过从他身上学会了很多，不光是技术、更多的是作为一个公司员工的心态。 2011年，感情依然没变化，和女朋友依旧是小吵不断，还好还是走过来了。 2011年，依旧月光、年光，每月依旧在固定的时间生活窘迫。 2011年，养了一只古牧，从四月份开始养着，到现在已经8个月了，它也有9月多大了。 2011年，上半年好玩，下半年很累。上半年，每天早上八点多近9点才慢悠悠的起床去上班，下半年，每天早上7点20就要起床然后挤公交。相比下半年真的很苦逼。 2011年，败入数码产品明显不如2010年，倍感欣慰。 2011年，身体貌似不如2010年了，需要锻炼，体重增加了5kg左右，鸭梨开始比山大了&#8230; 2011年，博客被墙，等待大半年不见解封的情况下，开了新的博客，没有导入以前的数据，重新开始。 2011年，该死的外国话还是外国话，没见到进步，这点很操蛋，一度怀疑自己是英语白痴。 2011年，第一次穿羽绒服，看来真的老了，都怕冷了。 2011年，还有很多很多&#8230;&#8230;&#8230;.. &#8211;EOF]]></description>
			<content:encoded><![CDATA[<p>2011年已经结束，元旦三天假期也已经过去，想想，还是零碎的总结下2011年。</p>
<p>2011年，工作上平均分配给了2个公司，于6月份离职SNSPLUS，进入另外一家公司。</p>
<p>2011年，我的本命年，因为没穿红内裤，损失不小。应该有4W人民币左右，不过还好的是家人朋友自己都身体健康、平平安安，就当舍财消灾了。</p>
<p>2011年，工作又回到C、C++上面来了，重新写C++让我觉得很高兴，年末碰到一个真正的技术上的大牛，虽然相处的时间不多，不过从他身上学会了很多，不光是技术、更多的是作为一个公司员工的心态。</p>
<p>2011年，感情依然没变化，和女朋友依旧是小吵不断，还好还是走过来了。</p>
<p>2011年，依旧月光、年光，每月依旧在固定的时间生活窘迫。</p>
<p>2011年，养了一只古牧，从四月份开始养着，到现在已经8个月了，它也有9月多大了。</p>
<p>2011年，上半年好玩，下半年很累。上半年，每天早上八点多近9点才慢悠悠的起床去上班，下半年，每天早上7点20就要起床然后挤公交。相比下半年真的很苦逼。</p>
<p>2011年，败入数码产品明显不如2010年，倍感欣慰。</p>
<p>2011年，身体貌似不如2010年了，需要锻炼，体重增加了5kg左右，鸭梨开始比山大了&#8230;</p>
<p>2011年，博客被墙，等待大半年不见解封的情况下，开了新的博客，没有导入以前的数据，重新开始。</p>
<p>2011年，该死的外国话还是外国话，没见到进步，这点很操蛋，一度怀疑自己是英语白痴。</p>
<p>2011年，第一次穿羽绒服，看来真的老了，都怕冷了。</p>
<p>2011年，还有很多很多&#8230;&#8230;&#8230;..</p>
<p>&#8211;EOF</p>
]]></content:encoded>
			<wfw:commentRss>http://cdbit.com/read/the-2011-summary.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>ASP.NET垃圾？.NET垃圾？</title>
		<link>http://cdbit.com/read/is-asp-net-and-net-bad.html</link>
		<comments>http://cdbit.com/read/is-asp-net-and-net-bad.html#comments</comments>
		<pubDate>Sun, 25 Dec 2011 10:32:44 +0000</pubDate>
		<dc:creator>cluries</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[CSDN]]></category>
		<category><![CDATA[CSharp]]></category>

		<guid isPermaLink="false">http://cdbit.com/?p=65</guid>
		<description><![CDATA[由这次CSDN泄漏用户资料的事件引起，某群中讨论得热火朝天。 这时候，又听到言论： CSDN是ASPX做的，所以ASP.NET真的很垃圾.Net也很垃圾！千万不要用ASP.NET! 上次有黑客兜售网游源码，都是asp.net的。 我很不喜欢这种言论，虽然我不是做.Net的，我一直觉得，技术没有什么垃圾不垃圾，只有你能不能驾驭住、能不能找到它合适的领域。同样的，我也很讨厌语言优劣论，不过这个偏题了，就不说了。 我用过一段时间的C＃，算是个入门者。我同意现在很多ASPX的程序写的问题很多，但是，其他语言的程序出问题的也不少。 ASPX的从业者很多，水平差异也非常大，造成很多人不信任ASPX程序的主要原因我认为是： 一部分的ASPX程序员是从ASPX开始进入程序员生涯的，这部分人有很大一部分呢又是直接使用webform来入门的，当时很多ASPX程序员只知道拖拉控件然后改改属性。于是他们对HTTP协议和特性知道的有限、对ASPX的工作原理模糊不清。 然后呢，当时很多企业大量缺人，于是这部分人也顺利的进入公司工作，企业对代码质量没把关好，于是出现了很多劣质的ASPX程序。也造成很多人对ASPX的恶劣印象。 然后我了解到的情况是：现在这样的情况已经有了很大的改善，很多的ASPX程序员都成长起来了。 所以我认为说ASP.NET很垃圾.Net也很垃圾的言论是一种很没有依据的说法，而且我恰恰认为C＃是一门优雅的语言，他出生比较晚，吸取了很多语言的优点，微软更新得也很勤快。 以上言论只是我一人的看法，我对.NET了解不多，所以如有诸多错误还请海涵。 &#8211;EOF]]></description>
			<content:encoded><![CDATA[<p>由这次CSDN泄漏用户资料的事件引起，某群中讨论得热火朝天。</p>
<p>这时候，又听到言论：</p>
<blockquote><p>CSDN是ASPX做的，所以ASP.NET真的很垃圾.Net也很垃圾！千万不要用ASP.NET!</p>
<p>上次有黑客兜售网游源码，都是asp.net的。</p></blockquote>
<p>我很不喜欢这种言论，虽然我不是做.Net的，我一直觉得，技术没有什么垃圾不垃圾，只有你能不能驾驭住、能不能找到它合适的领域。同样的，我也很讨厌语言优劣论，不过这个偏题了，就不说了。</p>
<p>我用过一段时间的C＃，算是个入门者。我同意现在很多ASPX的程序写的问题很多，但是，其他语言的程序出问题的也不少。</p>
<p>ASPX的从业者很多，水平差异也非常大，造成很多人不信任ASPX程序的主要原因我认为是：</p>
<blockquote><p>一部分的ASPX程序员是从ASPX开始进入程序员生涯的，这部分人有很大一部分呢又是直接使用webform来入门的，当时很多ASPX程序员只知道拖拉控件然后改改属性。于是他们对HTTP协议和特性知道的有限、对ASPX的工作原理模糊不清。</p>
<p>然后呢，当时很多企业大量缺人，于是这部分人也顺利的进入公司工作，企业对代码质量没把关好，于是出现了很多劣质的ASPX程序。也造成很多人对ASPX的恶劣印象。</p></blockquote>
<p>然后我了解到的情况是：现在这样的情况已经有了很大的改善，很多的ASPX程序员都成长起来了。</p>
<p>所以我认为说ASP.NET很垃圾.Net也很垃圾的言论是一种很没有依据的说法，而且我恰恰认为C＃是一门优雅的语言，他出生比较晚，吸取了很多语言的优点，微软更新得也很勤快。</p>
<p>以上言论只是我一人的看法，我对.NET了解不多，所以如有诸多错误还请海涵。</p>
<p>&#8211;EOF</p>
]]></content:encoded>
			<wfw:commentRss>http://cdbit.com/read/is-asp-net-and-net-bad.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CSDN就是个笑话</title>
		<link>http://cdbit.com/read/csdn-is-a-joke.html</link>
		<comments>http://cdbit.com/read/csdn-is-a-joke.html#comments</comments>
		<pubDate>Thu, 22 Dec 2011 15:05:41 +0000</pubDate>
		<dc:creator>cluries</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[CSDN]]></category>
		<category><![CDATA[密码]]></category>

		<guid isPermaLink="false">http://cdbit.com/?p=63</guid>
		<description><![CDATA[CSDN这个网站，我忘记我是什么时候注册的了。只是知道当时注册的时候，我还是个菜鸟中的菜鸟，当时会注册CSDN的账号是因为那个时候我曾经问过一个前辈：您平时都上什么技术社区呢？得到的回答是CSDN，于是我就乐呼呼的去注册了。 第一个账号的用户名和密码现在早已经忘记。当时注册进去后还是兴奋了一下的，觉得好象找到了组织一样，看到社区里面的帖子里面的讨论的问题，很想进去参与一句，但是奈何当时技术实在是菜，所以貌似我那第一个账号一直没发出过自己的声音。 后来也不知道是怎么回事，就不上CSDN了，我好像都忘记了中国还有这号网站一样。 在CSDN上注册第二个账号的原因是找某个代码（或者某本书吧）找到CSDN的下载频道去了，于是后面的大家估计都清楚了：为了能下载东西不得不又注册了个账号。 之后，这个账号就一直用于有的时候下载资源用。要说的是，我很讨厌CSDN设置的下载要扣积分这套系统，觉得完全是给查找资源的人设置障碍的，有的资源的分设置得老高老高的，下载下来的东西却是一坨屎。而且一直觉得CSDN资源的质量都很差，如果能在其他地方找到类似的，我基本不会选择CSDN上的。 再后来，积累多了，基本下载这些资源也少很多了，所以又一次忘记了CSDN。 之前2天前，爆出CSDN用户资料外泄，而且CSDN还把用户密码明文存储之后，突然间Twiiter上很多CSDN的tweets了。昨天晚上耐不住寂寞就下载了这个文件，打开搜索自己后来的那个用户名，果然存在，密码也是对的，email也能对上，于是当时我就想找快板砖干掉CSDN的开发人员。 不过已经爆出来了，只有赶快修改部分密码相同的服务和网站。一番折腾后，常用的服务和网站密码都修改完毕，于是开始google这件事情的缘由，看到robbin同学是这么说的： CSDN网站早期使用过明文密码，使用明文是因为和一个第三方chat程序整合验证带来的，后来的程序员始终未对此进行处理。一直到2009年4月当时的程序员修改了密码保存方式，改成了加密密码。 但部分老的明文密码未被清理，2010年8月底，对帐号数据库全部明文密码进行了清理。2011年元旦我们升级改造了CSDN帐号管理功能，使用了强加密算法，解决了CSDN帐号的各种安全性问题。 看到这个解释，我觉得相当可笑，为了和一个chat程序整合就明文保存用户密码，知道这有多危险么？这么看来CSDN是认为用户资料没有哪个神马狗屁Chat程序重要了？而且你说： 2011年元旦我们升级改造了CSDN帐号管理功能，使用了强加密算法，解决了CSDN帐号的各种安全性问题。 既然你是早期采用明文存储的，为嘛这么多年了都没改掉，还把用户资料这么导出又不安全存放。然后这份用户资料泄漏是年初就泄漏的，为嘛现在才改造？非要出了问题才改造？你说改造需要时间，可是这时间也太久了点吧。然后“使用了强加密算法&#8221;,请问是可逆的还是不可逆的呢？ 然后CSDN作为一个主要用户群体为开发者的网站，居然没有加密用户的密码，这相当的讽刺。我记得在我还是一个超级菜鸟的时候，我就知道用户密码必须要单向加密后存储。 在写这篇博文的时候：看到CSDN上发表了一篇公告：【公告】致CSDN会员的公开道歉信，这篇狗屁的公告中就说神马执意歉意什么的。狗屁，道歉有个毛用！而且公告尾部居然还加粗了以下内容： 备注说明：我们针对泄露出来的600多万帐号进行了全部扫描，统计出2011年CSDN新注册的500多万用户中，泄露出的ID有几千个。这些ID的E-mail地址绝大部分是错误的，有些密码也是错误的（少数密码吻合的我们已经重置了密码），可以确认这部分2011年的数据非本站泄露，而是黑客从其他社会工程库凑出来的数据。特此提醒2010年9月后CSDN新注册或改过密码的用户不必担心。 你们还很自豪？真是没一点悔意。 twitter上看到一条tweet,具体怎么说的忘记了，大概是这么说的： 如果CSDN泄漏用户资料这件事情在美国或者其他国家，用户早就把它告上法庭了。 我没去过国外，也没什么国外的朋友，不知道这句话的真假。但是国人真的好欺负？ 最后呢，今天又看到有报道说：人人、开心的资料也部分被泄漏了。新浪的用户系统（包括新浪微薄）密码采用的可逆算法加密的。。。。这些消息真是一个比一个重磅。 诅咒以CSDN为代表的这些网站早日关门大吉。 &#8211;EOF]]></description>
			<content:encoded><![CDATA[<p>CSDN这个网站，我忘记我是什么时候注册的了。只是知道当时注册的时候，我还是个菜鸟中的菜鸟，当时会注册CSDN的账号是因为那个时候我曾经问过一个前辈：您平时都上什么技术社区呢？得到的回答是CSDN，于是我就乐呼呼的去注册了。</p>
<p>第一个账号的用户名和密码现在早已经忘记。当时注册进去后还是兴奋了一下的，觉得好象找到了组织一样，看到社区里面的帖子里面的讨论的问题，很想进去参与一句，但是奈何当时技术实在是菜，所以貌似我那第一个账号一直没发出过自己的声音。</p>
<p>后来也不知道是怎么回事，就不上CSDN了，我好像都忘记了中国还有这号网站一样。</p>
<p>在CSDN上注册第二个账号的原因是找某个代码（或者某本书吧）找到CSDN的下载频道去了，于是后面的大家估计都清楚了：为了能下载东西不得不又注册了个账号。</p>
<p>之后，这个账号就一直用于有的时候下载资源用。要说的是，我很讨厌CSDN设置的下载要扣积分这套系统，觉得完全是给查找资源的人设置障碍的，有的资源的分设置得老高老高的，下载下来的东西却是一坨屎。而且一直觉得CSDN资源的质量都很差，如果能在其他地方找到类似的，我基本不会选择CSDN上的。</p>
<p>再后来，积累多了，基本下载这些资源也少很多了，所以又一次忘记了CSDN。</p>
<p>之前2天前，爆出CSDN用户资料外泄，而且CSDN还把用户密码明文存储之后，突然间Twiiter上很多CSDN的tweets了。昨天晚上耐不住寂寞就下载了这个文件，打开搜索自己后来的那个用户名，果然存在，密码也是对的，email也能对上，于是当时我就想找快板砖干掉CSDN的开发人员。</p>
<p>不过已经爆出来了，只有赶快修改部分密码相同的服务和网站。一番折腾后，常用的服务和网站密码都修改完毕，于是开始google这件事情的缘由，看到robbin同学是这么说的：</p>
<blockquote><p>CSDN网站早期使用过明文密码，使用明文是因为和一个第三方chat程序整合验证带来的，后来的程序员始终未对此进行处理。一直到2009年4月当时的程序员修改了密码保存方式，改成了加密密码。</p>
<p>但部分老的明文密码未被清理，2010年8月底，对帐号数据库全部明文密码进行了清理。2011年元旦我们升级改造了CSDN帐号管理功能，使用了强加密算法，解决了CSDN帐号的各种安全性问题。
</p></blockquote>
<p>看到这个解释，我觉得相当可笑，为了和一个chat程序整合就明文保存用户密码，知道这有多危险么？这么看来CSDN是认为用户资料没有哪个神马狗屁Chat程序重要了？而且你说：</p>
<blockquote><p>2011年元旦我们升级改造了CSDN帐号管理功能，使用了强加密算法，解决了CSDN帐号的各种安全性问题。</p></blockquote>
<p>既然你是早期采用明文存储的，为嘛这么多年了都没改掉，还把用户资料这么导出又不安全存放。然后这份用户资料泄漏是年初就泄漏的，为嘛现在才改造？非要出了问题才改造？你说改造需要时间，可是这时间也太久了点吧。然后“使用了强加密算法&#8221;,请问是可逆的还是不可逆的呢？</p>
<p>然后CSDN作为一个主要用户群体为开发者的网站，居然没有加密用户的密码，这相当的讽刺。我记得在我还是一个超级菜鸟的时候，我就知道用户密码必须要单向加密后存储。</p>
<p>在写这篇博文的时候：看到CSDN上发表了一篇公告：<a href="http://news.csdn.net/a/20111221/309505.html" target="_blank">【公告】致CSDN会员的公开道歉信</a>，这篇狗屁的公告中就说神马执意歉意什么的。狗屁，道歉有个毛用！而且公告尾部居然还加粗了以下内容：</p>
<blockquote><p>
备注说明：我们针对泄露出来的600多万帐号进行了全部扫描，统计出2011年CSDN新注册的500多万用户中，泄露出的ID有几千个。这些ID的E-mail地址绝大部分是错误的，有些密码也是错误的（少数密码吻合的我们已经重置了密码），可以确认这部分2011年的数据非本站泄露，而是黑客从其他社会工程库凑出来的数据。特此提醒2010年9月后CSDN新注册或改过密码的用户不必担心。
</p></blockquote>
<p>你们还很自豪？真是没一点悔意。</p>
<p>twitter上看到一条tweet,具体怎么说的忘记了，大概是这么说的：</p>
<blockquote><p>
如果CSDN泄漏用户资料这件事情在美国或者其他国家，用户早就把它告上法庭了。
</p></blockquote>
<p>我没去过国外，也没什么国外的朋友，不知道这句话的真假。但是国人真的好欺负？</p>
<p>最后呢，今天又看到有报道说：人人、开心的资料也部分被泄漏了。新浪的用户系统（包括新浪微薄）密码采用的可逆算法加密的。。。。这些消息真是一个比一个重磅。</p>
<p>诅咒以CSDN为代表的这些网站早日关门大吉。</p>
<p>&#8211;EOF</p>
]]></content:encoded>
			<wfw:commentRss>http://cdbit.com/read/csdn-is-a-joke.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>解决TTThumbsViewController设置delegate为当前class导致回退按钮消失</title>
		<link>http://cdbit.com/read/ttthumbsviewcontroller-delegate-navigationitem.html</link>
		<comments>http://cdbit.com/read/ttthumbsviewcontroller-delegate-navigationitem.html#comments</comments>
		<pubDate>Thu, 08 Dec 2011 15:39:14 +0000</pubDate>
		<dc:creator>cluries</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[delegate]]></category>
		<category><![CDATA[three20]]></category>
		<category><![CDATA[TTThumbsViewController]]></category>

		<guid isPermaLink="false">http://cdbit.com/?p=59</guid>
		<description><![CDATA[今天在做一个照片墙的功能的时候突然发现Three20的一个问题： 我的一个ViewController继承自TTThumbsViewController，这个Controller是由一个UINavigationController通过pushViewController: animated: 方法push出来的。 一开始，一切正常。但是后来我突然间发现UINavigationController的导航按钮消失不见了。 因为在最开始的时候我并没有发现这个问题，直到我把这个功能做的大概七七八八后，在过一次流程的时候才突然发现这个的。 发现UINavigationController的导航按钮消失后，通过注释代码的方法发现了当把TTThumbsViewController的delegate设置为self的时候，导航按钮就消失了。 一开始不得其门道，想不通为嘛当把delegate设置为self后会发生这样的问题，在google半天未见结果的后，决定看下TTThumbsViewController的实现。 在TTThumbsViewController的implementation中发现了以下代码： - (void)setDelegate:(id)delegate { _delegate = delegate; if (_delegate) { self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:[[[UIView alloc] init] autorelease]] autorelease]; self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:TTLocalizedString(@"Done", @"") style:UIBarButtonItemStyleBordered target:self action:@selector(removeFromSupercontroller)] autorelease]; } } 看到这里就完全明白为什么UINavigationBar的导航按钮会消失不见了，那么要解决这个问题也就简单了，初步想到可以有两种解决方法： 注释掉self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:[[[UIView alloc] init] autorelease]] autorelease];这句。 把TTThumbsViewController的delegate设置为一个其他的class。 因为我的很多代码直接写到了Controller中，所以我就直接采用了第一种方法了。注释掉那句代码后，可爱的UINavigationBar的导航按钮又回来了。 –EOF]]></description>
			<content:encoded><![CDATA[<p>今天在做一个照片墙的功能的时候突然发现Three20的一个问题：</p>
<blockquote><p>我的一个ViewController继承自TTThumbsViewController，这个Controller是由一个UINavigationController通过pushViewController: animated: 方法push出来的。</p>
<p>一开始，一切正常。但是后来我突然间发现UINavigationController的导航按钮消失不见了。</p></blockquote>
<p>因为在最开始的时候我并没有发现这个问题，直到我把这个功能做的大概七七八八后，在过一次流程的时候才突然发现这个的。</p>
<p>发现UINavigationController的导航按钮消失后，通过注释代码的方法发现了当把TTThumbsViewController的delegate设置为self的时候，导航按钮就消失了。</p>
<p>一开始不得其门道，想不通为嘛当把delegate设置为self后会发生这样的问题，在google半天未见结果的后，决定看下TTThumbsViewController的实现。</p>
<p>在TTThumbsViewController的implementation中发现了以下代码：</p>
<pre class="code">- (void)setDelegate:(id)delegate {
  _delegate = delegate;

  if (_delegate) {
    self.navigationItem.leftBarButtonItem =
    [[[UIBarButtonItem alloc] initWithCustomView:[[[UIView alloc] init]
                                                  autorelease]]
     autorelease];

    self.navigationItem.rightBarButtonItem =
    [[[UIBarButtonItem alloc] initWithTitle:TTLocalizedString(@"Done", @"")
                                      style:UIBarButtonItemStyleBordered
                                     target:self
                                     action:@selector(removeFromSupercontroller)] autorelease];
  }
}</pre>
<p>看到这里就完全明白为什么UINavigationBar的导航按钮会消失不见了，那么要解决这个问题也就简单了，初步想到可以有两种解决方法：</p>
<ol>
<li>注释掉self.navigationItem.leftBarButtonItem =<br />
[[[UIBarButtonItem alloc] initWithCustomView:[[[UIView alloc] init]<br />
autorelease]]<br />
autorelease];这句。</li>
<li>把TTThumbsViewController的delegate设置为一个其他的class。</li>
</ol>
<p>因为我的很多代码直接写到了Controller中，所以我就直接采用了第一种方法了。注释掉那句代码后，可爱的UINavigationBar的导航按钮又回来了。</p>
<p>–EOF</p>
]]></content:encoded>
			<wfw:commentRss>http://cdbit.com/read/ttthumbsviewcontroller-delegate-navigationitem.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>鱼刺</title>
		<link>http://cdbit.com/read/fishbone.html</link>
		<comments>http://cdbit.com/read/fishbone.html#comments</comments>
		<pubDate>Mon, 05 Dec 2011 13:20:11 +0000</pubDate>
		<dc:creator>cluries</dc:creator>
				<category><![CDATA[Live]]></category>
		<category><![CDATA[医院]]></category>
		<category><![CDATA[纤维镜]]></category>
		<category><![CDATA[鱼刺]]></category>

		<guid isPermaLink="false">http://cdbit.com/?p=56</guid>
		<description><![CDATA[今天周一，我没上班。是的，我请假了，不是我想偷懒，实在是没办法去上班，具体原因还得从昨天（2011-12-04）中午说起。 昨天是周末，决定去吃香辣蟹和香辣虾，到了地，点菜的时候也顺便点了点邮亭鲫鱼。 因为来的早，我们貌似是第一批客人，所以上菜也蛮快的。而且不知道怎么回事，以前不怎么喜欢吃这里的鲫鱼的，但是当时就是觉得特别好吃。 一直到吃完付款之前，什么事情都没有，生活还是那么的美好，不过在即将付款的时候，我鬼使神差的又夹了一块鱼肉放嘴里，而且我忘记了嘴里的是鱼肉！ 是的，悲剧发生了，一嘴的鱼刺，忙往盘子里面吐。一番忙活后，除了一根估计比较恨我的鱼刺外，其余的都出来了。 卡个鱼刺呗，没什么，以前也不是没碰到过，咳嗽下基本就能出来了，再不行喝点醋神马的也能搞定，所以也没在意。 回家后就觉得不怎么对劲了，无论什么办法都弄不出来。喝醋、吃东西、喝一大口水然后快速吞下&#8230;都试过了，但是，全都无效。 顺便要说的是：喝醋、而且是要慢慢的喝下，这对一个平时都不怎么吃醋的人来说，痛苦可想而知！更痛苦的是喝了一大碗的醋，鱼刺依然还是鱼刺，位置也没挪动下。 不知道鱼刺卡在具体哪个地方，晚上睡觉的时候，喉咙剧痛无比，于是，破天荒的失眠了昨晚，一直到早上6点多才迷迷糊糊的睡了2个小时。 早上起床后急奔医院，我受不了了，太难受了，而且自己能感觉到喉咙里面是肿了的。在去医院的路上，就有种不好的预感：从小到大，被鱼刺卡住的事情虽然不多，但是从来没有哪一次有这次这么严重，一天都没弄出来，最后还需要去医院。总觉得想要取出这块该死的鱼刺没那么简单。 果然，怕什么就来什么。医生努力的半天，没弄出来- -&#124;&#124;&#124;&#124;，说鱼刺卡的太深了，需要照片神马的，要特殊的设备。所以让我们换家大医院（这是一家区级医院，设备不是很完善）。 当时我就晕倒了，没办法，于是我忍着嘴里很不舒服的感觉（喷了麻药）上了去某三甲医院的车。 这个医院我第一次来，找了半天终于找到耳鼻喉科，挂号后找到医生，医生很熟练的给我开了张“纤维镜”缴费单=。= 148元。 今天周一，医院的人很多很多，交单子的时候，照纤维镜的医生助理就和我说估计要多等下，于是漫长的等待中&#8230;&#8230;&#8230;&#8230;.. 终于快到我了，发现我前面4人都是鱼刺卡住了喉咙，哈哈哈，看来周末大家都吃好的去了，今天集体来求救了。 做纤维镜很不好受，至少对于我来说，医生的原话是：我鼻子里面空间太小了（肉太多了？），纤维镜要通过鼻子我会很痛苦。。。。。 是的，真的很痛苦，不过幸运的是医生很快就找到了那该死的鱼刺，不过取出来貌似还不怎么好取，因为鱼刺全贴在肉壁上了，还好最后终于取出来了。 看到取出的那块十字造型的鱼刺，突然觉得好幸福。又回到了喉咙里面没异物的那种舒服自然的感觉了，果然，幸福真的很简单。 最后就是提醒童鞋们：如果遇到被鱼刺卡住，在尝试自己取出未果后，最好即时去医院，不然拖到最后倒霉的是自己。我托了一天，喉咙已经肿的很厉害了，肿了又加大了取出的难度，自己也更难受。 -EOF]]></description>
			<content:encoded><![CDATA[<p>今天周一，我没上班。是的，我请假了，不是我想偷懒，实在是没办法去上班，具体原因还得从昨天（2011-12-04）中午说起。</p>
<p>昨天是周末，决定去吃香辣蟹和香辣虾，到了地，点菜的时候也顺便点了点邮亭鲫鱼。</p>
<p>因为来的早，我们貌似是第一批客人，所以上菜也蛮快的。而且不知道怎么回事，以前不怎么喜欢吃这里的鲫鱼的，但是当时就是觉得特别好吃。</p>
<p>一直到吃完付款之前，什么事情都没有，生活还是那么的美好，不过在即将付款的时候，我鬼使神差的又夹了一块鱼肉放嘴里，而且我忘记了嘴里的是鱼肉！</p>
<p>是的，悲剧发生了，一嘴的鱼刺，忙往盘子里面吐。一番忙活后，除了一根估计比较恨我的鱼刺外，其余的都出来了。</p>
<p>卡个鱼刺呗，没什么，以前也不是没碰到过，咳嗽下基本就能出来了，再不行喝点醋神马的也能搞定，所以也没在意。</p>
<p>回家后就觉得不怎么对劲了，无论什么办法都弄不出来。喝醋、吃东西、喝一大口水然后快速吞下&#8230;都试过了，但是，全都无效。</p>
<p>顺便要说的是：喝醋、而且是要慢慢的喝下，这对一个平时都不怎么吃醋的人来说，痛苦可想而知！更痛苦的是喝了一大碗的醋，鱼刺依然还是鱼刺，位置也没挪动下。</p>
<p>不知道鱼刺卡在具体哪个地方，晚上睡觉的时候，喉咙剧痛无比，于是，破天荒的失眠了昨晚，一直到早上6点多才迷迷糊糊的睡了2个小时。</p>
<p>早上起床后急奔医院，我受不了了，太难受了，而且自己能感觉到喉咙里面是肿了的。在去医院的路上，就有种不好的预感：从小到大，被鱼刺卡住的事情虽然不多，但是从来没有哪一次有这次这么严重，一天都没弄出来，最后还需要去医院。总觉得想要取出这块该死的鱼刺没那么简单。</p>
<p>果然，怕什么就来什么。医生努力的半天，没弄出来- -||||，说鱼刺卡的太深了，需要照片神马的，要特殊的设备。所以让我们换家大医院（这是一家区级医院，设备不是很完善）。</p>
<p>当时我就晕倒了，没办法，于是我忍着嘴里很不舒服的感觉（喷了麻药）上了去某三甲医院的车。</p>
<p>这个医院我第一次来，找了半天终于找到耳鼻喉科，挂号后找到医生，医生很熟练的给我开了张“纤维镜”缴费单=。= 148元。</p>
<p>今天周一，医院的人很多很多，交单子的时候，照纤维镜的医生助理就和我说估计要多等下，于是漫长的等待中&#8230;&#8230;&#8230;&#8230;..</p>
<p>终于快到我了，发现我前面4人都是鱼刺卡住了喉咙，哈哈哈，看来周末大家都吃好的去了，今天集体来求救了。</p>
<p>做纤维镜很不好受，至少对于我来说，医生的原话是：我鼻子里面空间太小了（肉太多了？），纤维镜要通过鼻子我会很痛苦。。。。。</p>
<p>是的，真的很痛苦，不过幸运的是医生很快就找到了那该死的鱼刺，不过取出来貌似还不怎么好取，因为鱼刺全贴在肉壁上了，还好最后终于取出来了。</p>
<p>看到取出的那块十字造型的鱼刺，突然觉得好幸福。又回到了喉咙里面没异物的那种舒服自然的感觉了，果然，幸福真的很简单。</p>
<p>最后就是提醒童鞋们：如果遇到被鱼刺卡住，在尝试自己取出未果后，最好即时去医院，不然拖到最后倒霉的是自己。我托了一天，喉咙已经肿的很厉害了，肿了又加大了取出的难度，自己也更难受。</p>
<p>-EOF</p>
]]></content:encoded>
			<wfw:commentRss>http://cdbit.com/read/fishbone.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>在MySQL中快速的插入大量测试数据.</title>
		<link>http://cdbit.com/read/insert-large-data-to-mysql.html</link>
		<comments>http://cdbit.com/read/insert-large-data-to-mysql.html#comments</comments>
		<pubDate>Wed, 26 Oct 2011 01:42:49 +0000</pubDate>
		<dc:creator>cluries</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[插入数据]]></category>

		<guid isPermaLink="false">http://cdbit.com/?p=38</guid>
		<description><![CDATA[很多时候为了测试数据库设计是否恰当，优化SQL语句，需要在表中插入大量的数据，怎么插入大量的数据就是个问题了。 最开始想到的办法就是写一个程序通过一个很大的循环来不停的插入，比如这样： int i = LOOP_COUNT; while(i-->=0){ //insert data here. } 不过我在这么做的时候发现这样插入数据非常的慢，一秒钟插入的数据量还不到100条，于是想到不要一条一条的插入，而是通过 INSERT INTO TABLE VALUES (),(),(),()... 这样的方式来插入。于是修改程序为： int i = LOOP_COUNT; StringBuilder stringBuilder; while(i-->=0){ if(LOOP_COUNT!=i &#038;&#038; i%5000==0){ //通过insert values的方式插入这5000条数据并清空stringBuilder } stringBuilder.append("(数据)"); } //插入剩余的数据 这样做的插入速度是上升了很多，不过如果想要插入大量的输入，比如上亿条，那么花费的时间还是非常长的。 查询MySQL的文档，发现了一个页面：LOAD DATA INFILE 光看这个名字，觉得有戏，于是仔细看了下。 官方对于这个命令的描述是： LOAD DATA [LOW_PRIORITY &#124; CONCURRENT] [LOCAL] INFILE 'file_name' [REPLACE &#124; IGNORE] INTO TABLE tbl_name [CHARACTER [...]]]></description>
			<content:encoded><![CDATA[<p>很多时候为了测试数据库设计是否恰当，优化SQL语句，需要在表中插入大量的数据，怎么插入大量的数据就是个问题了。</p>
<p>最开始想到的办法就是写一个程序通过一个很大的循环来不停的插入，比如这样：</p>
<pre class="code">
int i = LOOP_COUNT;
while(i-->=0){
    //insert data here.
}
</pre>
<p>不过我在这么做的时候发现这样插入数据非常的慢，一秒钟插入的数据量还不到100条，于是想到不要一条一条的插入，而是通过</p>
<pre class="code">
INSERT INTO TABLE VALUES (),(),(),()...
</pre>
<p>这样的方式来插入。于是修改程序为：</p>
<pre class="code">
int i = LOOP_COUNT;
StringBuilder stringBuilder;
while(i-->=0){
    if(LOOP_COUNT!=i &#038;&#038; i%5000==0){
     //通过insert values的方式插入这5000条数据并清空stringBuilder
    }
    stringBuilder.append("(数据)");
}
//插入剩余的数据
</pre>
<p>这样做的插入速度是上升了很多，不过如果想要插入大量的输入，比如上亿条，那么花费的时间还是非常长的。</p>
<p>查询MySQL的文档，发现了一个页面：<a href="http://dev.mysql.com/doc/refman/5.5/en/load-data.html" target="_blank">LOAD DATA INFILE</a> 光看这个名字，觉得有戏，于是仔细看了下。</p>
<p>官方对于这个命令的描述是：</p>
<pre class="code">
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [CHARACTER SET charset_name]
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]
    [IGNORE number LINES]
    [(col_name_or_user_var,...)]
    [SET col_name = expr,...]
</pre>
<p>命令不复杂，具体的每个参数的意义和用法请看官方的解释 <a href="http://dev.mysql.com/doc/refman/5.5/en/load-data.html" target="_blank">http://dev.mysql.com/doc/refman/5.5/en/load-data.html</a></p>
<p>那么现在做的就是生成数据了，我习惯用\t作为数据的分隔符、用\n作为一行的分隔符，所以生成数据的代码如下：</p>
<pre class="code">
long start = System.currentTimeMillis() / 1000;
try {
    File file = new File(FILE);

    if (file.exists()) {
        file.delete();
    }
    file.createNewFile();

    FileOutputStream outStream = new FileOutputStream(file, true);

    StringBuilder builder = new StringBuilder(10240);
    DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
    Random rand = new Random();

    String tmpDate = dateFormat.format(new Date());
    Long tmpTimestamp = System.currentTimeMillis() / 1000;

    int i = 0;
    while (i++ < LOOP) {
        if (i > 0 &#038;&#038; i % 30000 == 0) {
            System.out.println("write offset:" + i);
            outStream.write(builder.toString().getBytes(CHARCODE));
            builder = new StringBuilder(10240);
        }

        if (tmpTimestamp.compareTo(System.currentTimeMillis() / 1000) != 0) {
            tmpDate = dateFormat.format(new Date());
            tmpTimestamp = System.currentTimeMillis() / 1000;
        }

        builder.append(tmpDate);
        builder.append("\t");
        builder.append(rand.nextInt(999));
        builder.append("\t");
        builder.append(Encrypt.md5(System.currentTimeMillis() + "" + rand.nextInt(99999999)));
        builder.append("\t");
        builder.append(rand.nextInt(999) % 2 == 0 ? "AA." : "BB");
        builder.append("\t");
        builder.append(rand.nextFloat() * 2000);
        builder.append("\t");
        builder.append(rand.nextInt(9));
        builder.append("\n");
    }

    System.out.println("write data:" + i);
    outStream.write(builder.toString().getBytes(CHARCODE));

    outStream.close();
} catch (Exception e) {
    e.printStackTrace();
}

System.out.println(System.currentTimeMillis() / 1000 - start);
</pre>
<p>这段代码会生成一个数据文件，每一行为一条记录，然后再使用上面提到的 LOAD DATA 来导入数据就可以了，我在公司的电脑下（2G内存+垃圾双核CPU，MySQL直接装在windows下，没任何优化，developer模式）每秒能达到近万条的插入速度，比其他方式都快很多。</p>
<p>另外如果想直接用GUI工具操作也可以，比如SQLYog中，右键要导入的表，选择Import &#8211; Import CSV Data Using Load Local.. 然后设置好编码、分隔符后就可以直接导入了。</p>
<p>&#8211;EOF</p>
]]></content:encoded>
			<wfw:commentRss>http://cdbit.com/read/insert-large-data-to-mysql.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

