<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href='http://feed.feedsky.com/styles/temp01.xsl' type='text/xsl' ?><!--这是一个由Feedsy提供技术支持的Feed，为了提高读者阅读的体验，以及满足用户美化自己Feed的需要，我们设计了多种精美的Feed模板，提供给大家选择，所有最终呈现出来的样式，皆由用户自愿选择使用，未经许可，任何团体和个人，请不要擅自修改样式或者盗用，这是对于用户选择权的尊重。--><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:fs="http://www.feedsky.com/namespace/feed" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link href="http://feed.feedsky.com/zbaccp" type="application/rss+xml" rel="self"></atom:link><fs:self_link href="http://feed.feedsky.com/zbaccp" type="application/rss+xml"></fs:self_link><lastBuildDate>Wed, 01 Jul 2009 06:51:19 GMT</lastBuildDate><title>北大青鸟中博</title><description>中博人自己的博客</description><link>http://blog.zbaccp.com</link><sy:updatePeriod>hourly</sy:updatePeriod><sy:updateFrequency>1</sy:updateFrequency><xhtml:meta name="robots" content="noindex"></xhtml:meta><language>en</language><pubDate>Wed, 01 Jul 2009 06:51:19 GMT</pubDate><item><title>C、C++ 和 Java安全编码实践提示与技巧</title><link>http://blog.zbaccp.com/?p=399</link><content:encoded>&lt;p&gt; 对于所有类型环境中的开发人员来说，安全性正成为一个越来越重要的主题，即便过去一直认为安全性不成问题的嵌入式系统也是如此。本文将介绍几种类型的编码漏洞，指出漏洞是什么、如何降低代码被攻击的风险、如何更好地找出代码中的此类缺陷。&lt;/p&gt;
&lt;p&gt;注入攻击&lt;br /&gt;
      通过将信息注入正在运行的流程，攻击者可以危害进程的运行状态，以反射到开发人员无法保护的某种最终目标。例如，攻击者可能会通过堆栈溢出（stack corruption）将代码注入进程，从而执行攻击者选定的代码。此外，攻击者也可能尝试将数据注入数据库，供将来使用；或将未受保护的字符串注入数据库查询，获取比开发人员更多的信息。无论出于怎样的目的，注入总是一件坏事，总是需要谨慎对待的。&lt;br /&gt;
      最恶劣的注入攻击形式也许是代码注入——将新代码置入正在运行的进程的内存空间，随后指示正在运行的进程执行这些代码。此类攻击如果成功，则几乎可以进行任何操作，因为正在运行的进程完全被劫持，可执行攻击者希望执行的任何代码。&lt;br /&gt;
      此类攻击最著名的示例之一就是 Windows 动画光标攻击，这正是本文要讨论的模式。攻击者利用一个简单的 Web 页面将形式不当的动画光标文件下载到查看者的 PC 中，导致浏览器调用此动画光标，动画光标调用时可能发生任意代码的注入。实际上，这是一个完美的攻击载体：因为它不要求对被攻击机器的任何实际访问、最终用户根本意识不到任何可能发生的麻烦；此外，如果攻击效果的恶意也是适度的，则对最终用户的外部影响几乎是零。&lt;br /&gt;
      考虑示例 1(a)，当然，这改写自 Windows 攻击，它构成了此类攻击载体的基础。这里的开发人员对于传入流的可靠性做出了基本的假设。信任流和并相信一切都没问题。使用基于堆栈的将被非串形化(deserialized)的类型调用函数，未知数据流和代码注入肯定会在某个时间点出现。&lt;br /&gt;
(a)&lt;br /&gt;
void LoadTypeFromStream(unsigned char* stream, SOMETYPE* typtr)&lt;br /&gt;
{&lt;br /&gt;
  int len;&lt;br /&gt;
  // Get the size of our type&amp;#8217;s serialized form&lt;br /&gt;
  memcpy(&amp;amp;len, stream, sizeof(int));&lt;br /&gt;
  // De-serialize the type&lt;br /&gt;
  memcpy(typtr, stream + sizeof(int), len);&lt;br /&gt;
}&lt;br /&gt;
(b)&lt;br /&gt;
void foo(unsigned char* stream)&lt;br /&gt;
{&lt;br /&gt;
  SOMETYPE ty;&lt;br /&gt;
  LoadTypeFromStream(stream, &amp;amp;ty);&lt;br /&gt;
}&lt;br /&gt;
(c)&lt;br /&gt;
void LoadTypeFromStream&lt;br /&gt;
      (unsigned char* stream, SOMETYPE* typtr)&lt;br /&gt;
{&lt;br /&gt;
    int len;&lt;br /&gt;
    // Get the size of our type&amp;#8217;s serialized form&lt;br /&gt;
    memcpy(&amp;amp;len, stream, sizeof(int));&lt;br /&gt;
    // GUARD&lt;br /&gt;
    if( len &amp;lt; 0 || len &amp;gt; sizeof(SOMETYPE) )&lt;br /&gt;
        throw TaintedDataException();&lt;br /&gt;
    // De-serialize the type&lt;br /&gt;
    memcpy(typtr, stream + sizeof(int), len);&lt;br /&gt;
}&lt;br /&gt;
示例1 注入攻击。&lt;br /&gt;
      这是怎样发生的？假设您调用示例 1（b）中的函数。我们就得到了一个易于利用的攻击载体。这里的问题在于 SOMETYPE 在编译时的大小是固定的。假设此类型在内存中使用 128 个字节表示。再假设您构建传入流时，使前 4 个字节（要非串形化的内容的长度）的读数为 256。现在，您没有检查正在处理的内容的有效性，而是将 256 个字节复制到了仅为 128 个字节的保留堆栈空间内。&lt;br /&gt;
      考虑到发布模式堆栈的典型布局，您显然遇到了麻烦。查看堆栈，了解原因所在。每个被调用的函数都会将其本地数据布设到堆栈的一个帧内，通常是通过在输入时从堆栈指针减去本地数据的已知大小（加上处理调用链本身所需的任何管理数据）实现的。编译器发出的理想函数 prolog（伪代码）如下所示：&lt;br /&gt;
 .foo&lt;br /&gt;
 sub sp, 128  ; sizeof SOMETYPE&lt;/p&gt;
&lt;p&gt;      随后，对可利用函数的调用应如下所示：&lt;br /&gt;
push sp   ; push the SOMETYPE&lt;br /&gt;
  local variable&lt;br /&gt;
push ap   ; push the stream&lt;br /&gt;
  pointer (comes from 1st argument)&lt;br /&gt;
call LoadTypeFromStream&lt;br /&gt;
ret&lt;br /&gt;
      在调用 foo() 时，调用方将流地址以及返回地址（作为使用调用指令或平台上可用的同等部分的隐式效果）压入堆栈，使堆栈内容中有 128 个字节是为我们的类型保留的，且紧邻返回给 foo() 调用方的返回地址，参见图 1。&lt;br /&gt;
      现在，LoadTypeFromStream 执行，并将 256 个字节写入所提供的地址，也就是在我们调用函数之前堆栈指针（SP）的值。这会覆盖应该使用的 128 个字节（本例中位于地址 0&amp;#215;1000 处），加上随后的 128 个字节，包括传入的参数指针、返回地址以及堆栈中随后 128 个字节内存储的其他任何信息。&lt;br /&gt;
      那么攻击者怎样利用这样的漏洞呢？并不简单，需要经过反复的试错。实际上，攻击者要安排攻击，使覆盖的返回地址将控制权移交给攻击者，而非预期调用方函数。因而，攻击者需要准确了解要利用哪些数据结构，这样的数据结构在要攻击的任意版本的操作系统或应用程序上有多大、周边有哪些内容（以便正确设定伪造的返回地址）、如何有意义地插入足够的信息以使返回地址和其他效果能够实现某种恶意操作。&lt;br /&gt;
      这一切做起来并不简单，但多种多样的攻击表明，总是有人有太多的空闲时间。&lt;br /&gt;
      应如何防范此类攻击？这是一次攻击还是多重攻击？所写入的代码是否真的像这里所显示的这样笨拙？现代编译器是否会对堆栈帧布局做一些特殊处理，以避免此类问题？&lt;br /&gt;
      总而言之，模糊处理就等于没有防御。我们都认识到，程序员将攻击预想得越简单，攻击出现的可能性就越高。然而，即便是复杂的代码，若未进行合理防御，也迟早会受到攻击。这种利用被污染的数据流和非常基本的缓冲溢出漏洞的攻击，多年以来这一直是热门的研究课题，但每年仍然会出现大量此类攻击。&lt;br /&gt;
      防范此类攻击的效果甚微，因为攻击形式复杂——注意您的数据假设。只要在示例1（a）中添加一行简单的代码，就会使其更加安全，参见示例1（c）。显然，随着流交互变得更加复杂，保护的要求也随之复杂化，但基本上说代码注入是编码中“不可饶恕”的过失，因为防范它的方法是那样普及和简单。&lt;/p&gt;
&lt;p&gt;SQL 注入&lt;br /&gt;
      此外还存在其他一些类型的 SQL 注入，可能会给以数据库为中心的应用程序造成严重的问题。在某些情况下，攻击者只是尝试访问更多的内容。在另一些情况下，攻击者关注的则是在数据库中存储新信息，以便使应用程序此后在不知情的前提下使用此类信息，入侵最终用户的会话。&lt;br /&gt;
      基于查询的攻击关注的是一种普遍应用的反模式，使用字符串串联构建查询。这种类型的漏洞常常出现在面向 Web 的应用程序中，在所有常用页面产品——包括 PHP、ASP、JSP 等及其后备控制器逻辑中同样常见。&lt;br /&gt;
      这种漏洞的核心是开发人员使用直接查询执行，而非利用查询准备来运行数据库交互。考虑以下登录验证查询示例：&lt;br /&gt;
SELECT ID FROM USERS WHERE NAME= &amp;#8216;user&amp;#8217; AND PWD=&amp;#8217;password&amp;#8217;&lt;br /&gt;
      用户将看到一个简单的 HTML 表单，该表单包含两个输入框并使用了这种反模式。从表单传入的参数（无论所讨论的页面产品是怎样接收到这些参数的）都将通过串联直接代入查询的字符串形式。&lt;br /&gt;
考虑攻击者提供的一组参数：&lt;br /&gt;
NAME:   x&lt;br /&gt;
PWD:    x&amp;#8217; OR &amp;#8216;1&amp;#8242; = &amp;#8216;1&lt;br /&gt;
      运行串联，结果将得到被利用的查询：&lt;br /&gt;
SELECT ID FROM USERS WHERE NAME=&lt;br /&gt;
  &amp;#8216;x&amp;#8217; AND PWD=&amp;#8217;x&amp;#8217; OR &amp;#8216;1&amp;#8242; = &amp;#8216;1&amp;#8242;&lt;br /&gt;
      如果登录仅检查该语句执行成功与否（而未考虑结果行），攻击者即可迅速获得该应用程序所处理的任意用户记录可提供的任意访问权限。很多应用程序的用户表的第一行都是为超级用户保留的，攻击此类应用程序轻而易举。&lt;br /&gt;
      利用未谨慎处理数据库语句内代入字符串的应用程序，攻击者可实现多种其他形式的攻击。这种反模式极为常见（参见最近的 Microsoft 公告和其他内容了解其普遍性），缓解方法也同样简单，并可置于基本数据库 API 之中：使用准备好的语句而非字符串串联。&lt;br /&gt;
      例如，考虑示例2 中的错误实现。此函数严格遵循反模式，还通过抛出包含传入（未过滤）数据（即用户名）的异常而执行了另外一项重要的 no-no 操作。如果以响应的形式为用户呈现此数据，您就很可能遇到某些恶意利用，特别是可能遭遇跨站脚本攻击。&lt;br /&gt;
public void validateUser(String user, String pwd, Connection db)&lt;br /&gt;
    throws InvalidUserException&lt;br /&gt;
{&lt;br /&gt;
  Statement stmt = null;&lt;br /&gt;
  ResultSet rs = null;&lt;br /&gt;
  try&lt;br /&gt;
  {&lt;br /&gt;
      // Create the statement&lt;br /&gt;
      stmt = db.createStatement();&lt;br /&gt;
      String sql = &amp;#8220;select id from users where user=&amp;#8217;&amp;#8221; + user +&lt;br /&gt;
                   &amp;#8220;&amp;#8216; and pwd=&amp;#8217;&amp;#8221; + pwd + &amp;#8220;&amp;#8216;&amp;#8221;;&lt;br /&gt;
      // Execute it, process the result&lt;br /&gt;
      rs = stmt.executeQuery(sql);&lt;br /&gt;
      if( rs == null || rs.next() == null )&lt;br /&gt;
          throw new InvalidUserException(user);&lt;br /&gt;
  }&lt;br /&gt;
  catch( SQLException e )&lt;br /&gt;
  {&lt;br /&gt;
      throw new InvalidUserException(user);&lt;br /&gt;
  }&lt;br /&gt;
  finally&lt;br /&gt;
  {&lt;br /&gt;
    try { if( rs != null ) rs.close(); } catch( Exception e ) { }&lt;br /&gt;
    try { if( stmt != null ) stmt.close(); } catch( Exception e ) { }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
示例2 错误实现。&lt;br /&gt;
      为了修正此代码，不应动态构建 SQL 查询，而是直接构建准备好的语句，并使用它来代替传入参数。&lt;br /&gt;
我们将准备的语句会为参数保留空间，并且不易受此类攻击利用，原因就在于它的词汇方面并不像字符串串联那样脆弱。&lt;br /&gt;
      考虑以下语句（准备该语句的目的与前面提到的串联字符串相同）：&lt;br /&gt;
SELECT ID FROM USERS WHERE USER=?&lt;br /&gt;
   AND PWD=?&lt;br /&gt;
      我使用这个准备好的语句代入了 user 和 pwd 参数的传入数据。如果我们将之前被利用的字符串作为输入，结果将是查询代入过程出错，因为不能将包含单引号等特殊字符的参数提供给准备好的查询。&lt;br /&gt;
      其他可能出现的利用也能在不同阶段捕捉到，但如示例3 所示，新实现的创建与原实现一样简单，但安全性要高得多（我们也从抛出的异常中删除了用户名，这样可以避免在未经过滤的情况下将其公开给调用方的危险）。&lt;br /&gt;
public void validateUser(String user, String pwd, Connection db)&lt;br /&gt;
    throws InvalidUserException&lt;br /&gt;
{&lt;br /&gt;
  PreparedStatement stmt = null;&lt;br /&gt;
  ResultSet rs = null;&lt;br /&gt;
  try&lt;br /&gt;
  {&lt;br /&gt;
      // Prepare the statement, rather than concatenating it&lt;br /&gt;
      String sql = &amp;#8220;select id from users where user=? and pwd=?&amp;#8221;);&lt;br /&gt;
      stmt = db.prepareStatement(sql);&lt;br /&gt;
      // Substitute our incoming parameters into the query&lt;br /&gt;
      stmt.setString(1, user);&lt;br /&gt;
      stmt.setString(2, pwd);&lt;br /&gt;
      // Execute the query and process the results as before&lt;br /&gt;
      rs = stmt.executeQuery();&lt;br /&gt;
      if( rs == null || rs.next() == null )&lt;br /&gt;
          throw new InvalidUserException();&lt;br /&gt;
  }&lt;br /&gt;
  catch( SQLException e )&lt;br /&gt;
  {&lt;br /&gt;
      throw new InvalidUserException();&lt;br /&gt;
  }&lt;br /&gt;
  finally&lt;br /&gt;
  {&lt;br /&gt;
    try { if( rs != null ) rs.close(); } catch( Exception e ) { }&lt;br /&gt;
    try { if( stmt != null ) stmt.close(); } catch( Exception e ) { }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
示例3  示例2 的较为安全的版本。&lt;br /&gt;
      总体而言，无论是处理查询还是DML，在处理来自最终用户的数据时，始终应使用准备好的语句来利用数据库本身内置的过滤和解析功能。&lt;/p&gt;
&lt;p&gt;跨站点脚本攻击（XSS）&lt;br /&gt;
      在早期的浏览器版本中，对于JavaScript 施加的第一项限制就是为页面内容建立一种边界，使一个站点提供的一个框架内执行的脚本无法访问其他站点提供的框架中的内容。因而，跨站点脚本攻击这种攻击模式关注的是使来自一个站点（攻击者站点）的脚本能够访问其他站点的内容（例如，用户的银行账户站点）。&lt;br /&gt;
      为此，用户通常必然要访问一个恶意或不可信的网站，而社会工程的众多试验已经显示，用户可能会被最古怪的站点吸引。&lt;br /&gt;
      在此类漏洞中，最常见的形式就是简单的反射漏洞，在一次服务器请求中将未经过滤的 HTML 参数（通常是表单参数）反射给用户。这种攻击载体的标准形式首先是通过搜索引擎结果页面显示出来的，通常会在页面标题中反射用户的查询关键词。如果未经过滤，这种反射回的查询关键词很可能包含一些编码不当的 HTML 标记，但可被接收方浏览器解释为有效的 HTML。&lt;br /&gt;
      实际上，未经过滤的传入数据的任何反射都会造成问题，因为 XSS数量和种类始终在增加，参见示例4。&lt;br /&gt;
public void doGet(HttpServletRequest req, HttpServletResponse res)&lt;br /&gt;
{&lt;br /&gt;
    string title = req.getParameter(&amp;#8221;searchTerm&amp;#8221;);&lt;br /&gt;
    res.getOutputStream().write(title.getBytes(&amp;#8221;UTF-8&amp;#8243;));&lt;br /&gt;
}&lt;br /&gt;
示例4 未经过滤的传入数据本身就存在问题。&lt;br /&gt;
      XSS反射的表现十分简单，而解决此问题的方法也极为简单——将从传入请求中读取的一切内容编码，之后再回发给浏览器即可。尽管我们在这里的示例中使用了Java，但包括HTML编码机制的所有常见页面产品均可用以避免此类漏洞。例如，下面这条 ASP 语句就可能被利用：&lt;br /&gt;
Response.Write Request.Form(&amp;#8221;username&amp;#8221;&quot;&lt;br /&gt;
      反之，以下语句则不能被利用：&lt;br /&gt;
Response.Write Server.HTMLEncode( Request.Form(&amp;#8221;username&amp;#8221;))&lt;br /&gt;
      尽管仍然没有内置对象可用于执行标准转换，但也可在 Java 中进行类似转换，以避免此类利用。也就是说，可轻松编写一个类似的 String 转换程序。对于寻找“现成”产品包的用户，JTidy 项目（jtidy.sourceforge.net）是一个理想的起点。&lt;br /&gt;
      其他更加复杂的 XSS 表现形式以未过滤用户输入的持久存储为中心，此类输入内容会在随后用于提供响应内容。这是一类更难以诊断的 XSS，因为攻击模式不仅依赖于所存储的未经过滤的用户输入，还依赖于此后对其他用户可用的存储数据。&lt;br /&gt;
      在早期Web发展阶段，不可信任的论坛提供的软件包特别易受此类攻击模式的影响。即便是现在，在数据库（或文件）中存储未经过滤的传入数据并随后将所存储的数据发送给用户的应用程序也易于受到此类持久形式的 XSS 的攻击。&lt;br /&gt;
      同样，解决方法非常简单，只需通过编程，在存储信息之前将信息编码或在将信息从持久存储发送给用户之前编码即可。总而言之，在存储之前编码数据总是更加安全，这种方式可以保证未来对此类数据的使用免遭XSS 攻击。&lt;/p&gt;
&lt;p&gt;查找漏洞&lt;br /&gt;
      本文介绍的问题的规避方法易于实现，但对于尝试控制现有代码库或新建代码库的安全性的开发人员或开发组织而言，所面临的最大挑战就是找到漏洞所在。毫无疑问，可以利用手动代码检查的方法，但我可以确定地说，围坐在桌边、查看大量代码并尝试找出可能成为漏洞的内容绝非乐事。&lt;br /&gt;
      静态源代码分析为此类问题提供了一种可行的解决方案，这种方法关注代码中现有的潜在漏洞或弱点，而不是像传统安全性应用程序或渗透测试工具那样尝试找到现有漏洞或攻击载体 。利用 SCA 工具可显著减少查找并缓解此类问题所需的时间和工作量。&lt;br /&gt;
      目前有多种开源和商业工具可用，分别具有不同的功能。Klocwork（我目前效力的企业）就提供了这样一种商业静态源代码分析产品套件，主要关注 C、C++ 和 Java，为开发人员提供了快速、准确的运行缺陷和安全漏洞分析，并且能够集成在您所选择的 IDE 之中。■&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/239585793/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=399&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239585793/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239585793/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://blog.zbaccp.com/?feed=rss2&amp;p=399</wfw:commentRss><description> 对于所有类型环境中的开发人员来说，安全性正成为一个越来越重要的主题，即便过去一直认为安全性不成问题的嵌入式系统也是如此。本文将介绍几种类型的编码漏洞，指出漏洞是什么、如何降低代码被攻击的风险、如何更好地找出代码中的此类缺陷。
注入攻击
      通过将信息注入正在运行的流程，攻击者可以危害进程的运行状态，以反射到开发人员无法保护的某种最终目标。例如，攻击者可能会通过堆栈溢出（stack corruption）将代码注入进程，从而执行攻击者选定的代码。此外，攻击者也可能尝试将数据注入数据库，供将来使用；或将未受保护的字符串注入数据库查询，获取比开发人员更多的信息。无论出于怎样的目的，注入总是一件坏事，总是需要谨慎对待的。
      最恶劣的注入攻击形式也许是代码注入——将新代码置入正在运行的进程的内存空间，随后指示正在运行的进程执行这些代码。此类攻击如果成功，则几乎可以进行任何操作，因为正在运行的进程完全被劫持，可执行攻击者希望执行的任何代码。
      此类攻击最著名的示例之一就是 Windows 动画光标攻击，这正是本文要讨论的模式。攻击者利用一个简单的 Web 页面将形式不当的动画光标文件下载到查看者的 PC 中，导致浏览器调用此动画光标，动画光标调用时可能发生任意代码的注入。实际上，这是一个完美的攻击载体：因为它不要求对被攻击机器的任何实际访问、最终用户根本意识不到任何可能发生的麻烦；此外，如果攻击效果的恶意也是适度的，则对最终用户的外部影响几乎是零。
      考虑示例 1(a)，当然，这改写自 Windows 攻击，它构成了此类攻击载体的基础。这里的开发人员对于传入流的可靠性做出了基本的假设。信任流和并相信一切都没问题。使用基于堆栈的将被非串形化(deserialized)的类型调用函数，未知数据流和代码注入肯定会在某个时间点出现。
(a)
void LoadTypeFromStream(unsigned char* stream, SOMETYPE* typtr)
{
  int len;
  // Get the size of our type&amp;#8217;s serialized form
  memcpy(&amp;#38;len, stream, sizeof(int));
  // De-serialize the type
  memcpy(typtr, stream + sizeof(int), len);
}
(b)
void foo(unsigned char* stream)
{
  SOMETYPE ty;
  LoadTypeFromStream(stream, &amp;#38;ty);
}
(c)
void LoadTypeFromStream
      (unsigned char* stream, SOMETYPE* [...]&lt;img src=&quot;http://www1.feedsky.com/t1/239585793/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=399&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239585793/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239585793/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>默认</category><pubDate>Wed, 01 Jul 2009 14:51:19 +0800</pubDate><author>student</author><comments>http://blog.zbaccp.com/?p=399#comments</comments><guid isPermaLink="false">http://blog.zbaccp.com/?p=399</guid><dc:creator>student</dc:creator><fs:srclink>http://blog.zbaccp.com/?p=399</fs:srclink><fs:srcfeed>http://blog.zbaccp.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/zbaccp/~7524155/239585793/5633121</fs:itemid></item><item><title>用C#制作PDF文件全攻略</title><link>http://blog.zbaccp.com/?p=397</link><content:encoded>&lt;p&gt;丽水市汽车运输集团有限公司信息中心 苟安廷&lt;br /&gt;
PDF文件是目前比较流行的电子文档格式，在办公自动化（OA）等软件的开发中，经常要用到该格式，但介绍如何制作PDF格式文件的资料非常少，在网上搜来搜去，都转贴的是同一段“暴力”破解的方法，代码片断如下：&lt;/p&gt;
&lt;p&gt;StreamWriter pPDF=new StreamWriter(filePath);&lt;/p&gt;
&lt;p&gt;ArrayList xRefs=new ArrayList();&lt;/p&gt;
&lt;p&gt;float yPos =0f;&lt;/p&gt;
&lt;p&gt;long streamStart=0;&lt;/p&gt;
&lt;p&gt;long streamEnd=0;&lt;/p&gt;
&lt;p&gt;long streamLen =0;&lt;/p&gt;
&lt;p&gt;string strPDFMessage=null;&lt;/p&gt;
&lt;p&gt;//PDF文档头信息&lt;/p&gt;
&lt;p&gt;strPDFMessage=&amp;#8221;％PDF-1.1\n&amp;#8221;;&lt;/p&gt;
&lt;p&gt;ConvertToByteAndAddtoStream(strPDFMessage);&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;xRefs.Add(mPDF.Length);&lt;/p&gt;
&lt;p&gt;strPDFMessage=&amp;#8221;1 0 obj\n&amp;#8221;;&lt;/p&gt;
&lt;p&gt;ConvertToByteAndAddtoStream(strPDFMessage);&lt;/p&gt;
&lt;p&gt;strPDFMessage=&amp;#8221;&amp;lt;&amp;lt; /Length 2 0 R &amp;gt;&amp;gt;\n&amp;#8221;;&lt;/p&gt;
&lt;p&gt;ConvertToByteAndAddtoStream(strPDFMessage);&lt;/p&gt;
&lt;p&gt;strPDFMessage=&amp;#8221;stream\n&amp;#8221;;&lt;/p&gt;
&lt;p&gt;ConvertToByteAndAddtoStream(strPDFMessage);&lt;/p&gt;
&lt;p&gt;……&lt;/p&gt;
&lt;p&gt;看了上面的制作办法，我眼镜都摔坏了三幅，如果用上面这样原始的办法能制作出满意的PDF文件，那一定是天才所为。后来，我从一个网站（网址：&lt;a href=&quot;http://itextsharp.sourceforge.net/index.html&quot;&gt;http://itextsharp.sourceforge.net/index.html&lt;/a&gt;）中看到了专门制作PDF文件的控件的介绍，暗喜之余，立马下载试验，果然非常轻松地制作出了想要的PDF文件，因为网站为英文，内容又多，读起来非常费力，在解决了自己的问题后，看到许多网友还在为PDF文件制作而郁闷，遂决定将该内容翻译为中文，由于本人英语水平一般，许多地方又晦涩难懂，故翻译质量不是很满意，敬请斧正，但大部分能看懂。本文的目的一是解决部分网友的燃眉之急，二是抛砖引玉，如果哪位仁兄愿意将该网站中的内容准确翻译出来，则是天下之大幸。&lt;/p&gt;
&lt;p&gt;要用本文的方法生成PDF文件，需要两个控件：itextsharp.dll和ICSharpCode.SharpZipLib.dll，由于示例代码实在太多，我将代码全部整理出来，放在另外一个文件“示例代码.doc”中，所有这些资源，我均放在了本人的ftp站点（&lt;a href=&quot;ftp://202.107.251.26&quot;&gt;ftp://202.107.251.26&lt;/a&gt;）上的“Pdf文件制作全攻略”文件夹中（文件夹中另外两个rar压缩文件为两个控件的源代码，供大家学习研究使用），你可以到这里下载相应的资源，或者直接到原网站下载。&lt;/p&gt;
&lt;p&gt;为便于调试和叙述，所有例子均为DOS控制台程序，windows程序使用方法完全一样，按照下面的步骤创建一个可调试的项目：&lt;/p&gt;
&lt;p&gt;1、 打开VS2003；&lt;/p&gt;
&lt;p&gt;2、 单击菜单“文件”→“新建”→“项目”，在项目类型中选择“Visual C#项目”，在模板中选择“控制台应用程序”，输入文件名称如“MakePdf”，指定好存放路径，然后点确定按钮；&lt;/p&gt;
&lt;p&gt;3、 在“解决方案资源管理器”中右键单击“引用”，从弹出的菜单中选择“添加引用”，在“.NET”选项夹中选择“浏览”，添加前面提到的两个应用，如下图：&lt;br /&gt;
4、 在代码窗口顶部添加两个引用：&lt;/p&gt;
&lt;p&gt;using iTextSharp.text;&lt;/p&gt;
&lt;p&gt;using iTextSharp.text.pdf;&lt;/p&gt;
&lt;p&gt;至此，准备工作完毕。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;第一部分 iText的简单应用&lt;br /&gt;
第一章 创建一个Document&lt;br /&gt;
利用iText五步创建一个PDF文件：helloword。&lt;/p&gt;
&lt;p&gt;第一步，创建一个 iTextSharp.text.Document对象的实例：&lt;/p&gt;
&lt;p&gt;Document document = new Document();&lt;/p&gt;
&lt;p&gt;第二步，为该Document创建一个Writer实例：&lt;/p&gt;
&lt;p&gt;PdfWriter.getInstance(document, new FileStream(&amp;#8221;Chap0101.pdf&amp;#8221;, FileMode.Create));&lt;/p&gt;
&lt;p&gt;第三步，打开当前Document&lt;/p&gt;
&lt;p&gt;document.Open();&lt;/p&gt;
&lt;p&gt;第四步，为当前Document添加内容：&lt;/p&gt;
&lt;p&gt;document.Add(new Paragraph(&amp;#8221;Hello World&amp;#8221;));&lt;/p&gt;
&lt;p&gt;第五步，关闭Document&lt;/p&gt;
&lt;p&gt;document.Close();&lt;/p&gt;
&lt;p&gt;完整的代码见示例代码0101。&lt;/p&gt;
&lt;p&gt;在例中，不难看出，制作一个PDF文件是非常简单的。&lt;/p&gt;
&lt;p&gt;注：如果你将例中“document.Add(new Paragraph(&amp;#8221;Hello World&amp;#8221;)); ”中的字符串“Hello Word”换成中文，如“这是我的第一个PDF文件”，产生的结果一定让你大失所望，因为生成的PDF文件中并没有将中文显示出来，不要担心，在第9章中要专门讲解字体问题，中文显示也就迎刃而解了，如果不能正确显示中文，也就没有必要翻译本文了。&lt;/p&gt;
&lt;p&gt;下面对这几步做详细介绍。&lt;/p&gt;
&lt;p&gt;第一步 创建一个Document实例：&lt;br /&gt;
iTextSharp.text.Document-object共有三个构造函数：&lt;/p&gt;
&lt;p&gt;public Document();&lt;/p&gt;
&lt;p&gt;public Document(Rectangle pageSize);&lt;/p&gt;
&lt;p&gt;public Document(Rectangle pageSize,&lt;/p&gt;
&lt;p&gt;int marginLeft,&lt;/p&gt;
&lt;p&gt;int marginRight,&lt;/p&gt;
&lt;p&gt;int marginTop,&lt;/p&gt;
&lt;p&gt;int marginBottom);&lt;/p&gt;
&lt;p&gt;第一个构造函数以A4页面作为参数调用第二个构造函数，第二个构造函数以每边36磅页边距为参数调用第三个构造函数&lt;/p&gt;
&lt;p&gt;u 页面尺寸：&lt;/p&gt;
&lt;p&gt;你可以通过指定的颜色和大小创建你自己的页面，示例代码0102创建一个细长的浅黄色背景的页面：&lt;/p&gt;
&lt;p&gt;Rectangle pageSize = new Rectangle(144, 720);&lt;/p&gt;
&lt;p&gt;pageSize.BackgroundColor = new Color(0xFF, 0xFF, 0xDE);&lt;/p&gt;
&lt;p&gt;Document document = new Document(pageSize);&lt;/p&gt;
&lt;p&gt;通常，你不必创建这样的页面，而可以从下面页面尺寸中选择：&lt;/p&gt;
&lt;p&gt;A0-A10, LEGAL, LETTER, HALFLETTER, _11&amp;#215;17, LEDGER, NOTE, B0-B5, ARCH_A-ARCH_E, FLSA 和 FLSE&lt;/p&gt;
&lt;p&gt;大多数情况下使用纵向页面，如果希望使用横向页面，你只须使用rotate()函数：&lt;/p&gt;
&lt;p&gt;Document document = new Document(PageSize.A4.rotate());&lt;/p&gt;
&lt;p&gt;详细代码见示例代码0103。&lt;/p&gt;
&lt;p&gt;u 页边距：&lt;/p&gt;
&lt;p&gt;当创建一个文件时，你还可以定义上、下、左、右页边距：&lt;/p&gt;
&lt;p&gt;Document document = new Document(PageSize.A5, 36, 72, 108, 180);&lt;/p&gt;
&lt;p&gt;在示例代码0104中你可以看到该文档有一个0.5英寸的左边距和1英寸的右边距，上边距为1.5英寸，下边距为2.5英寸。&lt;/p&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;p&gt;当创建一个矩形或设置边距时，你可能希望知道该用什么度量单位：厘米、英寸或象素，事实上，默认的度量系统以排版单位磅为基础得出其他单位的近似值，如1英寸=72磅，如果你想在A4页面的PDF中创建一个矩形，你需要计算以下数据：&lt;/p&gt;
&lt;p&gt;21 厘米 / 2.54 = 8.2677 英寸&lt;/p&gt;
&lt;p&gt;8.2677英寸* 72 = 595 磅&lt;/p&gt;
&lt;p&gt;29.7 厘米 / 2.54 = 11.6929 英寸&lt;/p&gt;
&lt;p&gt;11.6929英寸* 72 = 842 磅&lt;/p&gt;
&lt;p&gt;默认边距为36磅即半英寸。&lt;/p&gt;
&lt;p&gt;如果你修改了页面尺寸，仅仅影响到下一页，如果你修改了页边距，则影响到全部，故慎用。&lt;/p&gt;
&lt;p&gt;关于页面的初始值，请参考第三步。&lt;/p&gt;
&lt;p&gt;第二步 创建Writer实例&lt;br /&gt;
一旦创建了document，我们可以创建该文档的多个Writer的实例，所有这些Writer实例均继承自抽象类“iTextSharp.text.DocWriter”。&lt;/p&gt;
&lt;p&gt;同时还有另外一种情况，你可以用iTextSharp.text.pdf.PdfWriter产生文档PDF文件，如果你想创建一个TeX文档，你可以使用iTextSharp.text.TeX.TeXWriter包。&lt;/p&gt;
&lt;p&gt;Writer类的构造函数是私有的，你只能通过下面的方法创建一个实例：&lt;/p&gt;
&lt;p&gt;public static xxxWriter getInstance(Document document, Stream os); (xxx 是 Pdf 或 Xml)&lt;/p&gt;
&lt;p&gt;你可以通过下面的方法创建一个实例：&lt;/p&gt;
&lt;p&gt;PdfWriter writer = PdfWriter.getInstance(document, new FileStream(&amp;#8221;Chap01xx.pdf&amp;#8221;));&lt;/p&gt;
&lt;p&gt;但是你几乎永远不会用到Writer实例（除非你想创建高级PDF或者希望用一些非常特殊的函数，如ViewerPreferences 或 Encryption）。所以通过下面的办法得到实例已经足够了： PdfWriter.getInstance(document, new FileStream(&amp;#8221;Chap01xx.pdf&amp;#8221;));&lt;/p&gt;
&lt;p&gt;在第一步中创建一个文档时，第一个参数意义不大，第二个参数可以是任何一种流，到目前为止我们一直使用System.IO.FileStream将Document写入文件中，示例代码0105用到了System.IO.MemoryStream（这不是一个独立的例子，你必须在Servlet Engine中测试这些代码。&lt;/p&gt;
&lt;p&gt;第三步 打开Document&lt;/p&gt;
&lt;p&gt;u 摘要&lt;/p&gt;
&lt;p&gt;在你写入任何实际数据之前，你可能希望通过以下几种方法写入一些关于本文档的摘要：&lt;/p&gt;
&lt;p&gt;public boolean addTitle(String title)&lt;/p&gt;
&lt;p&gt;public boolean addSubject(String subject)&lt;/p&gt;
&lt;p&gt;public boolean addKeywords(String keywords)&lt;/p&gt;
&lt;p&gt;public boolean addAuthor(String author)&lt;/p&gt;
&lt;p&gt;public boolean addCreator(String creator)&lt;/p&gt;
&lt;p&gt;public boolean addProducer()&lt;/p&gt;
&lt;p&gt;public boolean addCreationDate()&lt;/p&gt;
&lt;p&gt;public boolean addHeader(String name, String content)&lt;/p&gt;
&lt;p&gt;你可以选择自己的标题、主题、关键字、作者、创建程序，但以下产品信息将始终被添加：iTextSharp (或者iTextSharp的引用)和创建时间（实际上这两种方法是自动调用的）。&lt;/p&gt;
&lt;p&gt;你还可以将自定义的名称添加为“报头信息”，但是这对于PdfWriter没有任何作用，如果看看实例代码0101产生的pdf文件的“文档属性”，我们可以看到仅仅有PDF创建程序和产品日期，而示例代码0106的“文档属性”框中有更多的信息。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;打开document前要做的事：&lt;/p&gt;
&lt;p&gt;你只能在Open方法调用之前添加摘要，这是iText开发工具提供的一个选择。&lt;/p&gt;
&lt;p&gt;在HTML中，报头信息被放在文档前面报头标识中间，调用Open方法将导致报头信息写入流，因而在Document被打开后无法更改这些数据。&lt;/p&gt;
&lt;p&gt;PDF报头信息不包括摘要，看起来有类似于：&lt;/p&gt;
&lt;p&gt;％PDF-1.2&lt;/p&gt;
&lt;p&gt;该行显示生成的文档是一个版本为1.2的PDF格式的文件，在PDF中，摘要保存在PdfInfo对象中，当文档关闭时已经写入PdfWriter中了，因此，没有关于为什么不能修改库来满足任何时候添加或更改摘要的技术原因&lt;/p&gt;
&lt;p&gt;u 页面初始化&lt;/p&gt;
&lt;p&gt;Open方法在不同的Witer中同时会产生初始化事件，举例来说，如果你需要一个水印或者页眉页角对象出现在文档第一页的开始处，你需要在打开文档前添加这些，同样的用于设置该文档其他页水印、页眉、页角、页数和尺寸。&lt;/p&gt;
&lt;p&gt;当调用下列方法：&lt;/p&gt;
&lt;p&gt;public bool setPageSize(Rectangle pageSize)&lt;/p&gt;
&lt;p&gt;public bool Add(Watermark watermark)&lt;/p&gt;
&lt;p&gt;public void removeWatermark()&lt;/p&gt;
&lt;p&gt;setting Header property&lt;/p&gt;
&lt;p&gt;public void resetHeader()&lt;/p&gt;
&lt;p&gt;setting Footer property&lt;/p&gt;
&lt;p&gt;public void resetFooter()&lt;/p&gt;
&lt;p&gt;public void resetPageCount()&lt;/p&gt;
&lt;p&gt;setting PageCount property&lt;/p&gt;
&lt;p&gt;产生的结果只能在下一个新页中看到（当在本页调用初始化方法时），代码见示例代码0107，你必须要准备一张名为watermark.jpg的图片，如下图：&lt;br /&gt;
u 阅读器参数：&lt;/p&gt;
&lt;p&gt;你可以通过下面的办法为PDF文件指定一些阅读器 (如Adobe Reader) 参数：&lt;/p&gt;
&lt;p&gt;public void setViewerPreferences(int preferences)&lt;/p&gt;
&lt;p&gt;在示例代码0108中，指定了下面一些参数：&lt;/p&gt;
&lt;p&gt;writerA.setViewerPreferences(PdfWriter.PageLayoutTwoColumnLeft);&lt;/p&gt;
&lt;p&gt;writerB.setViewerPreferences(PdfWriter.HideMenubar | PdfWriter.HideToolbar);&lt;/p&gt;
&lt;p&gt;writerC.setViewerPreferences(PdfWriter.PageLayoutTwoColumnLeft | PdfWriter.PageModeFullScreen | PdfWriter.NonFullScreenPageModeUseThumbs);&lt;/p&gt;
&lt;p&gt;正如你所看到的，参数可以使用以下一些常量：&lt;/p&gt;
&lt;p&gt;l 文件被打开时，页面布局用到下面的其中一个 ：&lt;/p&gt;
&lt;p&gt;PdfWriter.PageLayoutSinglePage – 同时只显示一个页面&lt;br /&gt;
PdfWriter.PageLayoutOneColumn –单列显示&lt;br /&gt;
PdfWriter.PageLayoutTwoColumnLeft –双列显示,奇数页在左&lt;br /&gt;
PdfWriter.PageLayoutTwoColumnRight -双列显示,奇数页在右&lt;br /&gt;
l 文件打开时，页面模式用到下面其中之一：&lt;/p&gt;
&lt;p&gt;PdfWriter.PageModeUseNone – 既不显示大钢也不显示缩略图&lt;br /&gt;
PdfWriter.PageModeUseOutlines – 显示大纲&lt;br /&gt;
PdfWriter.PageModeUseThumbs – 显示缩略图&lt;br /&gt;
PdfWriter.PageModeFullScreen – 全屏模式，没有菜单、windows控件或者其他任何windows可见控件&lt;br /&gt;
l PdfWriter.HideToolbar – 当文档激活时，是否隐藏阅读程序（如Adobe Reader）的工具条&lt;/p&gt;
&lt;p&gt;l PdfWriter.HideMenubar -当文档激活时，是否隐藏阅读程序的菜单.&lt;/p&gt;
&lt;p&gt;l PdfWriter.HideWindowUI -当文档激活时，是否隐藏阅读程序的界面元素，如滚动条、导航条等，而仅仅保留文档显示&lt;/p&gt;
&lt;p&gt;l PdfWriter.FitWindow – 是否调整文档窗口尺寸以适合显示第一页。&lt;/p&gt;
&lt;p&gt;l PdfWriter.CenterWindow – 是否将文档窗口放到屏幕中央&lt;/p&gt;
&lt;p&gt;l 在全屏模式下，指定如何显示界面元素（选择一个）&lt;/p&gt;
&lt;p&gt;PdfWriter.NonFullScreenPageModeUseNone -既不显示大钢也不显示缩略图&lt;br /&gt;
PdfWriter.NonFullScreenPageModeUseOutlines – 显示大钢&lt;br /&gt;
PdfWriter.NonFullScreenPageModeUseThumbs – 显示缩略图&lt;br /&gt;
说明:你只能在类PdfWriter中调用这些方法。&lt;/p&gt;
&lt;p&gt;u 加密&lt;/p&gt;
&lt;p&gt;打开文档之前还要做的一件事情就是加密（如果你希望该文档加密），要达到这个目的，你可以使用下面的方法：&lt;/p&gt;
&lt;p&gt;public void setEncryption(boolean strength, String userPassword, String ownerPassword, int permissions);&lt;/p&gt;
&lt;p&gt;strength 是下面两个常量之一：&lt;br /&gt;
PdfWriter.STRENGTH40BITS: 40 位&lt;br /&gt;
PdfWriter.STRENGTH128BITS: 128位 (Acrobat Reader 5.0及以上版本支持)&lt;br /&gt;
UserPassword和ownerPassword 可以为空或零长度， 这种情况下， ownerPassword 将被随机的字符串代替&lt;br /&gt;
Permissions 为下列常量之一：&lt;br /&gt;
PdfWriter.AllowPrinting&lt;br /&gt;
PdfWriter.AllowModifyContents&lt;br /&gt;
PdfWriter.AllowCopy&lt;br /&gt;
PdfWriter.AllowModifyAnnotations&lt;br /&gt;
PdfWriter.AllowFillIn&lt;br /&gt;
PdfWriter.AllowScreenReaders&lt;br /&gt;
PdfWriter.AllowAssembly&lt;br /&gt;
PdfWriter.AllowDegradedPrinting&lt;br /&gt;
该功能参见示例代码0109和示例代码0110。&lt;/p&gt;
&lt;p&gt;writer.setEncryption(PdfWriter.STRENGTH40BITS, null, null, PdfWriter.AllowCopy);&lt;/p&gt;
&lt;p&gt;示例代码0109产生的文件能够被打开而无须密码，但用户不能打印、修改本文档。&lt;/p&gt;
&lt;p&gt;writer.setEncryption(PdfWriter.STRENGTH128BITS, &amp;#8220;userpass&amp;#8221;, &amp;#8220;ownerpass&amp;#8221;, PdfWriter.AllowCopy | PdfWriter.AllowPrinting);&lt;/p&gt;
&lt;p&gt;打你试图打开示例代码0110产生的文件时，将要求输入密码（&amp;#8217;userpass&amp;#8217;），因为添加了AllowPrinting参数,你可以打印该文档而不会发生任何问题。&lt;/p&gt;
&lt;p&gt;第四步 添加内容&lt;br /&gt;
在解释第一步到第三步的不同示例中，你可能已经遇到了一些对象如Phrase, Paragraph等 在接下来的几章中，所有这些问题都将得到详细解释。&lt;/p&gt;
&lt;p&gt;有时你可能想一个writer故意忽略document产生的行为，如示例代码0111：&lt;/p&gt;
&lt;p&gt;当我们创建了两个writer： writerA 和 writerB：&lt;/p&gt;
&lt;p&gt;PdfWriter writerA = PdfWriter.getInstance(document, new FileStream(&amp;#8221;Chap0111a.pdf&amp;#8221;, FileMode.Create));&lt;/p&gt;
&lt;p&gt;PdfWriter writerB = PdfWriter.getInstance(document, new FileStream(&amp;#8221;Chap0111b.pdf&amp;#8221;, FileMode.Create));&lt;/p&gt;
&lt;p&gt;我们可以创建两个有细微差别的文档：&lt;/p&gt;
&lt;p&gt;writerA.Pause();&lt;/p&gt;
&lt;p&gt;document.add(new Paragraph(&amp;#8221;This paragraph will only be added to Chap0111b.pdf, not to Chap0111a.pdf&amp;#8221;));&lt;/p&gt;
&lt;p&gt;writerA.resume();&lt;/p&gt;
&lt;p&gt;你可以比较文件: Chap0111a.pdf和Chap0111b.pdf的区别&lt;/p&gt;
&lt;p&gt;第五步，关闭 document&lt;br /&gt;
关闭 document 非常重要, 因为它将关闭正在运行的Writer并将内容写入文件，该方法在最后被调用，你应该总是要关闭文档。&lt;/p&gt;
&lt;p&gt;高级话题：阅读PDF文件&lt;/p&gt;
&lt;p&gt;该部分内容介绍了iText只能产生PDF格式的文件而不能解析PDF格式文件，不再翻译。&lt;/p&gt;
&lt;p&gt;第二章 块、短句和段落&lt;br /&gt;
块&lt;br /&gt;
块(Chunk)是能被添加到文档的文本的最小单位，块可以用于构建其他基础元素如短句、段落、锚点等，块是一个有确定字体的字符串，要添加块到文档中时，其他所有布局变量均要被定义。下面一行中，我们创建了一个内容为“hello World”、红色、斜体、COURIER字体、尺寸20的一个块：&lt;/p&gt;
&lt;p&gt;Chunk chunk = new Chunk(&amp;#8221;Hello world&amp;#8221;, FontFactory.getFont(FontFactory.COURIER, 20, Font.ITALIC, new Color(255, 0, 0)));&lt;/p&gt;
&lt;p&gt;u 典型字体1：&lt;/p&gt;
&lt;p&gt;在本指南中，除了第九章外（你可以在这里学会使用其他字体），我们将始终使用典型字体1，这些是不同的典型字体1：&lt;/p&gt;
&lt;p&gt;· Courier (该字体定宽)&lt;/p&gt;
&lt;p&gt;· Helvetica&lt;/p&gt;
&lt;p&gt;· Times Roman&lt;/p&gt;
&lt;p&gt;· Symbol&lt;/p&gt;
&lt;p&gt;· ZapfDingbats&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;u 下划线/删除线&lt;/p&gt;
&lt;p&gt;如果你希望一些块有下划线或删除线，你可以通过改变字体风格简单做到：&lt;/p&gt;
&lt;p&gt;Chunk chunk1 = new Chunk(&amp;#8221;This text is underlined&amp;#8221;, FontFactory.getFont(FontFactory.HELVETICA, 12, Font.UNDERLINE));&lt;/p&gt;
&lt;p&gt;Chunk chunk2 = new Chunk(&amp;#8221;This font is of type ITALIC | STRIKETHRU&amp;#8221;, FontFactory.getFont(FontFactory.HELVETICA, 12, Font.ITALIC | Font.STRIKETHRU));&lt;/p&gt;
&lt;p&gt;u 上标/下标&lt;/p&gt;
&lt;p&gt;在块中有几个方法可以调用，其中大部分将在接下来的章节中介绍，本章中只介绍一个方法 setTextRise(float f). 你可以使用该方法在上标或下标中写块。&lt;/p&gt;
&lt;p&gt;u 块的背景&lt;/p&gt;
&lt;p&gt;如果你想改变块的背景，你可以使用方法setBackground(Color color). 这将在块文本的下面添加一个彩色矩形：&lt;/p&gt;
&lt;p&gt;ck.setBackground(new Color(0xFF, 0xFF, 0&amp;#215;00));&lt;/p&gt;
&lt;p&gt;在示例代码0101中，你可以概览典型字体1和一个使用setTextRise, setBackground等方法的的例子。&lt;/p&gt;
&lt;p&gt;短句&lt;br /&gt;
短句（Phrases）是一系列以特定间距（两行之间的距离）作为参数的块，一个短句有一个主字体，但短句中的一些块具有不同于主字体的字体，你有更多的选择去创建短句，一些具体使用参见代码0202。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;u 古希腊语&lt;/p&gt;
&lt;p&gt;因为古希腊语经常使用，在类Phrase的构造函数中有一个特征：将一个字符串作为参数（如果你想避免这种情况，你只能使用块工作而不能使用字符串），正如你在示例代码0203中看到的，这个特征自动地将913至937（除903）和945至969（古希腊的ASCII值）范围内的所有字体改为希腊符号。&lt;/p&gt;
&lt;p&gt;u 非主要性&lt;/p&gt;
&lt;p&gt;与其说这是一个特征，不如说是一个缺陷，但无论如何，这使创建一个非主要性的短句或段落成为可能，这将产生一个由下向上书写的临时作用（参见示例代码0204）。如果你想在一页中将一些位置移动到上面时可能有用。&lt;/p&gt;
&lt;p&gt;说明，当你穿越上边届时无法检查，也没有办法让你回到前一页。&lt;/p&gt;
&lt;p&gt;段落&lt;br /&gt;
段落是一系列块和（或）短句。同短句一样，段落有确定的间距。用户还可以指定缩排；在边和（或）右边保留一定空白，段落可以左对齐、右对齐和居中对齐。添加到文档中的每一个段落将自动另起一行。有几种办法建立一个段落，如：&lt;/p&gt;
&lt;p&gt;Paragraph p1 = new Paragraph(new Chunk(&amp;#8221;This is my first paragraph.&amp;#8221;, FontFactory.getFont(FontFactory.HELVETICA, 12)));&lt;/p&gt;
&lt;p&gt;Paragraph p2 = new Paragraph(new Phrase(&amp;#8221;This is my second paragraph.&amp;#8221;, FontFactory.getFont(FontFactory.HELVETICA, 12)));&lt;/p&gt;
&lt;p&gt;Paragraph p3 = new Paragraph(&amp;#8221;This is my third paragraph.&amp;#8221;, FontFactory.getFont(FontFactory.HELVETICA, 12));&lt;/p&gt;
&lt;p&gt;所有有些对象将被添加到段落中：&lt;/p&gt;
&lt;p&gt;p1.add(&amp;#8221;you can add strings, &amp;#8220;); p1.add(new Chunk(&amp;#8221;you can add chunks &amp;#8220;)); p1.add(new Phrase(&amp;#8221;or you can add phrases.&amp;#8221;));&lt;/p&gt;
&lt;p&gt;说明：一个段落有一个且仅有一个间距，如果你添加了一个不同字体的短句或块，原来的间距仍然有效，你可以通过SetLeading来改变间距，但是段落中所有内容将使用新的中的间距。见示例代码0205。&lt;/p&gt;
&lt;p&gt;u 保持段落的整体性&lt;/p&gt;
&lt;p&gt;在示例代码0206中，我们使用了setKeepTogether(true)方法来试图将一个段落放在同一页中，该方法并不是始终有效，举个例子，第一段不能刚好在一页中，于是被分成了两部分。第二段被放置在第二页，但第三段顺沿到了第三页上。&lt;/p&gt;
&lt;p&gt;字体的延续&lt;br /&gt;
你应该掌握字体延续的一些规则，这些规则的应用见示例代码0207，当我们将一些内容用指定的字体（非默认字体）创建一个短句或者段落后再添加更多内容时，初始对象的字体风格将被延续，请看“Hello 1!”和“Hello 2”：&lt;/p&gt;
&lt;p&gt;Phrase myPhrase = new Phrase(&amp;#8221;Hello 2! &amp;#8220;, new Font(Font.TIMES_NEW_ROMAN, 8, Font.BOLD));&lt;/p&gt;
&lt;p&gt;myPhrase.Add(new Phrase(&amp;#8221;some other font &amp;#8220;, new Font(Font.HELVETICA, 8, Font.ITALIC)));&lt;/p&gt;
&lt;p&gt;myPhrase.Add(new Phrase(&amp;#8221;This is the end of the sentence.\n&amp;#8221;, new Font(Font.TIMES_NEW_ROMAN, 8, Font.ITALIC)));&lt;/p&gt;
&lt;p&gt;document.Add(myPhrase);&lt;/p&gt;
&lt;p&gt;我们由Times New Roman 粗体字开始，添加一些文本使用Helvetica字体而不指定风格，我们发现文本被改变成了粗体，当我们再加一些文本使用Times New Roman字体和斜体风格，结果变成了粗斜体。&lt;/p&gt;
&lt;p&gt;如果我们使用FontFactory来创建字体，字体风格不会被延续，因为FontFactory使用了另外的技术构建一个字体：&lt;/p&gt;
&lt;p&gt;myPhrase = new Phrase(&amp;#8221;Hello 1bis! &amp;#8220;, FontFactory.getFont(FontFactory.TIMES_NEW_ROMAN, 8, Font.BOLD));&lt;/p&gt;
&lt;p&gt;myPhrase.Add(new Phrase(&amp;#8221;some other font &amp;#8220;, FontFactory.getFont(FontFactory.HELVETICA, 8, Font.ITALIC)));&lt;/p&gt;
&lt;p&gt;myPhrase.Add(new Phrase(&amp;#8221;This is the end of the sentence.\n&amp;#8221;, FontFactory.getFont(FontFactory.TIMES_NEW_ROMAN, 8, Font.ITALIC)));&lt;/p&gt;
&lt;p&gt;document.Add(myPhrase);&lt;/p&gt;
&lt;p&gt;在上面的代码中，使用Helvetica字体的文本风字体没有指定（既不是粗体也不是斜体）。采用Times New Roman的额外文本仅仅显示为斜体。&lt;/p&gt;
&lt;p&gt;你也看到我们添加了一个段落，添加该段落就如同一个短句。&lt;/p&gt;
&lt;p&gt;Paragraph myParagraph = new Paragraph(&amp;#8221;Hello 1! &amp;#8220;, new Font(Font.TIMES_NEW_ROMAN, 8, Font.BOLD));&lt;/p&gt;
&lt;p&gt;myParagraph.Add(new Paragraph(&amp;#8221;This is the end of the sentence.&amp;#8221;,FontFactory.getFont(new Font.TIMES_NEW_ROMAN, 8)));&lt;/p&gt;
&lt;p&gt;document.Add(myParagraph);&lt;/p&gt;
&lt;p&gt;你可以不这样做，但将失去字体风格的延续，首先不用任何字体创建段落（例中我们仅仅给字体出间距为1.5倍），然后添加内容的不同部分。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;myParagraph = new Paragraph(12);&lt;/p&gt;
&lt;p&gt;myParagraph.Add(new Paragraph(&amp;#8221;Hello 3! &amp;#8220;, new Font(Font.TIMES_NEW_ROMAN, 8, Font.BOLD)));&lt;/p&gt;
&lt;p&gt;myParagraph.Add(new Paragraph(&amp;#8221;This is the end of the sentence.&amp;#8221;, new Font(Font.TIMES_NEW_ROMAN, 8, Font.ITALIC)));&lt;/p&gt;
&lt;p&gt;document.Add(myParagraph);&lt;/p&gt;
&lt;p&gt;如果你使用了Phrase对象，你同样会失去字体风格的延续：&lt;/p&gt;
&lt;p&gt;myPhrase = new Phrase(12);&lt;/p&gt;
&lt;p&gt;myPhrase.Add(new Phrase(&amp;#8221;Hello 4! &amp;#8220;, new Font(Font.TIMES_NEW_ROMAN, 8, Font.BOLD)));&lt;/p&gt;
&lt;p&gt;myPhrase.Add(new Phrase(&amp;#8221;This is the end of the sentence.&amp;#8221;, newFont(Font.TIMES_NEW_ROMAN, 8, Font.ITALIC)));&lt;/p&gt;
&lt;p&gt;document.Add(myPhrase);&lt;/p&gt;
&lt;p&gt;u 更改分割符&lt;/p&gt;
&lt;p&gt;通常，当文本不能放在一行时，文本将被分割成不同的部分，iText首先会查找分割符，如果没有找到，文本将在行尾被截断。有一些预定的分割符如“ ”空格和“-”连字符，但是你可以使用setSplitCharacter方法来覆盖这些默认值。在示例代码0208中，你可以看到当到达行尾时一个块是如何被分割的。然后分隔符被改成点“.”，该行在该字符处被分割。&lt;/p&gt;
&lt;p&gt;第三章 锚点、列表和注释&lt;br /&gt;
锚点&lt;br /&gt;
我们都知道HTML中的超文本链接，当我们点击某些语句，你能够跳转到网上的其他页。在PDF中也可以实现这种功能。事实上，在第十一章整个章节中有关于PDF链接的介绍，但这是iText的更高级的应用，本章中我们处理简单的iText。&lt;/p&gt;
&lt;p&gt;如果你想在文档中添加一个外部链接（例如使用URL链接到WEB上的其他文档），你可以简单地使用Anchor对象，它派生于Phrase对象，使用方法相同。只有两种额外方法定义两种额外变量：setName和 setReference。&lt;/p&gt;
&lt;p&gt;外部链接示例：&lt;/p&gt;
&lt;p&gt;Anchor anchor = new Anchor(&amp;#8221;website&amp;#8221;, FontFactory.getFont(FontFactory.HELVETICA, 12, Font.UNDERLINE, new Color(0, 0, 255)));&lt;/p&gt;
&lt;p&gt;anchor.Reference = &amp;#8220;&lt;a href=&quot;http://itextsharp.sourceforge.net&quot;&gt;http://itextsharp.sourceforge.net&lt;/a&gt;&amp;#8220;;&lt;/p&gt;
&lt;p&gt;anchor.Name = &amp;#8220;website&amp;#8221;;&lt;/p&gt;
&lt;p&gt;如果你想添加内部链接，你需要选择该链接不同的名称，就象你相位在HTML中利用名称作为锚点一样。为达到该目的，你需要添加一个“#”。&lt;/p&gt;
&lt;p&gt;内部链接示例：&lt;/p&gt;
&lt;p&gt;Anchor anchor1 = new Anchor(&amp;#8221;This is an internal link&amp;#8221;);&lt;/p&gt;
&lt;p&gt;anchor1.Name = &amp;#8220;link1&amp;#8243;;&lt;/p&gt;
&lt;p&gt;Anchor anchor2 = new Anchor(&amp;#8221;Click here to jump to the internal link&amp;#8221;);&lt;/p&gt;
&lt;p&gt;anchor.Reference = &amp;#8220;#link1&amp;#8243;;&lt;/p&gt;
&lt;p&gt;这两个链接的例子请见示例代码0301。&lt;/p&gt;
&lt;p&gt;列表&lt;br /&gt;
通过类List 和ListItem，你可以添加列表到PDF文件中，对于列表你还可以选择是否排序。&lt;/p&gt;
&lt;p&gt;排序列表示例：&lt;/p&gt;
&lt;p&gt;List list = new List(true, 20);&lt;/p&gt;
&lt;p&gt;list.Add(new ListItem(&amp;#8221;First line&amp;#8221;));&lt;/p&gt;
&lt;p&gt;list.Add(new ListItem(&amp;#8221;The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?&amp;#8221;));&lt;/p&gt;
&lt;p&gt;list.Add(new ListItem(&amp;#8221;Third line&amp;#8221;));&lt;/p&gt;
&lt;p&gt;结果如下：&lt;/p&gt;
&lt;p&gt;First line&lt;br /&gt;
The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?&lt;br /&gt;
Third line&lt;br /&gt;
不排序示例如下：&lt;/p&gt;
&lt;p&gt;List overview = new List(false, 10);&lt;/p&gt;
&lt;p&gt;overview.Add(new ListItem(&amp;#8221;This is an item&amp;#8221;));&lt;/p&gt;
&lt;p&gt;overview.Add(&amp;#8221;This is another item&amp;#8221;);&lt;/p&gt;
&lt;p&gt;结果如下：&lt;/p&gt;
&lt;p&gt;This is an item&lt;br /&gt;
This is another item&lt;br /&gt;
你可以通过setListSymbol方法更改列表符号：&lt;/p&gt;
&lt;p&gt;// 用字符串作为列表符号&lt;/p&gt;
&lt;p&gt;list1.ListSymbol = &amp;#8220;*&amp;#8221;;&lt;/p&gt;
&lt;p&gt;// 用Chunk 作为列表符号（包含“• ”字符）&lt;/p&gt;
&lt;p&gt;list2.ListSymbol = new Chunk(&amp;#8221;\u2022&amp;#8243;, FontFactory.getFont(FontFactory.HELVETICA, 20));&lt;/p&gt;
&lt;p&gt;//用图片作为列表符号&lt;/p&gt;
&lt;p&gt;list3.ListSymbol = new Chunk(Image.getInstance(&amp;#8221;myBullet.gif&amp;#8221;), 0, 0);&lt;/p&gt;
&lt;p&gt;还可以使用setIndentationLeft和setIndentationRight方法设置缩排，列表符号的缩排在构造函数中设置。更多的例子请参见示例代码0302。&lt;/p&gt;
&lt;p&gt;注释&lt;br /&gt;
iText支持不同风格的注释。&lt;/p&gt;
&lt;p&gt;u 文本注释：&lt;/p&gt;
&lt;p&gt;你可以添加一小段文本到你的文档中，但它并非文档内容的一部分，注释有标题和内容：&lt;/p&gt;
&lt;p&gt;Annotation a = new Annotation(&lt;/p&gt;
&lt;p&gt;&amp;#8220;authors&amp;#8221;,&lt;/p&gt;
&lt;p&gt;&amp;#8220;Maybe it&amp;#8217;s because I wanted to be an author myself that I wrote iText.&amp;#8221;);&lt;/p&gt;
&lt;p&gt;u 外部链接注释：&lt;/p&gt;
&lt;p&gt;你需要指定一个可点击的矩形和一个字符串（URL描述）或URL对象：&lt;/p&gt;
&lt;p&gt;Annotation annot = new Annotation(100f, 700f, 200f, 800f, new URL(&amp;#8221;&lt;a href=&quot;http://www.lowagie.com&quot;&gt;http://www.lowagie.com&lt;/a&gt;&amp;#8220;));&lt;/p&gt;
&lt;p&gt;Annotation annot = new Annotation(100f, 700f, 200f, 800f, &amp;#8220;&lt;a href=&quot;http://www.lowagie.com&quot;&gt;http://www.lowagie.com&lt;/a&gt;&amp;#8220;);&lt;/p&gt;
&lt;p&gt;u 外部PDF文件链接注释：&lt;/p&gt;
&lt;p&gt;你需要指定一个可点击的矩形和一个字符串（文件名称）和目的文件或页码。&lt;/p&gt;
&lt;p&gt;Annotation annot = new Annotation(100f, 700f, 200f, 800f, &amp;#8220;other.pdf&amp;#8221;, &amp;#8220;mark&amp;#8221;);&lt;/p&gt;
&lt;p&gt;Annotation annot = new Annotation(100f, 700f, 200f, 800f, &amp;#8220;other.pdf&amp;#8221;, 2);&lt;/p&gt;
&lt;p&gt;u 指定行为链接注释&lt;/p&gt;
&lt;p&gt;你需要指定一个可点击的矩形和一个指定的行为：&lt;/p&gt;
&lt;p&gt;Annotation annot = new Annotation(100f, 700f, 200f, 800f, PdfAction.FIRSTPAGE);&lt;/p&gt;
&lt;p&gt;u 应用程序链接注释：&lt;/p&gt;
&lt;p&gt;你需要指定一个可点击的矩形和一个应用程序：&lt;/p&gt;
&lt;p&gt;Annotation annot = new Annotation(300f, 700f, 400f, 800f, &amp;#8220;C://winnt/notepad.exe&amp;#8221;, null, null, null);&lt;/p&gt;
&lt;p&gt;我们无须在页面上指定一个位置，iText会内部处理。你能够看到iText添加文本注释在页面上当前位置下面，第一个在段后第一行下面，第二个在短句结束处的下面。&lt;/p&gt;
&lt;p&gt;所有其他注释需要指定想匹配的矩形区域，在示例代码0304中，我们画了一些正方形（使用的函数将在第十章中介绍），为每个正方形添加了一些链接注释。&lt;/p&gt;
&lt;p&gt;第四章 页眉页脚、章节、区域和绘图对象&lt;br /&gt;
使用在第三至第五章中描述的大量简单iText对象可以避免更多的高级话题（第九至十二章），紧记这些简单对象限制的功能，大量复杂的功能在第三部分。&lt;/p&gt;
&lt;p&gt;页眉页脚&lt;br /&gt;
HeaderFooter对象可以于为文档每页添加页眉和页脚。这样一个页眉或页脚包含一个标准的短句（如果需要）和当前页码，如果你需要更多复杂的页眉和页脚（使用表格或者第几页共几页），请阅读第十二章。&lt;/p&gt;
&lt;p&gt;在示例代码0401中，你可以看到我们首先添加了一个包含页码没有任何边框的页脚。&lt;/p&gt;
&lt;p&gt;HeaderFooter footer = new HeaderFooter(new Phrase(&amp;#8221;This is page: &amp;#8220;), true);&lt;/p&gt;
&lt;p&gt;footer.Border = Rectangle.NO_BORDER;&lt;/p&gt;
&lt;p&gt;document.Footer = footer&lt;/p&gt;
&lt;p&gt;我们还可以使用下面的构造函数：&lt;/p&gt;
&lt;p&gt;HeaderFooter footer = new HeaderFooter(new Phrase(&amp;#8221;This is page &amp;#8220;), new Phrase(&amp;#8221;.&amp;#8221;));&lt;/p&gt;
&lt;p&gt;构造函数知道你希望添加一个页码和将其放置在两个短句间，如果你只是设置一个HeaderFooter而不改变边框，页眉或页脚的文本上下各有一条直线。&lt;/p&gt;
&lt;p&gt;HeaderFooter header = new HeaderFooter(new Phrase(&amp;#8221;This is a header without a page number&amp;#8221;), false);&lt;/p&gt;
&lt;p&gt;document.Header = header;&lt;/p&gt;
&lt;p&gt;章节和区域&lt;br /&gt;
在第十一章中将描述如何构建一个树的外观，如果你只需要一个简单的章节和（子）区域，你可以用Chapter对象和Section对象自动构建一个树：&lt;/p&gt;
&lt;p&gt;Paragraph cTitle = new Paragraph(&amp;#8221;This is chapter 1&amp;#8243;, chapterFont);&lt;/p&gt;
&lt;p&gt;Chapter chapter = new Chapter(cTitle, 1);&lt;/p&gt;
&lt;p&gt;Paragraph sTitle = new Paragraph(&amp;#8221;This is section 1 in chapter 1&amp;#8243;, sectionFont);&lt;/p&gt;
&lt;p&gt;Section section = chapter.addSection(sTitle, 1);&lt;/p&gt;
&lt;p&gt;在示例代码0402中，我们添加了一系列的章节和子区域，你可以看到完整的树形，树形结构默认打开，如果你希望部分节点关闭，你必须使用用BookmarkOpen属性其值为false，详见示例代码0403。&lt;/p&gt;
&lt;p&gt;图形&lt;br /&gt;
如果你想添加图形，如直线、圆、几何窗体，你应该阅读读十章，但如果你只需要一些有限的功能，你可以使用Graphic对象&lt;/p&gt;
&lt;p&gt;Graphic grx = new Graphic();&lt;/p&gt;
&lt;p&gt;//添加一个矩形&lt;/p&gt;
&lt;p&gt;grx.rectangle(100, 700, 100, 100);&lt;/p&gt;
&lt;p&gt;// 添加一条斜线&lt;/p&gt;
&lt;p&gt;grx.moveTo(100, 700);&lt;/p&gt;
&lt;p&gt;grx.lineTo(200, 800);&lt;/p&gt;
&lt;p&gt;// 将图形显示出来&lt;/p&gt;
&lt;p&gt;grx.stroke();&lt;/p&gt;
&lt;p&gt;document.Add(grx);&lt;/p&gt;
&lt;p&gt;完整的代码请见示例代码0404，如果想看到全部的方法，请参见PdfContentByte对象API。&lt;/p&gt;
&lt;p&gt;当你想给页面加一个边框或者在文本当前位置画一条水平线时，图形对象非常有用。下面的方法用指定的宽度、间距（如果需要）和颜色画一个边框。&lt;/p&gt;
&lt;p&gt;public void setBorder(float linewidth, float extraSpace);&lt;/p&gt;
&lt;p&gt;public void setBorder(float linewidth, float extraSpace, Color color);&lt;/p&gt;
&lt;p&gt;下面的方法用指定的宽度（如果需要）和颜色画一条水平线，线的长度是指定两边缘间可用面积的的百分比。&lt;/p&gt;
&lt;p&gt;public void setHorizontalLine(float linewidth, float percentage)&lt;/p&gt;
&lt;p&gt;public void setHorizontalLine(float linewidth, float percentage, Color color)&lt;/p&gt;
&lt;p&gt;示例代码5中，有一个离边界5磅，线宽3磅的边框，还有两条水平线，一条为黑色，5磅宽，可用空间的100％，另外一条为红色，线宽3磅，可用空间的80％。&lt;/p&gt;
&lt;p&gt;第五章 表格&lt;br /&gt;
重点：如果你仅仅生成PDF文件（没有XML、HTML、RTF……），使用类pdfPTable代替类Table更好。&lt;/p&gt;
&lt;p&gt;一些简单的表格&lt;br /&gt;
一个表格是包含单元格排列成矩阵的矩形区域。表格的距阵并不要求是m×n的，它可以有空洞或者单元格比单个的要大。&lt;/p&gt;
&lt;p&gt;创建一个表格最通用的办法是预先知道有几行几列：&lt;/p&gt;
&lt;p&gt;public Table(int columns, int rows);&lt;/p&gt;
&lt;p&gt;在示例代码0501中，我们构建了一个简单的表：&lt;/p&gt;
&lt;p&gt;Table aTable = new Table(2,2);&lt;/p&gt;
&lt;p&gt;aTable.addCell(&amp;#8221;0.0&amp;#8243;);&lt;/p&gt;
&lt;p&gt;aTable.addCell(&amp;#8221;0.1&amp;#8243;);&lt;/p&gt;
&lt;p&gt;aTable.addCell(&amp;#8221;1.0&amp;#8243;);&lt;/p&gt;
&lt;p&gt;aTable.addCell(&amp;#8221;1.1&amp;#8243;);&lt;/p&gt;
&lt;p&gt;该表格有两行两列，单元格被自动添加，从第一行第一列开始，然后是第二列，当一行满后，下一单元格自动添加到下一行的第一列中。&lt;/p&gt;
&lt;p&gt;也可以将单元格添加到表中指定的位置，如示例代码0502，别了要添加System.Drawing.dll引用，以获得Point对象，我们创建了一个4行4列的表格然后添加一些单元格到随机的位置上：&lt;/p&gt;
&lt;p&gt;Table aTable = new Table(4,4);&lt;/p&gt;
&lt;p&gt;aTable.AutoFillEmptyCells = true;&lt;/p&gt;
&lt;p&gt;aTable.addCell(&amp;#8221;2.2&amp;#8243;, new Point(2,2));&lt;/p&gt;
&lt;p&gt;aTable.addCell(&amp;#8221;3.3&amp;#8243;, new Point(3,3));&lt;/p&gt;
&lt;p&gt;aTable.addCell(&amp;#8221;2.1&amp;#8243;, new Point(2,1));&lt;/p&gt;
&lt;p&gt;aTable.addCell(&amp;#8221;1.3&amp;#8243;, new Point(1,3));&lt;/p&gt;
&lt;p&gt;你可以看到我们将AutoFillEmptyCells属性设置为true，这将自动、默认的单元格布局填充空的单元格，如果我们忘记了这样做（就象本例中第二个表格），将没有额外的单元格添加，不包含任何单格的行也将被忽略，在本例中，第一行将不显示，因为该行是空行。&lt;/p&gt;
&lt;p&gt;经常用数据库查询结果来填充表格，大多数情况下，你预先并不知道到底需要多少行，这就是为什么还有第二个构造函数的原因：&lt;/p&gt;
&lt;p&gt;public Table(int columns);&lt;/p&gt;
&lt;p&gt;iText根据需要自动添加行，在示例代码0503中，初始化了4行4列，当我们添加第6行和第7行的单元格时，iText自动增加行数到7。&lt;/p&gt;
&lt;p&gt;增加列数也是可能的，但是有点麻烦，它不能自动生成，你必须使用addColumns方法并设置列宽，详见示例代码0504。&lt;/p&gt;
&lt;p&gt;一些表格参数&lt;br /&gt;
前面例子中的表格并不美观，我们可以设置大量的参数来改变表格外观。类Table和类Cell派生于类Rectangle，我们可以用大量典型的Rectangle方法，让我们来看看示例代码0505。&lt;/p&gt;
&lt;p&gt;Table table = new Table(3);&lt;/p&gt;
&lt;p&gt;table.BorderWidth = 1;&lt;/p&gt;
&lt;p&gt;table.BorderColor = new Color(0, 0, 255);&lt;/p&gt;
&lt;p&gt;table.Cellpadding = 5;&lt;/p&gt;
&lt;p&gt;5. table.Cellspacing = 5;&lt;/p&gt;
&lt;p&gt;Cell cell = new Cell(&amp;#8221;header&amp;#8221;);&lt;/p&gt;
&lt;p&gt;cell.Header = true;&lt;/p&gt;
&lt;p&gt;cell.Colspan = 3;&lt;/p&gt;
&lt;p&gt;table.addCell(cell);&lt;/p&gt;
&lt;p&gt;10. cell = new Cell(&amp;#8221;example cell with colspan 1 and rowspan 2&amp;#8243;);&lt;/p&gt;
&lt;p&gt;cell.Rowspan = 2;&lt;/p&gt;
&lt;p&gt;cell.BorderColor = new Color(255, 0, 0);&lt;/p&gt;
&lt;p&gt;table.addCell(cell);&lt;/p&gt;
&lt;p&gt;table.addCell(&amp;#8221;1.1&amp;#8243;);&lt;/p&gt;
&lt;p&gt;15. table.addCell(&amp;#8221;2.1&amp;#8243;);&lt;/p&gt;
&lt;p&gt;table.addCell(&amp;#8221;1.2&amp;#8243;);&lt;/p&gt;
&lt;p&gt;table.addCell(&amp;#8221;2.2&amp;#8243;);&lt;/p&gt;
&lt;p&gt;table.addCell(&amp;#8221;cell test1&amp;#8243;);&lt;/p&gt;
&lt;p&gt;cell = new Cell(&amp;#8221;big cell&amp;#8221;);&lt;/p&gt;
&lt;p&gt;20. cell.Rowspan = 2;&lt;/p&gt;
&lt;p&gt;cell.Colspan = 2;&lt;/p&gt;
&lt;p&gt;cell.BackgroundColor = new Color(0xC0, 0xC0, 0xC0);&lt;/p&gt;
&lt;p&gt;table.addCell(cell);&lt;/p&gt;
&lt;p&gt;table.addCell(&amp;#8221;cell test2&amp;#8243;);&lt;/p&gt;
&lt;p&gt;25. document.Add(table);&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;u 单元格间距和填距&lt;/p&gt;
&lt;p&gt;在第4行中，我们设置了表格的填距，就是单元格边界和内容间一定数量的空间，在前面的示例中，我们看到文本紧贴边界，通过使用用特定的填距，就可以避免。&lt;/p&gt;
&lt;p&gt;在第5行中，我们设置了表格的间距，就是单元格和表格边界间的一定数量的空间，不同的单元格间使用了半数空间，具体代码见示例代码0506。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/239308530/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=397&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308530/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308530/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://blog.zbaccp.com/?feed=rss2&amp;p=397</wfw:commentRss><description>丽水市汽车运输集团有限公司信息中心 苟安廷
PDF文件是目前比较流行的电子文档格式，在办公自动化（OA）等软件的开发中，经常要用到该格式，但介绍如何制作PDF格式文件的资料非常少，在网上搜来搜去，都转贴的是同一段“暴力”破解的方法，代码片断如下：
StreamWriter pPDF=new StreamWriter(filePath);
ArrayList xRefs=new ArrayList();
float yPos =0f;
long streamStart=0;
long streamEnd=0;
long streamLen =0;
string strPDFMessage=null;
//PDF文档头信息
strPDFMessage=&amp;#8221;％PDF-1.1\n&amp;#8221;;
ConvertToByteAndAddtoStream(strPDFMessage);
 
xRefs.Add(mPDF.Length);
strPDFMessage=&amp;#8221;1 0 obj\n&amp;#8221;;
ConvertToByteAndAddtoStream(strPDFMessage);
strPDFMessage=&amp;#8221;&amp;#60;&amp;#60; /Length 2 0 R &amp;#62;&amp;#62;\n&amp;#8221;;
ConvertToByteAndAddtoStream(strPDFMessage);
strPDFMessage=&amp;#8221;stream\n&amp;#8221;;
ConvertToByteAndAddtoStream(strPDFMessage);
……
看了上面的制作办法，我眼镜都摔坏了三幅，如果用上面这样原始的办法能制作出满意的PDF文件，那一定是天才所为。后来，我从一个网站（网址：http://itextsharp.sourceforge.net/index.html）中看到了专门制作PDF文件的控件的介绍，暗喜之余，立马下载试验，果然非常轻松地制作出了想要的PDF文件，因为网站为英文，内容又多，读起来非常费力，在解决了自己的问题后，看到许多网友还在为PDF文件制作而郁闷，遂决定将该内容翻译为中文，由于本人英语水平一般，许多地方又晦涩难懂，故翻译质量不是很满意，敬请斧正，但大部分能看懂。本文的目的一是解决部分网友的燃眉之急，二是抛砖引玉，如果哪位仁兄愿意将该网站中的内容准确翻译出来，则是天下之大幸。
要用本文的方法生成PDF文件，需要两个控件：itextsharp.dll和ICSharpCode.SharpZipLib.dll，由于示例代码实在太多，我将代码全部整理出来，放在另外一个文件“示例代码.doc”中，所有这些资源，我均放在了本人的ftp站点（ftp://202.107.251.26）上的“Pdf文件制作全攻略”文件夹中（文件夹中另外两个rar压缩文件为两个控件的源代码，供大家学习研究使用），你可以到这里下载相应的资源，或者直接到原网站下载。
为便于调试和叙述，所有例子均为DOS控制台程序，windows程序使用方法完全一样，按照下面的步骤创建一个可调试的项目：
1、 打开VS2003；
2、 单击菜单“文件”→“新建”→“项目”，在项目类型中选择“Visual C#项目”，在模板中选择“控制台应用程序”，输入文件名称如“MakePdf”，指定好存放路径，然后点确定按钮；
3、 在“解决方案资源管理器”中右键单击“引用”，从弹出的菜单中选择“添加引用”，在“.NET”选项夹中选择“浏览”，添加前面提到的两个应用，如下图：
4、 在代码窗口顶部添加两个引用：
using iTextSharp.text;
using iTextSharp.text.pdf;
至此，准备工作完毕。
 
第一部分 iText的简单应用
第一章 创建一个Document
利用iText五步创建一个PDF文件：helloword。
第一步，创建一个 iTextSharp.text.Document对象的实例：
Document document = new Document();
第二步，为该Document创建一个Writer实例：
PdfWriter.getInstance(document, new FileStream(&amp;#8221;Chap0101.pdf&amp;#8221;, FileMode.Create));
第三步，打开当前Document
document.Open();
第四步，为当前Document添加内容：
document.Add(new Paragraph(&amp;#8221;Hello World&amp;#8221;));
第五步，关闭Document
document.Close();
完整的代码见示例代码0101。
在例中，不难看出，制作一个PDF文件是非常简单的。
注：如果你将例中“document.Add(new Paragraph(&amp;#8221;Hello World&amp;#8221;)); ”中的字符串“Hello Word”换成中文，如“这是我的第一个PDF文件”，产生的结果一定让你大失所望，因为生成的PDF文件中并没有将中文显示出来，不要担心，在第9章中要专门讲解字体问题，中文显示也就迎刃而解了，如果不能正确显示中文，也就没有必要翻译本文了。
下面对这几步做详细介绍。
第一步 创建一个Document实例：
iTextSharp.text.Document-object共有三个构造函数：
public Document();
public Document(Rectangle pageSize);
public Document(Rectangle pageSize,
int marginLeft,
int marginRight,
int marginTop,
int marginBottom);
第一个构造函数以A4页面作为参数调用第二个构造函数，第二个构造函数以每边36磅页边距为参数调用第三个构造函数
u 页面尺寸：
你可以通过指定的颜色和大小创建你自己的页面，示例代码0102创建一个细长的浅黄色背景的页面：
Rectangle pageSize [...]&lt;img src=&quot;http://www1.feedsky.com/t1/239308530/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=397&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308530/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308530/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>默认</category><pubDate>Wed, 01 Jul 2009 08:26:04 +0800</pubDate><author>吃鱼不吐刺</author><comments>http://blog.zbaccp.com/?p=397#comments</comments><guid isPermaLink="false">http://blog.zbaccp.com/?p=397</guid><dc:creator>吃鱼不吐刺</dc:creator><fs:srclink>http://blog.zbaccp.com/?p=397</fs:srclink><fs:srcfeed>http://blog.zbaccp.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/zbaccp/~7524155/239308530/5633121</fs:itemid></item><item><title>面试中的十二个“高级”错误，求职者不得不知</title><link>http://blog.zbaccp.com/?p=395</link><content:encoded>&lt;p&gt;　　在求职 面试 中，没有人能保证不犯错误。只是聪明的求职者会不断地修正错误走向成熟。然而在 面试 中有些错误却是一些相当聪明的求职者也难免会一犯再犯的，我们权称之为“高级”错误。某跨国公司人力资源管理专家总结经验，列举出常见的十二种“高级”错误，以飨读者。&lt;/p&gt;
&lt;p&gt;　　不善于打破沉默&lt;/p&gt;
&lt;p&gt;　　 面试 开始时，应试者不善“破冰”(即打破沉默)，而等待面试官打开话匣。面试中，应试者又出于种种顾虑，不愿主动说话，结果使面试出现冷场。即便能勉强打破沉默，语音语调亦极生硬，使场面更显尴尬。实际上，无论是面试前或面试中，面试者主动致意与交谈，会留给面试官热情和善于与人交谈的良好印象。&lt;/p&gt;
&lt;p&gt;　　与面试官“套近乎”&lt;/p&gt;
&lt;p&gt;　　具备一定专业素养的面试官是忌讳与应试者套近乎的，因为面试中双方关系过于随便或过于紧张都会影响面试官的评判。过分“套近乎”亦会在客观上妨碍应试者在短短的面试时间内，做好专业经验与技能的陈述。聪明的应试者可以例举一至两件有根有据的事情来赞扬招聘单位，从而表现出您对这家公司的兴趣。&lt;/p&gt;
&lt;p&gt;　　为偏见或成见所左右&lt;/p&gt;
&lt;p&gt;　　有时候，参加面试前自己所了解的有关面试官或该招聘单位的负面评价会左右自己面试中的思维。误认为貌似冷淡的面试官或是严厉或是对应试者不满意，因此十分紧张。还有些时候，面试官是一位看上去比自己年轻许多的小姐，心中便开始嘀咕：“她怎么能有资格面试我呢?”其实，在招聘面试这种特殊的采购关系中，应试者作为供方，需要积极面对不同风格的面试官即客户。一个真正的销售员在面对客户的时候，他的态度是无法选择的。&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年中换了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;　　对个人职业发展计划模糊&lt;/p&gt;
&lt;p&gt;　　对个人职业发展计划，很多人只有目标，没有思路。比如当问及“您未来5年事业发展计划如何?”时，很多人都会回答说“我希望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年之内逃税1000万元，那您会怎么做?”如果您当场抓耳搔腮地思考逃税计谋，或文思泉涌，立即列举出一大堆方案，都证明您上了他们的圈套。实际上，在几乎所有的国际化大企业中，遵纪守法是员工行为的最基本要求。&lt;/p&gt;
&lt;p&gt;　　主动打探薪酬福利&lt;/p&gt;
&lt;p&gt;　　有些应试者会在面试快要结束时主动向面试官打听该职位的薪酬福利等情况，结果是欲速则不达。具备人力资源专业素养的面试者是忌讳这种行为的。其实，如果招聘单位对某一位应试者感兴趣的话，自然会问及其薪酬情况。&lt;/p&gt;
&lt;p&gt;　　不知如何收场&lt;/p&gt;
&lt;p&gt;　　很多求职应试者面试结束时，或因成功的兴奋，或因失败的恐惧，会语无伦次，手足无措。其实，面试结束时，作为应试者，您不妨表达您对应聘职位的理解;充满热情地告诉面试者您对此职位感兴趣，并询问下一步是什么;面带微笑和面试官握手并感谢面试官的接待及对您的考虑。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/239308549/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=395&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308549/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308549/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://blog.zbaccp.com/?feed=rss2&amp;p=395</wfw:commentRss><description>　　在求职 面试 中，没有人能保证不犯错误。只是聪明的求职者会不断地修正错误走向成熟。然而在 面试 中有些错误却是一些相当聪明的求职者也难免会一犯再犯的，我们权称之为“高级”错误。某跨国公司人力资源管理专家总结经验，列举出常见的十二种“高级”错误，以飨读者。
　　不善于打破沉默
　　 面试 开始时，应试者不善“破冰”(即打破沉默)，而等待面试官打开话匣。面试中，应试者又出于种种顾虑，不愿主动说话，结果使面试出现冷场。即便能勉强打破沉默，语音语调亦极生硬，使场面更显尴尬。实际上，无论是面试前或面试中，面试者主动致意与交谈，会留给面试官热情和善于与人交谈的良好印象。
　　与面试官“套近乎”
　　具备一定专业素养的面试官是忌讳与应试者套近乎的，因为面试中双方关系过于随便或过于紧张都会影响面试官的评判。过分“套近乎”亦会在客观上妨碍应试者在短短的面试时间内，做好专业经验与技能的陈述。聪明的应试者可以例举一至两件有根有据的事情来赞扬招聘单位，从而表现出您对这家公司的兴趣。
　　为偏见或成见所左右
　　有时候，参加面试前自己所了解的有关面试官或该招聘单位的负面评价会左右自己面试中的思维。误认为貌似冷淡的面试官或是严厉或是对应试者不满意，因此十分紧张。还有些时候，面试官是一位看上去比自己年轻许多的小姐，心中便开始嘀咕：“她怎么能有资格面试我呢?”其实，在招聘面试这种特殊的采购关系中，应试者作为供方，需要积极面对不同风格的面试官即客户。一个真正的销售员在面对客户的时候，他的态度是无法选择的。
　　慷慨陈词，却举不出例子
　　应试者大谈个人成就、特长、技能时，聪明的面试官一旦反问：“能举一两个例子吗”?应试者便无言应对。而面试官恰恰认为，事实胜于雄辩。在面试中，应试者要想以其所谓的沟通能力、解决问题的能力、团队合作能力，领导能力等取信于人，唯有举例。
　　缺乏积极态势
　　面试官常常会提出或触及一些让应试者难为情的事情。很多人对此面红耳赤，或躲躲闪闪，或撒谎敷衍，而不是诚实的回答、正面的解释。比方说面试官问：您为什么5年中换了3次工作?有人可能就会大谈工作如何困难，上级不支持等，而不是告诉面试官：虽然工作很艰难，自己却因此学到了很多，也成熟了很多。
　　丧失专业风采
　　有些应试者面试时各方面表现良好，可一旦被问及现所在公司或以前公司时，就会愤怒地抨击其老板或者公司，甚至大肆谩骂。在众多国际化的大企业中，或是在具备专业素养的面试官面前，这种行为是非常忌讳的。
　　不善于提问
　　有些人在不该提问时提问，如面试中打断面试官谈话而提问。也有些人面试前对提问没有足够准备，轮到有提问机会时却不知说什么好。而事实上，一个好的提问，胜过 简历 中的无数笔墨，会让面试官刮目相看。
　　对个人职业发展计划模糊
　　对个人职业发展计划，很多人只有目标，没有思路。比如当问及“您未来5年事业发展计划如何?”时，很多人都会回答说“我希望5年之内做到全国销售总监一职。“如果面试官接着问”为什么”，应试者常常会觉得莫名其妙。其实，任何一个具体的职业发展目标都离不开您对个人目前技能的评估以及您为胜任职业目标所需拟定的粗线条的技能发展计划。
　　假扮完美
　　面试官常常会问：“您性格上有什么弱点?您在事业上受过挫折吗?”有人会毫不犹豫地回答：没有。其实这种回答常常是对自己不负责任的。没人没有弱点，没人没有受过挫折。只有充分地认识到自己的弱点，也只有正确地认识自己所受的挫折，才能造就真正成熟的人格。
　　被“引君入瓮”
　　面试官有时会考核应试者的商业判断能力及商业道德方面的素养。比如：面试官在介绍公司诚实守信的企业文化之后或索性什么也不介绍，问：“您作为财务经理，如果我(总经理)要求您1年之内逃税1000万元，那您会怎么做?”如果您当场抓耳搔腮地思考逃税计谋，或文思泉涌，立即列举出一大堆方案，都证明您上了他们的圈套。实际上，在几乎所有的国际化大企业中，遵纪守法是员工行为的最基本要求。
　　主动打探薪酬福利
　　有些应试者会在面试快要结束时主动向面试官打听该职位的薪酬福利等情况，结果是欲速则不达。具备人力资源专业素养的面试者是忌讳这种行为的。其实，如果招聘单位对某一位应试者感兴趣的话，自然会问及其薪酬情况。
　　不知如何收场
　　很多求职应试者面试结束时，或因成功的兴奋，或因失败的恐惧，会语无伦次，手足无措。其实，面试结束时，作为应试者，您不妨表达您对应聘职位的理解;充满热情地告诉面试者您对此职位感兴趣，并询问下一步是什么;面带微笑和面试官握手并感谢面试官的接待及对您的考虑。&lt;img src=&quot;http://www1.feedsky.com/t1/239308549/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=395&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308549/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308549/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>默认</category><pubDate>Tue, 30 Jun 2009 15:25:52 +0800</pubDate><author>student</author><comments>http://blog.zbaccp.com/?p=395#comments</comments><guid isPermaLink="false">http://blog.zbaccp.com/?p=395</guid><dc:creator>student</dc:creator><fs:srclink>http://blog.zbaccp.com/?p=395</fs:srclink><fs:srcfeed>http://blog.zbaccp.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/zbaccp/~7524155/239308549/5633121</fs:itemid></item><item><title>实现C语言高效编程的办法</title><link>http://blog.zbaccp.com/?p=392</link><content:encoded>&lt;p&gt;编写高效简洁的C语言代码，是许多软件工程师追求的目标。本文就工作中的一些体会和经验做相关的阐述，不对的地方请各位指教。&lt;/p&gt;
&lt;p&gt;　　第1招：以空间换时间&lt;/p&gt;
&lt;p&gt;　　计算机程序中最大的矛盾是空间和时间的矛盾，那么，从这个角度出发逆向思维来考虑程序的效率问题，我们就有了解决问题的第1招——以空间换时间。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;　　例如：字符串的赋值。&lt;br /&gt;
　　方法A，通常的办法：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.mscto.com/&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;#define LEN 32&lt;br /&gt;
char string1 [LEN];&lt;br /&gt;
memset (string1,0,LEN);&lt;br /&gt;
strcpy (string1,“This is a example!!”）;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;　　方法B：&lt;/p&gt;
&lt;p&gt;const char string2[LEN] =“This is a example!”;&lt;br /&gt;
char * cp;&lt;br /&gt;
cp = string2 ;&lt;br /&gt;
(使用的时候可以直接用指针来操作。)&lt;br /&gt;
　　从上面的例子可以看出，A和B的效率是不能比的。在同样的存储空间下，B直接使用指针就可以操作了，而A需要调用两个字符函数才能完成。B的缺点在于灵活性没有A好。在需要频繁更改一个字符串内容的时候，A具有更好的灵活性；如果采用方法B，则需要预存许多字符串，虽然占用了大量的内存，但是获得了程序执行的高效率。&lt;/p&gt;
&lt;p&gt;　　如果系统的实时性要求很高，内存还有一些，那我推荐你使用该招数。&lt;/p&gt;
&lt;p&gt;　　该招数的变招——使用宏函数而不是函数。举例如下：&lt;/p&gt;
&lt;p&gt;　　方法C：&lt;/p&gt;
&lt;p&gt;#define bwMCDR2_ADDRESS 4&lt;br /&gt;
#define bsMCDR2_ADDRESS 17&lt;br /&gt;
int BIT_MASK(int __bf)&lt;br /&gt;
{&lt;br /&gt;
　return ((1U &amp;lt;&amp;lt; (bw ## __bf)) - 1) &amp;lt;&amp;lt; (bs ## __bf);&lt;br /&gt;
}&lt;br /&gt;
void SET_BITS(int __dst, int __bf, int __val)&lt;br /&gt;
{&lt;br /&gt;
　__dst = ((__dst) &amp;amp; ~(BIT_MASK(__bf))) | \(((__val) &amp;lt;&amp;lt; (bs ## __bf)) &amp;amp; (BIT_MASK(__bf))))&lt;br /&gt;
}&lt;br /&gt;
SET_BITS(MCDR2, MCDR2_ADDRESS, RegisterNumber);&lt;br /&gt;
　　方法D：&lt;br /&gt;
#define bwMCDR2_ADDRESS 4&lt;br /&gt;
#define bsMCDR2_ADDRESS 17&lt;br /&gt;
#define bmMCDR2_ADDRESS BIT_MASK(MCDR2_ADDRESS)&lt;br /&gt;
#define BIT_MASK(__bf) (((1U &amp;lt;&amp;lt; (bw ## __bf)) - 1) &amp;lt;&amp;lt; (bs ## __bf))&lt;br /&gt;
#define SET_BITS(__dst, __bf, __val) \&lt;br /&gt;
((__dst) = ((__dst) &amp;amp; ~(BIT_MASK(__bf))) | \&lt;br /&gt;
(((__val) &amp;lt;&amp;lt; (bs ## __bf)) &amp;amp; (BIT_MASK(__bf))))&lt;/p&gt;
&lt;p&gt;SET_BITS(MCDR2, MCDR2_ADDRESS, RegisterNumber);&lt;br /&gt;
　　函数和宏函数的区别就在于，宏函数占用了大量的空间，而函数占用了时间。大家要知道的是，函数调用是要使用系统的栈来保存数据的，如果编译器里有栈检查选项，一般在函数的头会嵌入一些汇编语句对当前栈进行检查；同时，CPU也要在函数调用时保存和恢复当前的现场，进行压栈和弹栈操作，所以，函数调用需要一些CPU时间。而宏函数不存在这个问题。宏函数仅仅作为预先写好的代码嵌入到当前程序，不会产生函数调用，所以仅仅是占用了空间，在频繁调用同一个宏函数的时候，该现象尤其突出。　　D方法是我看到的最好的置位操作函数，是ARM公司源码的一部分，在短短的三行内实现了很多功能，几乎涵盖了所有的位操作功能。C方法是其变体，其中滋味还需大家仔细体会。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;　　第2招：数学方法解决问题&lt;br /&gt;
　　现在我们演绎高效C语言编写的第二招——采用数学方法来解决问题。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;　　数学是计算机之母，没有数学的依据和基础，就没有计算机的发展，所以在编写程序的时候，采用一些数学方法会对程序的执行效率有数量级的提高。&lt;br /&gt;
　　举例如下，求 1~100的和。&lt;/p&gt;
&lt;p&gt;　　方法E&lt;/p&gt;
&lt;p&gt;int I , j;&lt;br /&gt;
for (I = 1 ;I&amp;lt;=100; I ++）{&lt;br /&gt;
　j += I;&lt;br /&gt;
}&lt;br /&gt;
　　方法F&lt;/p&gt;
&lt;p&gt;int I;&lt;br /&gt;
I = (100 * (1+100)) / 2&lt;/p&gt;
&lt;p&gt;　　这个例子是我印象最深的一个数学用例，是我的计算机启蒙老师考我的。当时我只有小学三年级，可惜我当时不知道用公式 N×（N+1）/ 2 来解决这个问题。方法E循环了100次才解决问题，也就是说最少用了100个赋值，100个判断，200个加法（I和j）；而方法F仅仅用了1个加法，1 次乘法，1次除法。效果自然不言而喻。所以，现在我在编程序的时候，更多的是动脑筋找规律，最大限度地发挥数学的威力来提高程序运行的效率。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/239308558/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=392&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308558/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308558/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://blog.zbaccp.com/?feed=rss2&amp;p=392</wfw:commentRss><description>编写高效简洁的C语言代码，是许多软件工程师追求的目标。本文就工作中的一些体会和经验做相关的阐述，不对的地方请各位指教。
　　第1招：以空间换时间
　　计算机程序中最大的矛盾是空间和时间的矛盾，那么，从这个角度出发逆向思维来考虑程序的效率问题，我们就有了解决问题的第1招——以空间换时间。
 
　　例如：字符串的赋值。
　　方法A，通常的办法：

#define LEN 32
char string1 [LEN];
memset (string1,0,LEN);
strcpy (string1,“This is a example!!”）;
 
　　方法B：
const char string2[LEN] =“This is a example!”;
char * cp;
cp = string2 ;
(使用的时候可以直接用指针来操作。)
　　从上面的例子可以看出，A和B的效率是不能比的。在同样的存储空间下，B直接使用指针就可以操作了，而A需要调用两个字符函数才能完成。B的缺点在于灵活性没有A好。在需要频繁更改一个字符串内容的时候，A具有更好的灵活性；如果采用方法B，则需要预存许多字符串，虽然占用了大量的内存，但是获得了程序执行的高效率。
　　如果系统的实时性要求很高，内存还有一些，那我推荐你使用该招数。
　　该招数的变招——使用宏函数而不是函数。举例如下：
　　方法C：
#define bwMCDR2_ADDRESS 4
#define bsMCDR2_ADDRESS 17
int BIT_MASK(int __bf)
{
　return ((1U &amp;#60;&amp;#60; (bw ## __bf)) - 1) &amp;#60;&amp;#60; (bs ## __bf);
}
void SET_BITS(int __dst, int __bf, int __val)
{
　__dst = ((__dst) &amp;#38; ~(BIT_MASK(__bf))) &amp;#124; \(((__val) &amp;#60;&amp;#60; (bs ## __bf)) &amp;#38; [...]&lt;img src=&quot;http://www1.feedsky.com/t1/239308558/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=392&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308558/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308558/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>默认</category><pubDate>Tue, 30 Jun 2009 14:18:24 +0800</pubDate><author>吃鱼不吐刺</author><comments>http://blog.zbaccp.com/?p=392#comments</comments><guid isPermaLink="false">http://blog.zbaccp.com/?p=392</guid><dc:creator>吃鱼不吐刺</dc:creator><fs:srclink>http://blog.zbaccp.com/?p=392</fs:srclink><fs:srcfeed>http://blog.zbaccp.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/zbaccp/~7524155/239308558/5633121</fs:itemid></item><item><title>高效能人的七个习惯</title><link>http://blog.zbaccp.com/?p=391</link><content:encoded>&lt;p&gt;惯一：别指望谁能推着你走 &lt;/p&gt;
&lt;p&gt;如果你不向前走，谁又会推你走呢？因此，积极主动的态度，是实现个人目标的原则。 &lt;/p&gt;
&lt;p&gt;我们常说，“我不会······因为遗传······”、“我迟到、因为······”、“我的计划没完成、因为······等等，我们总在找借口或是抱怨，在不满中消耗自己的生命。而人类和动物的区别正是人能主动积极地创造、实现梦想，来提升我们的生命品质。所以，有效能的人士为自己的行为及一生所做的选择负责，自主选择应对外界环境的态度和方法；他们致力于实现有能力控制的事情，而不是被动地忧虑那些没法用能力控制或难以控制的事情；他们通过能力提升效能，从而扩展自身的关注范围和影响范围。 &lt;/p&gt;
&lt;p&gt;积极的心态能让你拥有“选择的自由”。我们虽然不能控制客观环境，但我们可以选择对客观现实做何种反应。积极的涵义不仅仅是采取行动，还代表对自己负责的态度。个人行为取决于自身，而非外部环境，并且人有能力也有责任创造有利的外在环境。 &lt;/p&gt;
&lt;p&gt;习惯二：忠诚于自己的人生计划 &lt;/p&gt;
&lt;p&gt;我们经常在人生的道路上迷失方向，因徘徊和迷途消耗了生命。而高效能的人懂得设计自己的未来。他们认真地计划自己要成为什么人，想做些什么，要拥有什么，并且清晰明确的写出，以此作为决策指导。因此，“以终为始”是实现自我领导的原则。这将确保自己的行为和目标保持一致，并不受其他人的或外界环境的影响。我们将这个书面计划称之为“使命宣言”。 &lt;/p&gt;
&lt;p&gt;任何一个存在的社会组织都需要“使命宣言”，任何一个企业或个人也不例外。“使命宣言”需要阶段性地评估以及持续修正和改良。 &lt;/p&gt;
&lt;p&gt;确立目标后全力以赴，就是我们所说的在正确的时间做正确的事，并把事情做对，为什么很多人成功了反而感到失落？许多人在埋头苦干时，尚未发掘人生的终极目标，只是为忙碌而忙碌着，未曾洞悉自己心灵深处的所欲所求，也不曾审视过自己的人生信条：你到底要做什么？什么是你生命中最重要的？你生活的重心是什么？只有确立了符合价值观的人生目标，才能凝聚意志力，全力以赴且持之以恒地付诸实现，才有可能获得内心最大的满足。 &lt;/p&gt;
&lt;p&gt;习惯三：选择不做什么更难 &lt;/p&gt;
&lt;p&gt;每个人的时间都是有限的，所以要做重要的事，即你觉得有价值并对你的生命价值、最高目标具有贡献的事情；要少做紧急的事，也就是你或别人认为需要立刻解决的事。消防队的最大贡献应是做好防火工作，而不只是忙于到处救火。因此，“要事第一”是自我管理的原则。 &lt;/p&gt;
&lt;p&gt;有效能的人只会少量非常重要且需立即处理的紧急、危机事件，他们将工作焦点放在重要但不紧急的事情上，来保持效益与将近率平衡。 &lt;/p&gt;
&lt;p&gt;“有效管理”是把最重要的事放在第一位的重点管理。先由领导决定什么是重点后，自己撑握住重点并时刻把它放在第一位，以免被感觉、情绪或冲动左右。要想集中精力于当前的要务，就必须先排除次要事情的牵绊，要勇于说“不”。 &lt;/p&gt;
&lt;p&gt;习惯四：远离角斗场的时代 &lt;/p&gt;
&lt;p&gt;懂得利人利已的人，把生活看做一个合作的舞台，而不是角斗场，。一般人遇事多用二分法：非强即弱，非胜即败。其实，世界给了每个人足够的立足空间，他人之得并非自己之失。因此，“双赢思维”成为人际关系的原则。 &lt;/p&gt;
&lt;p&gt;我们从小就参加各种比赛、考试，培养了一种你赢我输、你死我活的竞争心态。试想一下，谁又甘心在竞赛中认输呢？树立双赢思维就是要在人际交往中不断寻求互利，以达成双方都满意的并致力于合作的协议计划。 &lt;/p&gt;
&lt;p&gt;具有双赢思维的人，往往有三种人性品格：正直、成熟和富足心态。他们忠于自己的感受、价值观和承诺，有勇气表达自己的想法及感觉，能以豁达体谅的心态看待别人的想法及体验，相信世界有足够的发展资源和空间，人人都能共享。 &lt;/p&gt;
&lt;p&gt;利人利已观念的形成是以诚信、成熟、豁达的品格基础的。豁达的胸襟源自于个人崇高的价值观与自信和安全感，所以不怕与人共名声、共财势，从而肯于尝试无限的可能性，充分发挥创造力和宽广的选择空间。 &lt;/p&gt;
&lt;p&gt;习惯五：换位思考的沟通 &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+1可以大于2 &lt;/p&gt;
&lt;p&gt;统合综效是对付阻碍成长与改变的最有力途径。助力通常是积极、合理、自觉、符合经济效益的力量；相反阻力则消极、不合逻辑、情绪化和不自觉。不设法消除阻力的后果就等于向弹簧施加作用力，结果还是要弹。如果将双赢思维、换位沟通与统合综效原则整合，不仅可以化解阻力，甚至可以化阻力为助力，“统合综效”就是创造性合作的原则。 &lt;/p&gt;
&lt;p&gt;集思广益的合作威力无比。许多自然现象显示，全体大于部分和总和。不同植物生长在一起，根部会相互缠绕，士质会因此改善，植物比单独生长更茂盛；两块砖头所能承受的力量大于单独承受力的总和。这些原理也同样适用于人，但也有例外。只有人人都敞开胸怀，以接纳的心态尊重差异时，才能众志成城。 &lt;/p&gt;
&lt;p&gt;习惯七：过身心平衡的生活 &lt;/p&gt;
&lt;p&gt;身心和意志是我们达成目标的基础。所以，有规律地锻炼身心将使我们能接受更大的挑战，静思内省将使人的直觉变得越来越敏感。当我们平衡地在这两方面改善时，则加强了所有习惯的效能。这样我们将成长、变化并最终走向成功。 &lt;/p&gt;
&lt;p&gt;人生最值得投资的就是磨练自己。生活与工作都要靠自己，因此自己是最值得珍爱的财富。工作本身并不能给人带来经济上的安全感，而具备良好的思考、学习、创造与适应能力。才能使自己立于不败之地；拥有财富，并不代表有永远的经济保障，拥有创造财富的能力才真正可靠。 &lt;/p&gt;
&lt;p&gt;以上这七个习惯相辅相成的。前三个习惯在于我们本身，确立目标就要全力以赴，着重于如何进行个人修炼，由依赖转向独立，实现“个人成功”；第四、五、六个习惯，即建立共赢、换位沟通、集思广益，都将促进团队沟通与合作；而第七个习惯涵盖了前六个，督促我们从身心开始完善。通过培养这些习惯，我们可以循序渐进地获得实质的变革，成为真正的高效能人士。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/239308580/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=391&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308580/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308580/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://blog.zbaccp.com/?feed=rss2&amp;p=391</wfw:commentRss><description>惯一：别指望谁能推着你走 
如果你不向前走，谁又会推你走呢？因此，积极主动的态度，是实现个人目标的原则。 
我们常说，“我不会······因为遗传······”、“我迟到、因为······”、“我的计划没完成、因为······等等，我们总在找借口或是抱怨，在不满中消耗自己的生命。而人类和动物的区别正是人能主动积极地创造、实现梦想，来提升我们的生命品质。所以，有效能的人士为自己的行为及一生所做的选择负责，自主选择应对外界环境的态度和方法；他们致力于实现有能力控制的事情，而不是被动地忧虑那些没法用能力控制或难以控制的事情；他们通过能力提升效能，从而扩展自身的关注范围和影响范围。 
积极的心态能让你拥有“选择的自由”。我们虽然不能控制客观环境，但我们可以选择对客观现实做何种反应。积极的涵义不仅仅是采取行动，还代表对自己负责的态度。个人行为取决于自身，而非外部环境，并且人有能力也有责任创造有利的外在环境。 
习惯二：忠诚于自己的人生计划 
我们经常在人生的道路上迷失方向，因徘徊和迷途消耗了生命。而高效能的人懂得设计自己的未来。他们认真地计划自己要成为什么人，想做些什么，要拥有什么，并且清晰明确的写出，以此作为决策指导。因此，“以终为始”是实现自我领导的原则。这将确保自己的行为和目标保持一致，并不受其他人的或外界环境的影响。我们将这个书面计划称之为“使命宣言”。 
任何一个存在的社会组织都需要“使命宣言”，任何一个企业或个人也不例外。“使命宣言”需要阶段性地评估以及持续修正和改良。 
确立目标后全力以赴，就是我们所说的在正确的时间做正确的事，并把事情做对，为什么很多人成功了反而感到失落？许多人在埋头苦干时，尚未发掘人生的终极目标，只是为忙碌而忙碌着，未曾洞悉自己心灵深处的所欲所求，也不曾审视过自己的人生信条：你到底要做什么？什么是你生命中最重要的？你生活的重心是什么？只有确立了符合价值观的人生目标，才能凝聚意志力，全力以赴且持之以恒地付诸实现，才有可能获得内心最大的满足。 
习惯三：选择不做什么更难 
每个人的时间都是有限的，所以要做重要的事，即你觉得有价值并对你的生命价值、最高目标具有贡献的事情；要少做紧急的事，也就是你或别人认为需要立刻解决的事。消防队的最大贡献应是做好防火工作，而不只是忙于到处救火。因此，“要事第一”是自我管理的原则。 
有效能的人只会少量非常重要且需立即处理的紧急、危机事件，他们将工作焦点放在重要但不紧急的事情上，来保持效益与将近率平衡。 
“有效管理”是把最重要的事放在第一位的重点管理。先由领导决定什么是重点后，自己撑握住重点并时刻把它放在第一位，以免被感觉、情绪或冲动左右。要想集中精力于当前的要务，就必须先排除次要事情的牵绊，要勇于说“不”。 
习惯四：远离角斗场的时代 
懂得利人利已的人，把生活看做一个合作的舞台，而不是角斗场，。一般人遇事多用二分法：非强即弱，非胜即败。其实，世界给了每个人足够的立足空间，他人之得并非自己之失。因此，“双赢思维”成为人际关系的原则。 
我们从小就参加各种比赛、考试，培养了一种你赢我输、你死我活的竞争心态。试想一下，谁又甘心在竞赛中认输呢？树立双赢思维就是要在人际交往中不断寻求互利，以达成双方都满意的并致力于合作的协议计划。 
具有双赢思维的人，往往有三种人性品格：正直、成熟和富足心态。他们忠于自己的感受、价值观和承诺，有勇气表达自己的想法及感觉，能以豁达体谅的心态看待别人的想法及体验，相信世界有足够的发展资源和空间，人人都能共享。 
利人利已观念的形成是以诚信、成熟、豁达的品格基础的。豁达的胸襟源自于个人崇高的价值观与自信和安全感，所以不怕与人共名声、共财势，从而肯于尝试无限的可能性，充分发挥创造力和宽广的选择空间。 
习惯五：换位思考的沟通 
如果一位眼科医生为病人配眼镜，他先摘下自己的眼镜让病人试戴，其理由是：“我已经戴了十多年，效果很好，就给你吧，反正我家里还有一副。”那么，谁都知道这是行不通的；如果医生还说：“我戴得很好，你再试试，别心慌。”在病人看到的东西都扭曲了的同时，医生还反复说：“只要有信心，你一定能看得到。”那就真叫人哭笑不得。我们常说：遇事要将心比心。因此，“知已知彼”是交流的原则。 
医生尚未诊断就开处方，谁敢领教？但与人沟通时，我们常犯这种不分青红皂白、妄下断语的毛病。因此必须强调：“了解他人”与“表达自我”是人际沟通不可缺少的要素。首先要了解对方了解自己，才是进行有效人际交流的关键，要改变匆匆忙忙去建议或解决问题的倾向。 
要培养设身处地的“换位”沟通习惯。欲求别人的理解，首先要理解对方。人人都希望被了解，也急于表达但却常疏于倾听。众所周知，有效的倾听不仅可获取广泛的准确信息，还有助于双方情感的积累。当我们的修养到了能把握自己、保持心态平和、能抵御外界干扰和博采众家之言时，我们的人际关系也就上了一个台阶。 
习惯六：1+1可以大于2 
统合综效是对付阻碍成长与改变的最有力途径。助力通常是积极、合理、自觉、符合经济效益的力量；相反阻力则消极、不合逻辑、情绪化和不自觉。不设法消除阻力的后果就等于向弹簧施加作用力，结果还是要弹。如果将双赢思维、换位沟通与统合综效原则整合，不仅可以化解阻力，甚至可以化阻力为助力，“统合综效”就是创造性合作的原则。 
集思广益的合作威力无比。许多自然现象显示，全体大于部分和总和。不同植物生长在一起，根部会相互缠绕，士质会因此改善，植物比单独生长更茂盛；两块砖头所能承受的力量大于单独承受力的总和。这些原理也同样适用于人，但也有例外。只有人人都敞开胸怀，以接纳的心态尊重差异时，才能众志成城。 
习惯七：过身心平衡的生活 
身心和意志是我们达成目标的基础。所以，有规律地锻炼身心将使我们能接受更大的挑战，静思内省将使人的直觉变得越来越敏感。当我们平衡地在这两方面改善时，则加强了所有习惯的效能。这样我们将成长、变化并最终走向成功。 
人生最值得投资的就是磨练自己。生活与工作都要靠自己，因此自己是最值得珍爱的财富。工作本身并不能给人带来经济上的安全感，而具备良好的思考、学习、创造与适应能力。才能使自己立于不败之地；拥有财富，并不代表有永远的经济保障，拥有创造财富的能力才真正可靠。 
以上这七个习惯相辅相成的。前三个习惯在于我们本身，确立目标就要全力以赴，着重于如何进行个人修炼，由依赖转向独立，实现“个人成功”；第四、五、六个习惯，即建立共赢、换位沟通、集思广益，都将促进团队沟通与合作；而第七个习惯涵盖了前六个，督促我们从身心开始完善。通过培养这些习惯，我们可以循序渐进地获得实质的变革，成为真正的高效能人士。&lt;img src=&quot;http://www1.feedsky.com/t1/239308580/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=391&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308580/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308580/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>默认</category><pubDate>Tue, 30 Jun 2009 10:14:31 +0800</pubDate><author>wang</author><comments>http://blog.zbaccp.com/?p=391#comments</comments><guid isPermaLink="false">http://blog.zbaccp.com/?p=391</guid><dc:creator>wang</dc:creator><fs:srclink>http://blog.zbaccp.com/?p=391</fs:srclink><fs:srcfeed>http://blog.zbaccp.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/zbaccp/~7524155/239308580/5633121</fs:itemid></item><item><title>职场寓言小故事</title><link>http://blog.zbaccp.com/?p=389</link><content:encoded>&lt;p&gt;  1.一只乌鸦坐在树上，整天无所事事。一只小兔子看见乌鸦，就问：“我能象你一样整天坐在那里，什么事也不干吗？”乌鸦答道：“当然啦，为什么不呢？”于是，兔子便坐在树下，开始休息。突然，一只狐狸出现了。狐狸跳向兔子……并把它给吃了。&lt;br /&gt;
    这个故事的寓意是……要想坐在那里什么也不干，你必须坐（做）得非常非常高。　&lt;br /&gt;
    2.一只火鸡和一头公牛在聊天。“我非常想到那棵树顶上去，”火鸡叹口气道，“但是我没有那份力气。”“这样啊，那你为什么不吃点我的粪便呢？”公牛答道，“那里面充满了营养。”火鸡吃了一团牛粪，发现它真的使自己有力气到达树的第一个分叉处。第二天，在吃了更多的牛粪以后，火鸡到达了树的第二个分叉处。最终，两星期后，火鸡非常骄傲地站在了树的顶端。但不幸的是，没多久，它就被一个农夫盯上了，并且农夫非常利索地就将火鸡射了下来。&lt;br /&gt;
    这个故事的寓意是……牛粪（狗屎运）也许能使你抵达顶峰，但它不能使你永远呆在那儿。&lt;br /&gt;
    3.一只小鸟正在飞往南方过冬的途中。天气太冷了，小鸟冻僵了，从天上掉下来，跌在一大片农田里。它躺在田里的时候，一只母牛走了过来，而且拉了一泡屎在它身上。冻僵的小鸟躺在牛屎堆里，发掘牛粪真是太温暖了。牛粪让它慢慢缓过劲儿来了！它躺在那儿，又暖和又开心，不久就开始高兴地唱起歌来了。一只路过的猫听到了小鸟的歌声，走过来查个究竟。顺着声音，猫发现了躲在牛粪中的小鸟，非常敏捷地将它刨了出来，并将它给吃了！&lt;br /&gt;
    这个故事的寓意是……&lt;br /&gt;
    1）不是每个在你身上拉屎的都是你的敌人。&lt;br /&gt;
    2）不是每个把你从屎堆中拉出来的都是你的朋友。&lt;br /&gt;
    3）而且，当你陷入深深的屎堆当中（身陷困境）的时候，闭上你的鸟嘴！&lt;br /&gt;
    4、表演大师有一位表演大师上场前，他的助理告诉他鞋带松了。大师点头致谢，蹲下来仔细系。&lt;br /&gt;
    等到助理转身后，又蹲下来将鞋带解松。有个旁观者看到了这一切，不解地问：“大师，您为什么又要将鞋带解松呢？”大师回答道：“因为我饰演的是一位劳累的旅者，长途跋涉让他的鞋事松开，可以通过这个细节表现他的劳累憔悴。”“那你为什么不直接告诉你的助理呢？”“他能细心地发现我的鞋带松了，并且热心地告诉我，我一定要保护他这种热情的积极性，及时地给他鼓励，至于为什么要将鞋带解开，将来会有更多的机会教他表演，可以下一次再说啊。”&lt;br /&gt;
    人一个时间只能做一件事，懂抓重点，才是真正的人才。&lt;br /&gt;
    5、鹦鹉一个人去买鹦鹉，看到一只鹦鹉前标：此鹦鹉会两门语言，售价二百元。另一只鹦鹉前则标道：此鹦鹉会四门语言，售价四百元。该买哪只呢？两只都毛色光鲜，非常灵活可爱。这人转啊转，拿不定主意。结果突然发现一只老掉了牙的鹦鹉，毛色暗淡散乱，标价八百元。这人赶紧将老板叫来：这只鹦鹉是不是会说八门语言？店主说：不。这人奇怪了：那为什么又老又丑，又没有能力，会值这个数呢？店主回答：因为另外两只鹦鹉叫这只鹦鹉老板。&lt;br /&gt;
    这故事告诉我们，真正的领导人，不一定自己能力有多强，只要懂信任，懂放权，懂珍惜，就能团结比自己更强的力量，从而提升自己的身价。相反许多能非常强的人却因为过于完美主义，事必躬亲，什么人都不如自己，最后只能做最好的攻关人员，销售代表，成不了优秀的领导人。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/239308583/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=389&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308583/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308583/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://blog.zbaccp.com/?feed=rss2&amp;p=389</wfw:commentRss><description>  1.一只乌鸦坐在树上，整天无所事事。一只小兔子看见乌鸦，就问：“我能象你一样整天坐在那里，什么事也不干吗？”乌鸦答道：“当然啦，为什么不呢？”于是，兔子便坐在树下，开始休息。突然，一只狐狸出现了。狐狸跳向兔子……并把它给吃了。
    这个故事的寓意是……要想坐在那里什么也不干，你必须坐（做）得非常非常高。　
    2.一只火鸡和一头公牛在聊天。“我非常想到那棵树顶上去，”火鸡叹口气道，“但是我没有那份力气。”“这样啊，那你为什么不吃点我的粪便呢？”公牛答道，“那里面充满了营养。”火鸡吃了一团牛粪，发现它真的使自己有力气到达树的第一个分叉处。第二天，在吃了更多的牛粪以后，火鸡到达了树的第二个分叉处。最终，两星期后，火鸡非常骄傲地站在了树的顶端。但不幸的是，没多久，它就被一个农夫盯上了，并且农夫非常利索地就将火鸡射了下来。
    这个故事的寓意是……牛粪（狗屎运）也许能使你抵达顶峰，但它不能使你永远呆在那儿。
    3.一只小鸟正在飞往南方过冬的途中。天气太冷了，小鸟冻僵了，从天上掉下来，跌在一大片农田里。它躺在田里的时候，一只母牛走了过来，而且拉了一泡屎在它身上。冻僵的小鸟躺在牛屎堆里，发掘牛粪真是太温暖了。牛粪让它慢慢缓过劲儿来了！它躺在那儿，又暖和又开心，不久就开始高兴地唱起歌来了。一只路过的猫听到了小鸟的歌声，走过来查个究竟。顺着声音，猫发现了躲在牛粪中的小鸟，非常敏捷地将它刨了出来，并将它给吃了！
    这个故事的寓意是……
    1）不是每个在你身上拉屎的都是你的敌人。
    2）不是每个把你从屎堆中拉出来的都是你的朋友。
    3）而且，当你陷入深深的屎堆当中（身陷困境）的时候，闭上你的鸟嘴！
    4、表演大师有一位表演大师上场前，他的助理告诉他鞋带松了。大师点头致谢，蹲下来仔细系。
    等到助理转身后，又蹲下来将鞋带解松。有个旁观者看到了这一切，不解地问：“大师，您为什么又要将鞋带解松呢？”大师回答道：“因为我饰演的是一位劳累的旅者，长途跋涉让他的鞋事松开，可以通过这个细节表现他的劳累憔悴。”“那你为什么不直接告诉你的助理呢？”“他能细心地发现我的鞋带松了，并且热心地告诉我，我一定要保护他这种热情的积极性，及时地给他鼓励，至于为什么要将鞋带解开，将来会有更多的机会教他表演，可以下一次再说啊。”
    人一个时间只能做一件事，懂抓重点，才是真正的人才。
    5、鹦鹉一个人去买鹦鹉，看到一只鹦鹉前标：此鹦鹉会两门语言，售价二百元。另一只鹦鹉前则标道：此鹦鹉会四门语言，售价四百元。该买哪只呢？两只都毛色光鲜，非常灵活可爱。这人转啊转，拿不定主意。结果突然发现一只老掉了牙的鹦鹉，毛色暗淡散乱，标价八百元。这人赶紧将老板叫来：这只鹦鹉是不是会说八门语言？店主说：不。这人奇怪了：那为什么又老又丑，又没有能力，会值这个数呢？店主回答：因为另外两只鹦鹉叫这只鹦鹉老板。
    这故事告诉我们，真正的领导人，不一定自己能力有多强，只要懂信任，懂放权，懂珍惜，就能团结比自己更强的力量，从而提升自己的身价。相反许多能非常强的人却因为过于完美主义，事必躬亲，什么人都不如自己，最后只能做最好的攻关人员，销售代表，成不了优秀的领导人。&lt;img src=&quot;http://www1.feedsky.com/t1/239308583/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=389&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308583/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308583/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>默认</category><pubDate>Mon, 29 Jun 2009 15:20:56 +0800</pubDate><author>student</author><comments>http://blog.zbaccp.com/?p=389#comments</comments><guid isPermaLink="false">http://blog.zbaccp.com/?p=389</guid><dc:creator>student</dc:creator><fs:srclink>http://blog.zbaccp.com/?p=389</fs:srclink><fs:srcfeed>http://blog.zbaccp.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/zbaccp/~7524155/239308583/5633121</fs:itemid></item><item><title>人生值得珍藏的42句话</title><link>http://blog.zbaccp.com/?p=387</link><content:encoded>&lt;p&gt; 1.生气是拿别人做错的事来惩罚自己。  &lt;/p&gt;
&lt;p&gt;    2.明天的希望,让我们忘了今天的痛苦。  &lt;/p&gt;
&lt;p&gt;    3.发光并非太阳的专利,你也可以发光。  &lt;/p&gt;
&lt;p&gt;    4.获致幸福的不二法门是珍视你所拥有的、遗忘你所没有的。  &lt;/p&gt;
&lt;p&gt;    5.你可以用爱得到全世界,你也可以用恨失去全世界。  &lt;/p&gt;
&lt;p&gt;    6.真正的爱,应该超越生命的长度、心灵的宽度、灵魂的深度。  &lt;/p&gt;
&lt;p&gt;    7.爱的力量大到可以使人忘记一切,却又小到连一粒嫉妒的沙石也不能容纳。  &lt;/p&gt;
&lt;p&gt;    8.不论你在什麽时候开始,重要的是开始之後就不要停止.不论你在什麽时候结束,重要的是结束之後就不要悔恨。  &lt;/p&gt;
&lt;p&gt;    9.抱最大的希望,为最大的努力,做最坏的打算。  &lt;/p&gt;
&lt;p&gt;    10.有理想在的地方,地狱就是天堂。有希望在的地方,痛苦也成欢乐。  &lt;/p&gt;
&lt;p&gt;    11.上帝从不埋怨人们的愚昧,人们却埋怨上帝的不公平。  &lt;/p&gt;
&lt;p&gt;    12.美好的生命应该充满期待、惊喜和感激。  &lt;/p&gt;
&lt;p&gt;    13.世上最累人的事,莫过於虚伪的过日子。  &lt;/p&gt;
&lt;p&gt;    14.觉得自己做得到和做不到,其实只在一念之间。  &lt;/p&gt;
&lt;p&gt;    15.少一点预设的期待,那份对人的关怀会更自在。  &lt;/p&gt;
&lt;p&gt;    16.人只要不失去方向,就不会失去自己。  &lt;/p&gt;
&lt;p&gt;    17.如果你曾歌颂黎明,那麽也请你拥抱黑夜。  &lt;/p&gt;
&lt;p&gt;    18.问候不一定要慎重其事,但一定要真诚感人。  &lt;/p&gt;
&lt;p&gt;    19.人生重要的不是所站的位置,而是所朝的方向。  &lt;/p&gt;
&lt;p&gt;    20.当你能飞的时候就不要放弃飞。当你能梦的时候就不要放弃梦。当你能爱的时候就不要放弃爱。  &lt;/p&gt;
&lt;p&gt;    21.人总是珍惜未得到的,而遗忘了所拥有的。  &lt;/p&gt;
&lt;p&gt;    22.一个今天胜过两个明天。  &lt;/p&gt;
&lt;p&gt;    23.要铭记在心；每天都是一年中最美好的日子。  &lt;/p&gt;
&lt;p&gt;    24.乐观者在灾祸中看到机会；悲观者在机会中看到灾祸。  &lt;/p&gt;
&lt;p&gt;    25.有勇气并不表示恐惧不存在,而是敢面对恐惧、克服恐惧。  &lt;/p&gt;
&lt;p&gt;    26.人生最大的错误是不断担心会犯错。  &lt;/p&gt;
&lt;p&gt;    27.把你的脸迎向阳光,那就不会有阴影。  &lt;/p&gt;
&lt;p&gt;    28.经验是由痛苦中粹取出来的。  &lt;/p&gt;
&lt;p&gt;    29.用最少的悔恨面对过去。用最少的浪费面对现在。用最多的梦面对未来。  &lt;/p&gt;
&lt;p&gt;    30.如你想要拥有完美无暇的友谊,可能一辈子找不到朋友。  &lt;/p&gt;
&lt;p&gt;    31.不如意的时候不要尽往悲伤里钻,想想有笑声的日子吧。  &lt;/p&gt;
&lt;p&gt;    32.要纠正别人之前,先反省自己有没有犯错。  &lt;/p&gt;
&lt;p&gt;    33.因害怕失败而不敢放手一搏,永远不会成功。  &lt;/p&gt;
&lt;p&gt;    34.要克服生活的焦虑和沮丧,得先学会做自己的主人。  &lt;/p&gt;
&lt;p&gt;    35.你不能左右天气,但你能转变你的心情。  &lt;/p&gt;
&lt;p&gt;    36.孤单寂寞与被遗弃感是最可怕的贫穷。  &lt;/p&gt;
&lt;p&gt;    37.得意时应善待他人,因为你失意时会需要他们。  &lt;/p&gt;
&lt;p&gt;    38.希望,是一种甜蜜的等待；想念,是一份温馨的心情；朋友,是一生修来的福分；爱情；是一世难解的缘分。祝你在人生的道路上多点快乐！多点开心！  &lt;/p&gt;
&lt;p&gt;    39.世界上有两种人：索取者和给予者。前者也许能吃得更好,但后者绝对能睡得更香。  &lt;/p&gt;
&lt;p&gt;    40.分离对爱情的作用和风对火的作用相同：熊熊烈火被风越吹越旺,小火苗被风一吹就灭。  &lt;/p&gt;
&lt;p&gt;    41.1头狮子领导下的100只绵羊,要比1只绵羊领导的100头狮子可怕得多。  &lt;/p&gt;
&lt;p&gt;    42.我们向来喜欢崇拜自己的人,但我们不一定喜欢自己崇拜的人。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/239308609/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=387&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308609/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308609/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://blog.zbaccp.com/?feed=rss2&amp;p=387</wfw:commentRss><description> 1.生气是拿别人做错的事来惩罚自己。  
    2.明天的希望,让我们忘了今天的痛苦。  
    3.发光并非太阳的专利,你也可以发光。  
    4.获致幸福的不二法门是珍视你所拥有的、遗忘你所没有的。  
    5.你可以用爱得到全世界,你也可以用恨失去全世界。  
    6.真正的爱,应该超越生命的长度、心灵的宽度、灵魂的深度。  
    7.爱的力量大到可以使人忘记一切,却又小到连一粒嫉妒的沙石也不能容纳。  
    8.不论你在什麽时候开始,重要的是开始之後就不要停止.不论你在什麽时候结束,重要的是结束之後就不要悔恨。  
    9.抱最大的希望,为最大的努力,做最坏的打算。  
    10.有理想在的地方,地狱就是天堂。有希望在的地方,痛苦也成欢乐。  
    11.上帝从不埋怨人们的愚昧,人们却埋怨上帝的不公平。  
    12.美好的生命应该充满期待、惊喜和感激。  
    13.世上最累人的事,莫过於虚伪的过日子。  
    14.觉得自己做得到和做不到,其实只在一念之间。  
    15.少一点预设的期待,那份对人的关怀会更自在。  
    16.人只要不失去方向,就不会失去自己。  
    17.如果你曾歌颂黎明,那麽也请你拥抱黑夜。  
    18.问候不一定要慎重其事,但一定要真诚感人。  
    19.人生重要的不是所站的位置,而是所朝的方向。  
    20.当你能飞的时候就不要放弃飞。当你能梦的时候就不要放弃梦。当你能爱的时候就不要放弃爱。  
    21.人总是珍惜未得到的,而遗忘了所拥有的。  
    22.一个今天胜过两个明天。  
    23.要铭记在心；每天都是一年中最美好的日子。  
    24.乐观者在灾祸中看到机会；悲观者在机会中看到灾祸。  
    25.有勇气并不表示恐惧不存在,而是敢面对恐惧、克服恐惧。  
    26.人生最大的错误是不断担心会犯错。  
    27.把你的脸迎向阳光,那就不会有阴影。  
    28.经验是由痛苦中粹取出来的。  
    29.用最少的悔恨面对过去。用最少的浪费面对现在。用最多的梦面对未来。  
    30.如你想要拥有完美无暇的友谊,可能一辈子找不到朋友。  
    31.不如意的时候不要尽往悲伤里钻,想想有笑声的日子吧。  
    32.要纠正别人之前,先反省自己有没有犯错。  
    33.因害怕失败而不敢放手一搏,永远不会成功。  
    34.要克服生活的焦虑和沮丧,得先学会做自己的主人。  
    35.你不能左右天气,但你能转变你的心情。  
    36.孤单寂寞与被遗弃感是最可怕的贫穷。  
    37.得意时应善待他人,因为你失意时会需要他们。  
    38.希望,是一种甜蜜的等待；想念,是一份温馨的心情；朋友,是一生修来的福分；爱情；是一世难解的缘分。祝你在人生的道路上多点快乐！多点开心！  
    39.世界上有两种人：索取者和给予者。前者也许能吃得更好,但后者绝对能睡得更香。  
    40.分离对爱情的作用和风对火的作用相同：熊熊烈火被风越吹越旺,小火苗被风一吹就灭。  
    41.1头狮子领导下的100只绵羊,要比1只绵羊领导的100头狮子可怕得多。  
    42.我们向来喜欢崇拜自己的人,但我们不一定喜欢自己崇拜的人。&lt;img src=&quot;http://www1.feedsky.com/t1/239308609/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=387&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308609/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308609/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>默认</category><pubDate>Mon, 29 Jun 2009 09:20:03 +0800</pubDate><author>bigtree</author><comments>http://blog.zbaccp.com/?p=387#comments</comments><guid isPermaLink="false">http://blog.zbaccp.com/?p=387</guid><dc:creator>bigtree</dc:creator><fs:srclink>http://blog.zbaccp.com/?p=387</fs:srclink><fs:srcfeed>http://blog.zbaccp.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/zbaccp/~7524155/239308609/5633121</fs:itemid></item><item><title>Hibernate中二级缓存的配置和使用</title><link>http://blog.zbaccp.com/?p=385</link><content:encoded>&lt;p&gt;(一）Hibernate的二级缓存策略的一般过程如下：&lt;/p&gt;
&lt;p&gt;1) 条件查询的时候，总是发出一条select * from table_name where …. （选择所有字段）这样的SQL语句查询数据库，一次获得所有的数据对象。&lt;/p&gt;
&lt;p&gt;2) 把获得的所有数据对象根据ID放入到第二级缓存中。&lt;/p&gt;
&lt;p&gt;3) 当Hibernate根据ID访问数据对象的时候，首先从Session一级缓存中查；查不到，如果配置了二级缓存，那么从二级缓存中查；查不到，再查询数据库，把结果按照ID放入到缓存。&lt;/p&gt;
&lt;p&gt;4) 删除、更新、增加数据的时候，同时更新缓存。&lt;/p&gt;
&lt;p&gt;Hibernate的二级缓存策略，是针对于ID查询的缓存策略，对于条件查询则毫无作用。为此，Hibernate提供了针对条件查询的Query Cache。&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;1 经常被修改的数据&lt;/p&gt;
&lt;p&gt;2 财务数据，绝对不允许出现并发&lt;/p&gt;
&lt;p&gt;3 与其他应用共享的数据。&lt;/p&gt;
&lt;p&gt;实践部分：&lt;/p&gt;
&lt;p&gt;使用EhCache配置二级缓存：&lt;/p&gt;
&lt;p&gt;配置准备：&lt;/p&gt;
&lt;p&gt;1)把ehcache-1.2.3.jar加入到当前应用的classpath中。&lt;/p&gt;
&lt;p&gt;2)在hibernate.cfg.xml文件中加入EhCache缓存插件的提供类。&lt;br /&gt;
    &amp;lt;!&amp;#8211;配置缓存插件 &amp;#8211;&amp;gt;  &lt;br /&gt;
    &amp;lt;property name=&amp;#8221;hibernate.cache.provider_class&amp;#8221;&amp;gt;  &lt;br /&gt;
        org.hibernate.cache.EhCacheProvider  &lt;br /&gt;
    &amp;lt;/property&amp;gt; &lt;br /&gt;
3)挎贝ehcache.xml文件到类路径(项目工程的src目录下)，这个文件在Hibernate安装目录的etc下。&lt;/p&gt;
&lt;p&gt;配置步骤：&lt;/p&gt;
&lt;p&gt;Hibernate允许在类和集合的粒度上设置第二级缓存。在映射文件中，&amp;lt;class&amp;gt;和&amp;lt;set&amp;gt;元素都有一个&amp;lt;cache&amp;gt;子元素，这个子元素用来配置二级缓存。&lt;br /&gt;
示例：以category(产品类别)和product(产品)的映射为例：&lt;/p&gt;
&lt;p&gt;1) 修改要配置缓存的那个持久化类的对象关系映射文件：&lt;/p&gt;
&lt;p&gt;Category.hbm.xml&lt;/p&gt;
&lt;p&gt;&amp;lt;?xml version=&amp;#8221;1.0&amp;#8243; encoding=&amp;#8221;utf-8&amp;#8243;?&amp;gt;  &lt;/p&gt;
&lt;p&gt;&amp;lt;!DOCTYPE hibernate-mapping PUBLIC &amp;#8220;-//Hibernate/Hibernate Mapping DTD 3.0//EN&amp;#8221;  &lt;br /&gt;
&amp;#8220;0&amp;#8243;&amp;gt;  &lt;br /&gt;
&amp;lt;hibernate-mapping&amp;gt;  &lt;br /&gt;
    &amp;lt;class name=&amp;#8221;org.qiujy.domain.cachedemo.Category&amp;#8221; table=&amp;#8221;categories&amp;#8221;&amp;gt;  &lt;br /&gt;
       &amp;lt;!—  &lt;br /&gt;
             配置缓存,必须紧跟在class元素后面  &lt;br /&gt;
            对缓存中的Category对象采用读写型的并发访问策略  &lt;br /&gt;
        &amp;#8211;&amp;gt;  &lt;br /&gt;
       &amp;lt;cache usage=&amp;#8221;read-write&amp;#8221;/&amp;gt;  &lt;br /&gt;
        &lt;br /&gt;
       &amp;lt;id name=&amp;#8221;id&amp;#8221; type=&amp;#8221;java.lang.Long&amp;#8221;&amp;gt;  &lt;br /&gt;
           &amp;lt;column name=&amp;#8221;id&amp;#8221; /&amp;gt;  &lt;br /&gt;
           &amp;lt;generator class=&amp;#8221;native&amp;#8221; /&amp;gt;  &lt;br /&gt;
       &amp;lt;/id&amp;gt;  &lt;br /&gt;
       &amp;lt;!&amp;#8211; 配置版本号,必须紧跟在id元素后面 &amp;#8211;&amp;gt;  &lt;br /&gt;
       &amp;lt;version name=&amp;#8221;version&amp;#8221; column=&amp;#8221;version&amp;#8221; type=&amp;#8221;java.lang.Long&amp;#8221; /&amp;gt;  &lt;br /&gt;
        &lt;br /&gt;
       &amp;lt;property name=&amp;#8221;name&amp;#8221; type=&amp;#8221;java.lang.String&amp;#8221;&amp;gt;  &lt;br /&gt;
           &amp;lt;column name=&amp;#8221;name&amp;#8221; length=&amp;#8221;32&amp;#8243; not-null=&amp;#8221;true&amp;#8221;/&amp;gt;  &lt;br /&gt;
       &amp;lt;/property&amp;gt;  &lt;br /&gt;
        &lt;br /&gt;
       &amp;lt;property name=&amp;#8221;description&amp;#8221; type=&amp;#8221;java.lang.String&amp;#8221;&amp;gt;  &lt;br /&gt;
           &amp;lt;column name=&amp;#8221;description&amp;#8221; length=&amp;#8221;255&amp;#8243;/&amp;gt;  &lt;br /&gt;
       &amp;lt;/property&amp;gt;  &lt;br /&gt;
        &lt;br /&gt;
       &amp;lt;set name=&amp;#8221;products&amp;#8221; table=&amp;#8221;products&amp;#8221; cascade=&amp;#8221;all&amp;#8221; inverse=&amp;#8221;true&amp;#8221;&amp;gt;  &lt;br /&gt;
           &amp;lt;!&amp;#8211; Hibernate只会缓存对象的简单属性的值,  &lt;br /&gt;
       要缓存集合属性,必须在集合元素中也加入&amp;lt;cache&amp;gt;子元素  &lt;br /&gt;
       而Hibernate仅仅是把与当前持久对象关联的对象的OID存放到缓存中。  &lt;br /&gt;
如果希望把整个关联的对象的所有数据都存入缓存,  &lt;br /&gt;
则要在相应关联的对象的映射文件中配置&amp;lt;cache&amp;gt;元素  &lt;br /&gt;
           &amp;#8211;&amp;gt;  &lt;br /&gt;
           &amp;lt;cache usage=&amp;#8221;read-write&amp;#8221;/&amp;gt;  &lt;br /&gt;
            &lt;br /&gt;
           &amp;lt;key column=&amp;#8221;categoryId&amp;#8221; not-null=&amp;#8221;true&amp;#8221;/&amp;gt;  &lt;br /&gt;
           &amp;lt;one-to-many class=&amp;#8221;org.qiujy.domain.cachedemo.Product&amp;#8221;/&amp;gt;  &lt;br /&gt;
       &amp;lt;/set&amp;gt;  &lt;br /&gt;
        &lt;br /&gt;
    &amp;lt;/class&amp;gt;  &lt;br /&gt;
&amp;lt;/hibernate-mapping&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Product.hbm.xml&lt;/p&gt;
&lt;p&gt;&amp;lt;?xml version=&amp;#8221;1.0&amp;#8243; encoding=&amp;#8221;utf-8&amp;#8243;?&amp;gt;  &lt;br /&gt;
&amp;lt;!DOCTYPE hibernate-mapping PUBLIC &amp;#8220;-//Hibernate/Hibernate Mapping DTD 3.0//EN&amp;#8221;  &lt;br /&gt;
&amp;#8220;#&amp;#8221;&amp;gt;  &lt;br /&gt;
&amp;lt;hibernate-mapping&amp;gt;  &lt;br /&gt;
    &amp;lt;class name=&amp;#8221;org.qiujy.domain.cachedemo.Product&amp;#8221; table=&amp;#8221;products&amp;#8221;&amp;gt;  &lt;br /&gt;
        &lt;br /&gt;
       &amp;lt;cache usage=&amp;#8221;read-write&amp;#8221;/&amp;gt;  &lt;br /&gt;
        &lt;br /&gt;
       &amp;lt;id name=&amp;#8221;id&amp;#8221; type=&amp;#8221;java.lang.Long&amp;#8221;&amp;gt;  &lt;br /&gt;
           &amp;lt;column name=&amp;#8221;id&amp;#8221; /&amp;gt;  &lt;br /&gt;
           &amp;lt;generator class=&amp;#8221;native&amp;#8221; /&amp;gt;  &lt;br /&gt;
       &amp;lt;/id&amp;gt;  &lt;br /&gt;
       &amp;lt;!&amp;#8211; 配置版本号,必须紧跟在id元素后面 &amp;#8211;&amp;gt;  &lt;br /&gt;
       &amp;lt;version name=&amp;#8221;version&amp;#8221; column=&amp;#8221;version&amp;#8221; type=&amp;#8221;java.lang.Long&amp;#8221; /&amp;gt;  &lt;br /&gt;
        &lt;br /&gt;
       &amp;lt;property name=&amp;#8221;name&amp;#8221; type=&amp;#8221;java.lang.String&amp;#8221;&amp;gt;  &lt;br /&gt;
           &amp;lt;column name=&amp;#8221;name&amp;#8221; length=&amp;#8221;32&amp;#8243; not-null=&amp;#8221;true&amp;#8221;/&amp;gt;  &lt;br /&gt;
       &amp;lt;/property&amp;gt;  &lt;br /&gt;
        &lt;br /&gt;
       &amp;lt;property name=&amp;#8221;description&amp;#8221; type=&amp;#8221;java.lang.String&amp;#8221;&amp;gt;  &lt;br /&gt;
           &amp;lt;column name=&amp;#8221;description&amp;#8221; length=&amp;#8221;255&amp;#8243;/&amp;gt;  &lt;br /&gt;
       &amp;lt;/property&amp;gt;  &lt;br /&gt;
        &lt;br /&gt;
       &amp;lt;property name=&amp;#8221;unitCost&amp;#8221; type=&amp;#8221;java.lang.Double&amp;#8221;&amp;gt;  &lt;br /&gt;
           &amp;lt;column name=&amp;#8221;unitCost&amp;#8221; /&amp;gt;  &lt;br /&gt;
       &amp;lt;/property&amp;gt;  &lt;br /&gt;
        &lt;br /&gt;
       &amp;lt;property name=&amp;#8221;pubTime&amp;#8221; type=&amp;#8221;java.util.Date&amp;#8221;&amp;gt;  &lt;br /&gt;
           &amp;lt;column name=&amp;#8221;pubTime&amp;#8221; not-null=&amp;#8221;true&amp;#8221; /&amp;gt;  &lt;br /&gt;
       &amp;lt;/property&amp;gt;  &lt;br /&gt;
        &lt;br /&gt;
       &amp;lt;many-to-one name=&amp;#8221;category&amp;#8221;  &lt;br /&gt;
                column=&amp;#8221;categoryId&amp;#8221;  &lt;br /&gt;
               class=&amp;#8221;org.qiujy.domain.cachedemo.Category&amp;#8221;  &lt;br /&gt;
               cascade=&amp;#8221;save-update&amp;#8221;  &lt;br /&gt;
                not-null=&amp;#8221;true&amp;#8221;&amp;gt;  &lt;br /&gt;
        &amp;lt;/many-to-one&amp;gt;  &lt;br /&gt;
        &lt;br /&gt;
    &amp;lt;/class&amp;gt;  &lt;br /&gt;
&amp;lt;/hibernate-mapping&amp;gt;&lt;br /&gt;
2)编辑ehcache.xml文件：&lt;/p&gt;
&lt;p&gt;&amp;lt;ehcache&amp;gt;  &lt;br /&gt;
    &amp;lt;diskStore path=&amp;#8221;c:\\ehcache\&amp;#8221;/&amp;gt;  &lt;br /&gt;
    &amp;lt;defaultCache  &lt;br /&gt;
        maxElementsInMemory=&amp;#8221;10000&amp;#8243;  &lt;br /&gt;
        eternal=&amp;#8221;false&amp;#8221;  &lt;br /&gt;
        timeToIdleSeconds=&amp;#8221;120&amp;#8243;  &lt;br /&gt;
        timeToLiveSeconds=&amp;#8221;120&amp;#8243;  &lt;br /&gt;
        overflowToDisk=&amp;#8221;true&amp;#8221;    &lt;br /&gt;
        /&amp;gt;  &lt;br /&gt;
         &lt;br /&gt;
    &amp;lt;!&amp;#8211; 设置Category类的缓存的数据过期策略 &amp;#8211;&amp;gt;  &lt;br /&gt;
    &amp;lt;cache name=&amp;#8221;org.qiujy.domain.cachedemo.Category&amp;#8221;  &lt;br /&gt;
        maxElementsInMemory=&amp;#8221;100&amp;#8243;  &lt;br /&gt;
        eternal=&amp;#8221;true&amp;#8221;  &lt;br /&gt;
        timeToIdleSeconds=&amp;#8221;0&amp;#8243;  &lt;br /&gt;
        timeToLiveSeconds=&amp;#8221;0&amp;#8243;  &lt;br /&gt;
        overflowToDisk=&amp;#8221;false&amp;#8221;  &lt;br /&gt;
        /&amp;gt;  &lt;br /&gt;
         &lt;br /&gt;
     &amp;lt;!&amp;#8211; 设置Category类的products集合的缓存的数据过期策略 &amp;#8211;&amp;gt;  &lt;br /&gt;
     &amp;lt;cache name=&amp;#8221;org.qiujy.domain.cachedemo.Category.products&amp;#8221;  &lt;br /&gt;
        maxElementsInMemory=&amp;#8221;500&amp;#8243;  &lt;br /&gt;
        eternal=&amp;#8221;false&amp;#8221;  &lt;br /&gt;
        timeToIdleSeconds=&amp;#8221;300&amp;#8243;  &lt;br /&gt;
        timeToLiveSeconds=&amp;#8221;600&amp;#8243;  &lt;br /&gt;
        overflowToDisk=&amp;#8221;true&amp;#8221;  &lt;br /&gt;
        /&amp;gt;  &lt;br /&gt;
         &lt;br /&gt;
    &amp;lt;cache name=&amp;#8221;org.qiujy.domain.cachedemo.Product&amp;#8221;  &lt;br /&gt;
        maxElementsInMemory=&amp;#8221;500&amp;#8243;  &lt;br /&gt;
        eternal=&amp;#8221;false&amp;#8221;  &lt;br /&gt;
        timeToIdleSeconds=&amp;#8221;300&amp;#8243;  &lt;br /&gt;
        timeToLiveSeconds=&amp;#8221;600&amp;#8243;  &lt;br /&gt;
        overflowToDisk=&amp;#8221;true&amp;#8221;  &lt;br /&gt;
        /&amp;gt;  &lt;br /&gt;
     &lt;br /&gt;
&amp;lt;/ehcache&amp;gt;&lt;/p&gt;
&lt;p&gt;在Spring托管的Hibernate中使用二级缓存 1．在spring的配置文件中，hibernate部分加入 xml 代码 org.hibernate.cache.EhCacheProvider true 2.为HBM表设置cache策略 xml 代码 ３.在DAO中，调用find方法查询之前，设置使用缓存 Java代码 getHibernateTemplate().setCacheQueries(true); 补充： 如果不设置“查询缓存”，那么hibernate只会缓存使用load()方法获得的单个持久化对象，如果想缓存使用findall()、list()、Iterator()、createCriteria()、createQuery()等方法获得的数据结果集的话，就需要设置 hibernate.cache.use_query_cache true 才行。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/239308631/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=385&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308631/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308631/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://blog.zbaccp.com/?feed=rss2&amp;p=385</wfw:commentRss><description>(一）Hibernate的二级缓存策略的一般过程如下：
1) 条件查询的时候，总是发出一条select * from table_name where …. （选择所有字段）这样的SQL语句查询数据库，一次获得所有的数据对象。
2) 把获得的所有数据对象根据ID放入到第二级缓存中。
3) 当Hibernate根据ID访问数据对象的时候，首先从Session一级缓存中查；查不到，如果配置了二级缓存，那么从二级缓存中查；查不到，再查询数据库，把结果按照ID放入到缓存。
4) 删除、更新、增加数据的时候，同时更新缓存。
Hibernate的二级缓存策略，是针对于ID查询的缓存策略，对于条件查询则毫无作用。为此，Hibernate提供了针对条件查询的Query Cache。
（二）什么样的数据适合存放到第二级缓存中？
1 很少被修改的数据
2 不是很重要的数据，允许出现偶尔并发的数据
3 不会被并发访问的数据
4 参考数据,指的是供应用参考的常量数据，它的实例数目有限，它的实例会被许多其他类的实例引用，实例极少或者从来不会被修改。
（三）不适合存放到第二级缓存的数据？
1 经常被修改的数据
2 财务数据，绝对不允许出现并发
3 与其他应用共享的数据。
实践部分：
使用EhCache配置二级缓存：
配置准备：
1)把ehcache-1.2.3.jar加入到当前应用的classpath中。
2)在hibernate.cfg.xml文件中加入EhCache缓存插件的提供类。
    &amp;#60;!&amp;#8211;配置缓存插件 &amp;#8211;&amp;#62;  
    &amp;#60;property name=&amp;#8221;hibernate.cache.provider_class&amp;#8221;&amp;#62;  
        org.hibernate.cache.EhCacheProvider  
    &amp;#60;/property&amp;#62; 
3)挎贝ehcache.xml文件到类路径(项目工程的src目录下)，这个文件在Hibernate安装目录的etc下。
配置步骤：
Hibernate允许在类和集合的粒度上设置第二级缓存。在映射文件中，&amp;#60;class&amp;#62;和&amp;#60;set&amp;#62;元素都有一个&amp;#60;cache&amp;#62;子元素，这个子元素用来配置二级缓存。
示例：以category(产品类别)和product(产品)的映射为例：
1) 修改要配置缓存的那个持久化类的对象关系映射文件：
Category.hbm.xml
&amp;#60;?xml version=&amp;#8221;1.0&amp;#8243; encoding=&amp;#8221;utf-8&amp;#8243;?&amp;#62;  
&amp;#60;!DOCTYPE hibernate-mapping PUBLIC &amp;#8220;-//Hibernate/Hibernate Mapping DTD 3.0//EN&amp;#8221;  
&amp;#8220;0&amp;#8243;&amp;#62;  
&amp;#60;hibernate-mapping&amp;#62;  
    &amp;#60;class name=&amp;#8221;org.qiujy.domain.cachedemo.Category&amp;#8221; table=&amp;#8221;categories&amp;#8221;&amp;#62;  
       &amp;#60;!—  
             配置缓存,必须紧跟在class元素后面  
            对缓存中的Category对象采用读写型的并发访问策略  
        &amp;#8211;&amp;#62;  
       &amp;#60;cache usage=&amp;#8221;read-write&amp;#8221;/&amp;#62;  
        
       &amp;#60;id name=&amp;#8221;id&amp;#8221; type=&amp;#8221;java.lang.Long&amp;#8221;&amp;#62;  
           &amp;#60;column name=&amp;#8221;id&amp;#8221; /&amp;#62;  
           &amp;#60;generator class=&amp;#8221;native&amp;#8221; /&amp;#62;  
       &amp;#60;/id&amp;#62;  
       &amp;#60;!&amp;#8211; 配置版本号,必须紧跟在id元素后面 [...]&lt;img src=&quot;http://www1.feedsky.com/t1/239308631/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=385&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308631/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308631/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>默认</category><pubDate>Mon, 29 Jun 2009 08:51:34 +0800</pubDate><author>吃鱼不吐刺</author><comments>http://blog.zbaccp.com/?p=385#comments</comments><guid isPermaLink="false">http://blog.zbaccp.com/?p=385</guid><dc:creator>吃鱼不吐刺</dc:creator><fs:srclink>http://blog.zbaccp.com/?p=385</fs:srclink><fs:srcfeed>http://blog.zbaccp.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/zbaccp/~7524155/239308631/5633121</fs:itemid></item><item><title>知识产权保护列入IT监理</title><link>http://blog.zbaccp.com/?p=384</link><content:encoded>&lt;p&gt;质量控制、进度控制、信息安全控制和成本控制是信息系统工程监理中通常要解决的问题，不过在应用软件开发中出现的知识产权保护问题也越来越受到重视，并列入了北京信息安全测评中心组织编著的《信息系统工程监理》一书中五大IT监理目标之一。北京信息安全测评中心是北京市信息办授权的目前唯一一家对北京信息系统工程监理企业进行资质认证的机构，该中心于4月3日透露，目前北京市获得甲级资质认证的IT监理企业已有14家、乙级1家、未定级6家。 据悉，目前国内已有14个省市开展了信息系统工程监理法规的制定，虽然全国统一的信息系统工程监理标准还未出台，但《信息系统工程监理》一书中涉及的监理框架体系、目标和方法将对全国统一标准的出台有参考价值，也有助于我国提高系统集成及软件服务业的质量及在国际市场上的竞争力。该书提出了对质量控制、成本控制、进度控制、信息安全控制、知识产权保护控制问题中的相关原则。&lt;br /&gt;
        质量控制中的原则包括：以施工验收规范、工程质量验收及评审标准为依据，督促承建单位全面实现承建合同约定的质量目标；以质量预控为重点，对工程施工全过程实施质量控制；对工程项目的系统集成、应用系统开发及培训过程进行全面的质量控制，监督承建单位的质量保证体系落实到位；坚持本工序质量不合格或未进行验收签认，下一道工序不得施工，以防止质量隐患。&lt;br /&gt;
        进度控制的三条原则是：以建设工程施工合同所约定的工期目标为依据；在确保工程质量和安全的原则下控制工程进度；采用动态的控制方法对工程进度进行主动控制。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/239308646/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=384&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308646/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308646/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://blog.zbaccp.com/?feed=rss2&amp;p=384</wfw:commentRss><description>质量控制、进度控制、信息安全控制和成本控制是信息系统工程监理中通常要解决的问题，不过在应用软件开发中出现的知识产权保护问题也越来越受到重视，并列入了北京信息安全测评中心组织编著的《信息系统工程监理》一书中五大IT监理目标之一。北京信息安全测评中心是北京市信息办授权的目前唯一一家对北京信息系统工程监理企业进行资质认证的机构，该中心于4月3日透露，目前北京市获得甲级资质认证的IT监理企业已有14家、乙级1家、未定级6家。 据悉，目前国内已有14个省市开展了信息系统工程监理法规的制定，虽然全国统一的信息系统工程监理标准还未出台，但《信息系统工程监理》一书中涉及的监理框架体系、目标和方法将对全国统一标准的出台有参考价值，也有助于我国提高系统集成及软件服务业的质量及在国际市场上的竞争力。该书提出了对质量控制、成本控制、进度控制、信息安全控制、知识产权保护控制问题中的相关原则。
        质量控制中的原则包括：以施工验收规范、工程质量验收及评审标准为依据，督促承建单位全面实现承建合同约定的质量目标；以质量预控为重点，对工程施工全过程实施质量控制；对工程项目的系统集成、应用系统开发及培训过程进行全面的质量控制，监督承建单位的质量保证体系落实到位；坚持本工序质量不合格或未进行验收签认，下一道工序不得施工，以防止质量隐患。
        进度控制的三条原则是：以建设工程施工合同所约定的工期目标为依据；在确保工程质量和安全的原则下控制工程进度；采用动态的控制方法对工程进度进行主动控制。&lt;img src=&quot;http://www1.feedsky.com/t1/239308646/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=384&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308646/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308646/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>默认</category><pubDate>Sun, 28 Jun 2009 16:35:22 +0800</pubDate><author>wang</author><comments>http://blog.zbaccp.com/?p=384#comments</comments><guid isPermaLink="false">http://blog.zbaccp.com/?p=384</guid><dc:creator>wang</dc:creator><fs:srclink>http://blog.zbaccp.com/?p=384</fs:srclink><fs:srcfeed>http://blog.zbaccp.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/zbaccp/~7524155/239308646/5633121</fs:itemid></item><item><title>.NET和JAVA的跨平台，程序员很期望</title><link>http://blog.zbaccp.com/?p=383</link><content:encoded>&lt;p&gt;.NET和JAVA的跨平台，程序员很期望，其实不容易。&lt;br /&gt;
         Java最吸引人之处，在于跨平台。而.NET可以看作Java的改良版，囊括Java大部分的优点，所以当然也具有跨平台的潜力。但是认真追究起来，Java和.NET的程序其实也不算真正跨平台，因为Java VM（虚拟机器）和.NET VM本身就是一个平台，而Java程序只能在Java VM上执行，.NET程序只能在.NET VM上执行，至于VM的底下是什么操作系统，则无关紧要。&lt;/p&gt;
&lt;p&gt;        更清楚的说，Java和.NET的跨平台，指的是跨“操作系统”平台。所以，Java VM和.NET VM能移植到什么OS平台，Java程序和.NET程序就能跨到什么平台。从1.0版至今，Java历经了近多年的发展，Java已经无所不在了。除了在服务器上已经取得压倒性的胜利之外，在桌面系统的安装比例也已经超过90%（2002年的数据），且随着最近Dell等大厂和Sun签约在PC上预先安装Java VM，此数据未来会更高。&lt;/p&gt;
&lt;p&gt;        但事实上，Java跨平台的开放程度并不若我们所想象的美好，主要的原因在于“四不一没有”：&lt;/p&gt;
&lt;p&gt;        版本不一致：许多操作系统上虽然已经具备Java VM，但是版本并未和最新版的Java VM同步，甚至不同版本差距颇大者。举例来说，早期Mac OS在追随Java的脚步上，步伐很慢，往往差了一个版本，例如在Java 1.3推出一、二年后，Mac OS仍只有1.2版的Java VM可用（但是现在Mac OSX已经追上Java的版本推进）。另外，Java VM安装比例固然已经超过90%，但是其中应该有许多仍是使用IE浏览器内建的Microsoft VM（只支持到Java 1.1.4 API），不能执行1.2以后的Java 2程序。所幸的是，版本落差这个问题近来已经有显著的改善。&lt;br /&gt;
  &lt;br /&gt;
        特殊动态链接库不存在：对于那些非J2SE标准的动态链接库（例如Java 3D），往往只局限在Window、Solaris、Linux三个操作系统。关于这一点，我不认为未来几年内会有所改善。&lt;br /&gt;
  &lt;br /&gt;
        标准不够开放：Sun曾经把Java提交给ISO来制订开放的标准，但后来又因为舍不得而撤回，改成立JCP委员会为Java的标准制订单位。这也使得Java在开放程度上并未如宣传上所说的那么好。（这一方面，.NET还比Java好一些，至少核心部分已经是ECMA的标准）。&lt;br /&gt;
  &lt;br /&gt;
        厂商不服气：这可能会造成标准的分裂。早期微软在Visual J++产品中就有一些可能造成Java分裂的举动出现。近年来关于IBM和JBoss等公司，在J2EE的产品上，和Sun也是屡次发生冲突。甚至之前传出某公司有利用市场的力量，另立标准的可能。例如Eclipse的SWT就是一个和Java的AWT/Swing互相竞争的API。&lt;br /&gt;
  &lt;br /&gt;
        技术人员没有跟上新技术：过去这八年，Java修修补补，废弃了一些旧的API和程序设计思维，增加了许多新东西。如果开发人员未能随时补充新知识，仍用旧的方法开发系统，就会横生困扰。这其实是很严重的问题。.NET在跨平台问题也不少： .NET某些API在设计时，并没有考虑到跨平台的需求，例如Windows Forms就是如此。这会使得移植.NET VM到不同操作系统时，难度会比较高。Mono（Linux上的.NET VM）曾想移植Windows Forms到Linux上，但是后来放弃了，改成在Wine上面执行Windows Forms（当然效率会因此变差了）。[但是再后来由于System.Drawing实现的比较好，因而又基于System.Drawing来实现底层的SWF，Mono 1.2的发布就是等着SWF1.0的发布。当然效率肯定比不上Windows下的SWF。不过Mono是推举使用GTK#的]    只有核心部分是ECMA的标准，重要的API例如ASP.NET，和ADO.NET都不是标准，而是微软私有的财产，可能涉及法律问题。Mono另外推出Gtk#这套GUI的API（将Gtk+包装起来）。&lt;br /&gt;
  &lt;br /&gt;
        技术人员没有跟上新技术：.NET经过了5年的发展，最新到来的2.0版本和1.x版本相比较，修改、增加了许多API增加了许多新东西,程序设计的思维也发生了重大的变化。如果开发人员未能随时补充新知识，仍用旧的方法开发系统，就会横生困扰。这其实是很严重的问题,MS的WebCast做的非常好,在帮助技术人员跟上新技术方面MS做的比SUN要好许多。&lt;/p&gt;
&lt;p&gt;        目前微软有提供一套开放原始码的.NET VM，名为Share Source Common Language Infrastructure，简称SSCLI，代称Rotor。SSCLI仅供爱好者研究使用，不做商业发行（微软商业版的.NET VM是.NET CLR）。SSCLI可以在FreeBSD、Windows、Mac OS X等平台上执行。&lt;/p&gt;
&lt;p&gt;        为了让.NET能够摆脱微软的控制，除了由Novell/Ximian资助的Mono计划之外（Mono是西班牙文“猴子”的意思）， GNU（自由软件基金会），也有一个DotGNU Portable.NET的类似计划。如果Mono和DotGNU&lt;br /&gt;
Portable.NET等计划能成功，那么.NET的跨平台才能显露曙光，现在有许多的Linux发行版本都内置了Mono平台，如 Novell Suse Linux系列操作系统。&lt;/p&gt;
&lt;p&gt;        .NET以后是一定会流行的，至少会在Windows和Linux上成为主流。Linux和Mono得到Novell公司的大力支持，相信在不久的将来.NET将在Linux平台称为开发的平台。为了让Java能够跨进.NET的世界，有人设计了.NET VM上的Java VM，“IKVM.NET”正是这样的一套Java VM。仗着Java VM和.NET VM有许多相似之处，IKVM.NET在设计上就可以取巧，许多机制（例如垃圾收集）直接利用底下的.NET VM，不需要自己完成。有了像IKVM.NET这样的VM，Java就可以跨到.NET平台上，不失为一个扩展势力的好方法。&lt;/p&gt;
&lt;p&gt;        为了抢夺市场，Java和.NET阵营均使出浑身解数。Java阵营近来的脚步似乎加快了，这是好现象。而.NET阵营更是使出许多绝招，提供下面的工具：&lt;br /&gt;
  &lt;br /&gt;
        Visual J#：如果是1.1.4或更早以前的Java程序，可以直接利用Visual J#，来将Java的原始码编译成.NET的MSIL。这样的编译，成功率可以达到近100%。&lt;br /&gt;
  &lt;br /&gt;
        程序转换工具：如果你的Java程序并非1.1.4以前的古董，而是用到Java&lt;br /&gt;
2的许多新特色，那么你可以利用微软提供的程序转换工具（例如JLCA），来帮助将Java程序转成.NET程序，达到鲸吞的效果。这些工具通常可以将八九成的程序代码转换成功，但是许多地方仍须手动调整。我们可以期待，未来版本的此类工具会更强大，转换的成功率会更高。&lt;br /&gt;
  &lt;br /&gt;
        程序合作工具：既有的Java程序不可能一朝一夕改写成.NET，而转换工具也不是100%成功，那么如果能让既有的Java程序继续运作，而鼓励大家新的程序改用.NET平台，并慢慢换掉旧的Java程序，达到蚕食的效果。这个时候，程序代码合作工具就很重要，负责架起Java旧系统和.NET新系统之间的沟通桥梁。例如：Microsoft .NET and J2EE Interoperability Toolkit，就是这样的工具。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/239308654/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=383&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308654/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308654/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded><wfw:commentRss>http://blog.zbaccp.com/?feed=rss2&amp;p=383</wfw:commentRss><description>.NET和JAVA的跨平台，程序员很期望，其实不容易。
         Java最吸引人之处，在于跨平台。而.NET可以看作Java的改良版，囊括Java大部分的优点，所以当然也具有跨平台的潜力。但是认真追究起来，Java和.NET的程序其实也不算真正跨平台，因为Java VM（虚拟机器）和.NET VM本身就是一个平台，而Java程序只能在Java VM上执行，.NET程序只能在.NET VM上执行，至于VM的底下是什么操作系统，则无关紧要。
        更清楚的说，Java和.NET的跨平台，指的是跨“操作系统”平台。所以，Java VM和.NET VM能移植到什么OS平台，Java程序和.NET程序就能跨到什么平台。从1.0版至今，Java历经了近多年的发展，Java已经无所不在了。除了在服务器上已经取得压倒性的胜利之外，在桌面系统的安装比例也已经超过90%（2002年的数据），且随着最近Dell等大厂和Sun签约在PC上预先安装Java VM，此数据未来会更高。
        但事实上，Java跨平台的开放程度并不若我们所想象的美好，主要的原因在于“四不一没有”：
        版本不一致：许多操作系统上虽然已经具备Java VM，但是版本并未和最新版的Java VM同步，甚至不同版本差距颇大者。举例来说，早期Mac OS在追随Java的脚步上，步伐很慢，往往差了一个版本，例如在Java 1.3推出一、二年后，Mac OS仍只有1.2版的Java VM可用（但是现在Mac OSX已经追上Java的版本推进）。另外，Java VM安装比例固然已经超过90%，但是其中应该有许多仍是使用IE浏览器内建的Microsoft VM（只支持到Java 1.1.4 API），不能执行1.2以后的Java 2程序。所幸的是，版本落差这个问题近来已经有显著的改善。
  
        特殊动态链接库不存在：对于那些非J2SE标准的动态链接库（例如Java 3D），往往只局限在Window、Solaris、Linux三个操作系统。关于这一点，我不认为未来几年内会有所改善。
  
        标准不够开放：Sun曾经把Java提交给ISO来制订开放的标准，但后来又因为舍不得而撤回，改成立JCP委员会为Java的标准制订单位。这也使得Java在开放程度上并未如宣传上所说的那么好。（这一方面，.NET还比Java好一些，至少核心部分已经是ECMA的标准）。
  
        厂商不服气：这可能会造成标准的分裂。早期微软在Visual J++产品中就有一些可能造成Java分裂的举动出现。近年来关于IBM和JBoss等公司，在J2EE的产品上，和Sun也是屡次发生冲突。甚至之前传出某公司有利用市场的力量，另立标准的可能。例如Eclipse的SWT就是一个和Java的AWT/Swing互相竞争的API。
  
        技术人员没有跟上新技术：过去这八年，Java修修补补，废弃了一些旧的API和程序设计思维，增加了许多新东西。如果开发人员未能随时补充新知识，仍用旧的方法开发系统，就会横生困扰。这其实是很严重的问题。.NET在跨平台问题也不少： .NET某些API在设计时，并没有考虑到跨平台的需求，例如Windows Forms就是如此。这会使得移植.NET VM到不同操作系统时，难度会比较高。Mono（Linux上的.NET VM）曾想移植Windows Forms到Linux上，但是后来放弃了，改成在Wine上面执行Windows Forms（当然效率会因此变差了）。[但是再后来由于System.Drawing实现的比较好，因而又基于System.Drawing来实现底层的SWF，Mono 1.2的发布就是等着SWF1.0的发布。当然效率肯定比不上Windows下的SWF。不过Mono是推举使用GTK#的]    只有核心部分是ECMA的标准，重要的API例如ASP.NET，和ADO.NET都不是标准，而是微软私有的财产，可能涉及法律问题。Mono另外推出Gtk#这套GUI的API（将Gtk+包装起来）。
  
        技术人员没有跟上新技术：.NET经过了5年的发展，最新到来的2.0版本和1.x版本相比较，修改、增加了许多API增加了许多新东西,程序设计的思维也发生了重大的变化。如果开发人员未能随时补充新知识，仍用旧的方法开发系统，就会横生困扰。这其实是很严重的问题,MS的WebCast做的非常好,在帮助技术人员跟上新技术方面MS做的比SUN要好许多。
        目前微软有提供一套开放原始码的.NET VM，名为Share Source Common Language Infrastructure，简称SSCLI，代称Rotor。SSCLI仅供爱好者研究使用，不做商业发行（微软商业版的.NET VM是.NET CLR）。SSCLI可以在FreeBSD、Windows、Mac OS X等平台上执行。
        为了让.NET能够摆脱微软的控制，除了由Novell/Ximian资助的Mono计划之外（Mono是西班牙文“猴子”的意思）， GNU（自由软件基金会），也有一个DotGNU Portable.NET的类似计划。如果Mono和DotGNU
Portable.NET等计划能成功，那么.NET的跨平台才能显露曙光，现在有许多的Linux发行版本都内置了Mono平台，如 Novell Suse Linux系列操作系统。
        [...]&lt;img src=&quot;http://www1.feedsky.com/t1/239308654/zbaccp/feedsky/s.gif?r=http://blog.zbaccp.com/?p=383&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;&lt;p class=&quot;fswww1&quot;&gt;&lt;a href=&quot;http://www1.feedsky.com/r/l/feedsky/zbaccp/239308654/art01.html&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; ismap=&quot;ismap&quot; src=&quot;http://www1.feedsky.com/r/i/feedsky/zbaccp/239308654/art01.gif&quot; onerror=&quot;this.style.display='none'&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><category>默认</category><pubDate>Sun, 28 Jun 2009 15:00:25 +0800</pubDate><author>student</author><comments>http://blog.zbaccp.com/?p=383#comments</comments><guid isPermaLink="false">http://blog.zbaccp.com/?p=383</guid><dc:creator>student</dc:creator><fs:srclink>http://blog.zbaccp.com/?p=383</fs:srclink><fs:srcfeed>http://blog.zbaccp.com/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/zbaccp/~7524155/239308654/5633121</fs:itemid></item></channel></rss>
