木木's profile宠辱不惊PhotosBlogListsMore Tools Help

Blog


    February 10

    javascript中事件的理解

    本文来自:慕容星空小站
     
     在javascript中,event事件是一个必不可少的讨论话题,它在和用户的交互中起到了很重要的作用。今天我们就来讨论一下JavaScript中的事件处理,并且结合它来阐叙Ajax框架实现拖动效果的原理了。
    一、 Event对象
       1   Event对象的主要属性和方法
      event代表事件的状态,专门负责对事件的处理,它的属性和方法能帮助我们完成很多和用户交互的操作,下面我们就来看看它的一些属性和方法。
            type:事件的类型,就是HTML标签属性中,没有“on”前缀之后的字符串,例如“Click”就代表单击事件。
      srcElement:事件源,就是发生事件的元素。比如<a onclick="check()"></a> a这个链接是事件发生的源头,也就是该事件的srcElement。
      button:声明了被按下的鼠标键,是一个整数。0代表没有按键,1代表鼠标左键,2代表鼠标右键,4代表鼠标的中间键,如果按下了多个鼠标键,就把这些值加在一起,所以3就代表左右键同时按下。
      clientX/clientY:是指事件发生的时候,鼠标的横、纵坐标,返回的是整数,它们的值是相对于包容窗口的左上角生成的。
      offsetX/offsetY:鼠标指针相对于源元素的位置,可以确定单击Image对象的哪个象素。
      altKey,ctrlKey,shiftKey:顾名思义,这些属性是指鼠标事件发生的时候,是否同时按住了Alt、Ctrl或者Shift键,返回的是一个布尔值。
      keyCode:返回keydown和keyup事件发生的时候,按键的代码以及keypress事件的Unicode字符。比如event.keyCode=13代表按下了回车键;
      fromElement、toElement前者是指代mouseover事件移动过的文档元素,后者指代mouseout事件中鼠标移动到的文档元素。
      cancelBubble:一个布尔属性,把它设置为true的时候,将停止事件进一步起泡到包容层次的元素,它用于检测是否接受上层元素的事件的控制。true代表不被上层元素的事件控制,false代表允许被上层元素的事件控制。
      returnValue:一个布尔值属性,设置为false的时候可以阻止浏览器执行默认的事件动作,相当于<a href=”#” onclick=”ProcessMethod();return false;” />。
             attachEvent()和detachEvent()方法:为制定DOM对象事件类型注册多个事件处理函数的方法,它们有两个参数,第一个是事件类型,第二个是事件处理函数。在attachEvent()事件执行的时候,this关键字指向的是window对象,而不是发生事件的那个元素。
       2    IE Event对象的一些说明
      Event对象是一个全局属性
      在IE中,不能把Event对象作为参数传递给事件处理程序,只能用window.event或者event来引用Event对象。因为在IE中,Event是window的一个属性,也就是说event是一个全局变量,这个变量提供了事件的细节。
     3 关于事件的起泡的概念
            IE中事件的起泡:IE中事件可以沿着包容层次一点点起泡到上层,也就是说,下层的DOM节点定义的事件处理函数,到了上层的节点如果还有和下层相同事件类型的事件处理函数,那么上层的事件处理函数也会执行。例如,<div>标签包含了<a>,如果这两个标签都有 onclick事件的处理函数,那么执行的情况就是先执行<a>标签的onclick事件处理函数,再执行<div>的事件处理函数。如果希望<a>的事件处理函数执行完毕之后,不希望执行上层的<div>的onclick的事件处理函数了,那么就把 cancelBubble设置为false即可。
      
    二、 IE中拖动DOM元素的例子
    /*
      该函数由mousedown事件处理调用
      它为随后发生的mousemove和mouseup事件注册了临时的捕捉事件处理程序
      并用这些事件处理程序拖动指定的文档元素
      第二个参数必须是mousedown事件的事件对象
    */
    function beginDrag(elementToDrag,event)
    {
      //该元素当前位于何处
      //该元素的样式性质必须具有left和top css属性
      //此外,我们假定他们用象素做单位
      //var x=parseInt(elementToDrag.style.left);
      //var y=parseInt(elementToDrag.style.top);
     
      //计算一个点和鼠标点击之间的距离,下面的嵌套的moveHandler函数需要这些值
      var deltaX=event.clientX-parseInt(elementToDrag.style.left);
      var deltaY=event.clientY-parseInt(elementToDrag.style.top);
     
    //  注册mousedown事件后发生的mousemove和mouseup事件的处理程序
    //  注意,它们被注册为文档的捕捉事件处理程序
    //  在鼠标按钮保持按下的状态的时候,这些事件处理程序保持活动的状态
    //  在按钮被释放的时候,它们被删除
      document.attachEvent("onmousemove",moveHandler);
      document.attachEvent("onmouseup",upHandler);
      
      //我们已经处理了该事件,不要让别的元素看到它
     event.cancelBubble=true;
     event.returnValue=false;
     
      /*
        这是在元素被拖动时候捕捉mousemove事件的处理程序,它响应移动的元素
       
      */
      function moveHandler(e) 
      {
        //把元素移动到当前的鼠标位置
        e=window.event;
        elementToDrag.style.left=(event.clientX-deltaX)+"px";
        elementToDrag.style.top=(event.clientY-deltaY)+"px";
       
        //不要让别的元素看到该事件
        event.cancelBubble=true;
       
      }
     
      /*
        该事件将捕捉拖动结束的时候发生的mouseup事件
      */
      function upHandler(e)
      {
        //注销事件处理程序
          document.detachEvent("onmouseup",upHandler);
          document.detachEvent("onmousemove",moveHandler);}
      
          event.cancelBubble=true;
        } 
       调用它的HTML文件代码:
     <html>
     <head>
         <title>Untitled Page</title>
         <script type="text/javascript" src="dragIE.js"></script>
     </head>
     <body>
     <div style="position:absolute;left:100px;top:100px;background-color:White;border:solid black;">
       <div style="background-color:Gray;border-bottom:solid black;padding:3px;font-family:Sans-Serif;font-weight:bold;" onmousedown="beginDrag(this.parentNode,event);">
       拖动我&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
       </div>
       <div>
       <p>This is a test.Testing,testing</p></div>
     </div>
     </body>
    三、 DOM中的高级事件处理
     IE 6中的事件处理,并不是W3C DOM标准的事件处理模型,所以如果上述代码运行在Mozilla Firefox的浏览器中,就会失去作用,同时即将发布的IE 7也将支持W3C DOM的二级标准,所以掌握DOM的高级事件处理显得就很重要了,因为W3C DOM二级标准是未来Web的发展方向,同时W3C DOM的API非常常用,为未来更加复杂的Web开发提供了良好的基础。
    (一)事件处理程序的作用域和事件的传播
      在正式讨论DOM高级事件处理之前,我们有必要了解一下事件处理程序的作用域。事件处理程序的作用域要比普通的函数作用域复杂很多。普通的函数作用域链比较容易,例如在一个普通函数中查找一个变量a,那么JavaScript解释器会先在该函数的调用对象中查找是否有a这个变量,如果没有,将会在作用域链的下一个对象,一般是全局对象中查找。但是事件处理程序没这么简单,特别是用HTML的属性定义的,它们的作用域链的头部是调用它们的对象,而下一个对象并不是全局对象,而是触发事件处理程序的对象。这样就会出现一个问题,window和document都有一个方法open(),如果open()前面不加修饰,那么在事件处理的函数中将会调用document.open()方法,而不是常用的window.open()方法,所以使用的时候应该明确指明是 window.open()。
    (二)事件传播和注册事件处理程序
    1.事件传播
      在二级DOM标准中,事件处理程序比较复杂,当事件发生的时候,目标节点的事件处理程序就会被触发执行,但是目标节点的父节点也有机会来处理这个事件。事件的传播分为三个阶段,首先是捕捉阶段,事件从 Document对象沿着DOM树向下传播到目标节点,如果目标的任何一个父节点注册了捕捉事件的处理程序,那么事件在传播的过程中就会首先运行这个程序。下一个阶段就是发生在目标节点自身了,注册在目标节点上的相应的事件处理程序就会执行;最后是起泡阶段,事件将从目标节点向上传回给父节点,同样,如果父节点有相应的事件处理程序也会处理。在IE中,没有捕捉的阶段,但是有起泡的阶段。可以用stopPropagating()方法来停止事件传播,也就是让其他元素对这个事件不可见,在IE 6中,就是把cancelBubble设置为true。
    2.注册事件处理程序
      和IE一样, DOM标准也有自己的事件处理程序,不过DOM二级标准的事件处理程序比IE的强大一些,事件处理程序的注册用addEventListner方法,该方法有三个参数,第一个是事件类型,第二个是处理的函数,第三个是一个布尔值,true表示制定的事件处理程序将在事件传播的阶段用于捕捉事件,否则就不捕捉,当事件发生在对象上才触发执行这个事件处理的函数,或者发生在该对象的字节点上,并且向上起泡到这个对象上的时候,触发执行这个事件处理的函数。例如:document.addEventListener("mousemove",moveHandler,true);就是在mousemove事件发生的时候,调用moveHandler函数,并且可以捕捉事件。
      可以用addEventListener为一个事件注册多个事件处理的程序,但是这些函数的执行顺序是不确定,并不像C#那样按照注册的顺序执行。
    在Mozilla Firefox中用addEventListener注册一个事件处理程序的时候,this关键字就表示调用事件处理程序的文档元素,但是其他浏览器并不一定是这样,因为这不是DOM标准,正确的做法是用currentTarget属性来引用调用事件处理程序的文档元素。
    3.二级DOM标准中的Event
    和IE不同的是,W3C DOM中的Event对象并不是window全局对象下面的属性,换句话说,event不是全局变量。通常在DOM二级标准中,event作为发生事件的文档对象的属性。Event含有两个子接口,分别是UIEvent和MutationEvent,这两个子接口实现了Event的所有方法和属性,而 MouseEvent接口又是UIEvent的子接口,所以实现了UIEvent和Event的所有方法和属性。下面,我们就看看Event、 UIEvent和MouseEvent的主要属性和方法。
      1.Event
        type:事件类型,和IE类似,但是没有“on”前缀,例如单击事件只是“click”。
        target:发生事件的节点。
        currentTarget:发生当前正在处理的事件的节点,可能是Target属性所指向的节点,也可能由于捕捉或者起泡,指向Target所指节点的父节点。
        eventPhase:指定了事件传播的阶段。是一个数字。
        timeStamp:事件发生的时间。
        bubbles:指明该事件是否起泡。
        cancelable:指明该事件是否可以用preventDefault()方法来取消默认的动作。
        preventDefault()方法:取消事件的默认动作;
        stopPropagation()方法:停止事件传播。
      2.UIEvent
        view:发生事件的window对象。
        detail:提供事件的额外信息,对于单击事件、mousedown和mouseup事件都代表的是点击次数。
      3.MouseEvent
       button:一个数字,指明在mousedown、mouseup和单击事件中,鼠标键的状态,和IE中的button属性类似,但是数字代表的意义不一样,0代表左键,1代表中间键,2代表右键。
       altKey、ctrlKey、shiftKey、metaKey:和IE相同,但是IE没有最后一个。
    clientX、clientY:和IE的含义相同,但是在DOM标准中,这两个属性值都不考虑文档的滚动情况,也就是说,无论文档滚动到哪里,只要事件发生在窗口左上角,clientX和clientY都是0,所以在IE中,要想得到事件发生的坐标相对于文档开头的位置,要加上 document.body.scrollLeft和document.body.scrollTop。
       screenX、screenY:鼠标指针相对于显示器左上角的位置,如果你想打开新的窗口,这两个属性很重要。
       relatedTarget:和IE中的fromElement、toElement类似,除了对于mouseover和mouseout有意义外,其他的事件没什么意义。
    (三)兼容于两种主流浏览器的拖动DOM元素的例子
      好了,刚才讲了这么多DOM编程和IE中的事件,那么如何编写兼容IE和Mozilla Firefox两种主流浏览器的拖拽程序呢?代码如下:
    function beginDrag(elementToDrag,event)
    {
      var deltaX=event.clientX-parseInt(elementToDrag.style.left);
      var deltaY=event.clientY-parseInt(elementToDrag.style.top);
     
    if(document.addEventListener)
    {
      document.addEventListener("mousemove",moveHandler,true);
      document.addEventListener("mouseup",upHandler,true);
    }
    else if(document.attachEvent)
    {
      document.attachEvent("onmousemove",moveHandler);
      document.attachEvent("onmouseup",upHandler);
     
    }
     
      if(event.stopPropagation)   event.stopPropagation();
      else event.cancelBubble=true;
      if(event.preventDefault)  event.preventDefault();
      else event.returnValue=false;
     
      function moveHandler(e) 
      {
      if (!e) e=window.event; //如果是IE的事件对象,那么就用window.event
      //全局属性,否则就用DOM二级标准的Event对象。
        elementToDrag.style.left=(event.clientX-deltaX)+"px";
        elementToDrag.style.top=(event.clientY-deltaY)+"px";
       
         if(event.stopPropagation)   event.stopPropagation();
        else event.cancelBubble=true;
       
      }
     
      function upHandler(e)
      {
           if(document.removeEventListener)
        {
          document.removeEventListener("mouseup",upHandler,true);
          document.removeEventListener("mousemove",moveHandler,true);}
          else
        {
          document.detachEvent("onmouseup",upHandler);
          document.detachEvent("onmousemove",moveHandler);}
        }
          if(event.stopPropagation)   event.stopPropagation();
        else event.cancelBubble=true;
       
    最后我们来回顾一下事件执行过程中的三个阶段:
     1 捕捉阶段,事件从Document对象沿Dom解析的树向下传播给目标节点。
     2 目标节点触发阶段 事件处理程序在目标上的运行阶段
     3 起泡阶段 事件从目标元素向上传播或者起泡回Document对象的文档层次。
     

    Ajax的原理和应用【下】

    本文来自: 慕容星空小站

     

    6ajax原理和XmlHttpRequest对象

     

      Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。要清楚这个过程和原理,我们必须对 XMLHttpRequest有所了解。

    XMLHttpRequestajax的核心机制,它是在IE5中首先引入的,是一种支持异步请求的技术。简单的说,也就是javascript可以及时向服务器提出请求和处理响应,而不阻塞用户。达到无刷新的效果。

      所以我们先从XMLHttpRequest讲起,来看看它的工作原理。

      首先,我们先来看看XMLHttpRequest这个对象的属性。

      它的属性有:

      onreadystatechange  每次状态改变所触发事件的事件处理程序。

      responseText     从服务器进程返回数据的字符串形式。

      responseXML    从服务器进程返回的DOM兼容的文档数据对象。

      status           从服务器返回的数字代码,比如常见的404(未找到)和200(已就绪)

      status Text       伴随状态码的字符串信息

      readyState       对象状态值

    0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)

    1 (初始化) 对象已建立,尚未调用send方法

    2 (发送数据) send方法已调用,但是当前的状态及http头未知

    3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBodyresponseText获取部分数据会出现错误,

    4 (完成) 数据接收完毕,此时可以通过通过responseXmlresponseText获取完整的回应数据

     

      但是,由于各浏览器之间存在差异,所以创建一个XMLHttpRequest对象可能需要不同的方法。这个差异主要体现在IE和其它浏览器之间。下面是一个比较标准的创建XMLHttpRequest对象的方法。

     

       function CreateXmlHttp()

       {

      

       //IE浏览器创建XmlHttpRequest对象

        if(window.XmlHttpRequest)

        {

         xmlhttp=new XmlHttpRequest();

        }

        //IE浏览器创建XmlHttpRequest对象

         if(window.ActiveXObject)

        {

        try

        {

         xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");    

        }

        catch(e)

        {

        try{

         xmlhttp=new ActiveXObject("msxml2.XMLHTTP");

         }

         catch(ex){}

        }

        }

       } 

    function Ustbwuyi()

       {

        var data=document.getElementById("username").value;  

            CreateXmlHttp();

            if(!xmlhttp)

            {

             alert("创建xmlhttp对象异常!");

             return false;

            }      

            xmlhttp.open("POST",url,false);

            xmlhttp.onreadystatechange=function()

            {  

             if(xmlhttp.readyState==4)

               {

               document.getElementById("user1").innerHTML="数据正在加载...";

                 if(xmlhttp.status==200)

                 {

                  document.write(xmlhttp.responseText);

                 }     

               }

             }

            xmlhttp.send();

      

       }

    如上所示,函数首先检查XMLHttpRequest的整体状态并且保证它已经完成(readyStatus=4),即数据已经发送完毕。然后根据服务器的设定询问请求状态,如果一切已经就绪(status=200),那么就执行下面需要的操作。

    对于XmlHttpRequest的两个方法,opensend,其中open方法指定了:

    a、向服务器提交数据的类型,即post还是get

    b、请求的url地址和传递的参数。

    c、传输方式,false为同步,true为异步。默认为true。如果是异步通信方式(true),客户机就不等待服务器的响应;如果是同步方式(false),客户机就要等到服务器返回消息后才去执行其他操作。我们需要根据实际需要来指定同步方式,在某些页面中,可能会发出多个请求,甚至是有组织有计划有队形大规模的高强度的request,而后一个是会覆盖前一个的,这个时候当然要指定同步方式。

        Send方法用来发送请求。

     

      知道了XMLHttpRequest的工作流程,我们可以看出,XMLHttpRequest是完全用来向服务器发出一个请求的,它的作用也局限于此,但它的作用是整个ajax实现的关键,因为ajax无非是两个过程,发出请求和响应请求。并且它完全是一种客户端的技术。而XMLHttpRequest正是处理了服务器端和客户端通信的问题所以才会如此的重要。

      现在,我们对ajax的原理大概可以有一个了解了。我们可以把服务器端看成一个数据接口,它返回的是一个纯文本流,当然,这个文本流可以是XML格式,可以是Html,可以是Javascript代码,也可以只是一个字符串。这时候,XMLHttpRequest向服务器端请求这个页面,服务器端将文本的结果写入页面,这和普通的web开发流程是一样的,不同的是,客户端在异步获取这个结果后,不是直接显示在页面,而是先由javascript来处理,然后再显示在页面。至于现在流行的很多ajax控件,比如magicajax等,可以返回DataSet等其它数据类型,只是将这个过程封装了的结果,本质上他们并没有什么太大的区别。

     

     

    7ajax的优点

       Ajax的给我们带来的好处大家基本上都深有体会,在这里我只简单的讲几点:

       1、最大的一点是页面无刷新,在页面内与服务器通信,给用户的体验非常好。

      2、使用异步方式与服务器通信,不需要打断用户的操作,具有更加迅速的响应能力。

      3、可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。并且减轻服务器的负担,ajax的原则是按需取数据,可以最大程度的减少冗余请求,和响应对服务器造成的负担。

      4、基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。

    8ajax的缺点

      下面我着重讲一讲ajax的缺陷,因为平时我们大多注意的都是ajax给我们所带来的好处诸如用户体验的提升。而对ajax所带来的缺陷有所忽视。

      下面所阐述的ajax的缺陷都是它先天所产生的。

       1ajax干掉了back按钮,即对浏览器后退机制的破坏。后退按钮是一个标准的web站点的重要功能,但是它没法和js进行很好的合作。这是ajax所带来的一个比较严重的问题,因为用户往往是希望能够通过后退来取消前一次操作的。那么对于这个问题有没有办法?答案是肯定的,用过Gmail的知道,Gmail下面采用的ajax技术解决了这个问题,在Gmail下面是可以后退的,但是,它也并不能改变ajax的机制,它只是采用的一个比较笨但是有效的办法,即用户单击后退按钮访问历史记录时,通过创建或使用一个隐藏的IFRAME来重现页面上的变更。(例如,当用户在Google Maps中单击后退时,它在一个隐藏的IFRAME中进行搜索,然后将搜索结果反映到Ajax元素上,以便将应用程序状态恢复到当时的状态。)

    但是,虽然说这个问题是可以解决的,但是它所带来的开发成本是非常高的,和ajax框架所要求的快速开发是相背离的。这是ajax所带来的一个非常严重的问题。

     2、安全问题

    技术同时也对IT企业带来了新的安全威胁,ajax技术就如同对企业数据建立了一个直接通道。这使得开发者在不经意间会暴露比以前更多的数据和服务器逻辑。ajax的逻辑可以对客户端的安全扫描技术隐藏起来,允许黑客从远端服务器上建立新的攻击。还有ajax也难以避免一些已知的安全弱点,诸如跨站点脚步攻击、SQL注入攻击和基于credentials的安全漏洞等。

      3、对搜索引擎的支持比较弱。

      4、破坏了程序的异常机制。至少从目前看来,像ajax.dllajaxpro.dll这些ajax框架是会破坏程序的异常机制的。关于这个问题,我曾经在开发过程中遇到过,但是查了一下网上几乎没有相关的介绍。后来我自己做了一次试验,分别采用ajax和传统的form提交的模式来删除一条数据……给我们的调试带来了很大的困难。

     5、另外,像其他方面的一些问题,比如说违背了url和资源定位的初衷。例如,我给你一个url地址,如果采用了ajax技术,也许你在该url地址下面看到的和我在这个url地址下看到的内容是不同的。这个和资源定位的初衷是相背离的。

     6、一些手持设备(如手机、PDA等)现在还不能很好的支持ajax,比如说我们在手机的浏览器上打开采用ajax技术的网站时,它目前是不支持的,当然,这个问题和我们没太多关系。

     

     

    9ajax的几种框架

     

     目前我们采用的比较多的ajax框架主要有ajax.dll,ajaxpro.dll,magicajax.dll 以及微软的atlas框架。Ajax.dllAjaxpro.dll这两个框架差别不大,而magicajax.dll只是封装得更厉害一些,比如说它可以直接返回DataSet数据集,前面我们已经说过,ajax返回的都是字符串,magicajax只是对它进行了封装而已。但是它的这个特点可以给我们带来很大的方便,比如说我们的页面有一个列表,而列表的数据是不断变化的,那么我们可以采用magicajax来处理,操作很简单,添加magicajax之后,将要更新的列表控件放在magicajax的控件之内,然后在pageload里面定义更新间隔的时间就ok了,atlas的原理和magicajax差不多。但是,需要注意的一个问题是,这几种框架都只支持IE,没有进行浏览器兼容方面的处理,用反编译工具察看他们的代码就可以知道。

     除了这几种框架之外,我们平时用到的比较多的方式是自己创建xmlHttpRequest对象,这种方式和前面的几种框架相比更具有灵活性。另外,在这里还提一下aspnet2.0自带的异步回调接口,它和ajax一样也可以实现局部的无刷新,但它的实现实际上也是基于xmlhttprequest对象的,另外也是只支持IE,当然这是微软的一个竞争策略。

     

    10ajax示例

    验证用户名是否注册。

    采用两种方式

    1 ajax.dll

    2 自己写xmlhttprequest对象

     

    10.ajax中常见到的一些错误

     1 配置的问题

     

    pageload里面配置该页面的时候

     

    11

    在后台调用的方法里调用了前台的部分

    Ajax的原理和应用【上】

    本文来自:慕容星空小站
     

           在写这篇文章之前,曾经写过一篇关于AJAX技术的随笔,不过涉及到的方面很窄,对AJAX技术的背景、原理、优缺点等各个方面都很少涉及null。这次写这篇文章的背景是因为公司需要对内部程序员做一个培训。项目经理找到了我,并且征询我培训的主题,考虑到之前JavascriptCSSWEB开发技术都已经讲解过了,所以决定针对AJAX这一块做一个比较系统的培训,所以这篇文章实际上是一个培训的材料。

           在这篇文章中,我将从10个方面来对AJAX技术进行系统的讲解。

     

    1ajax技术的背景

     

          不可否认,ajax技术的流行得益于google的大力推广,正是由于google earthgoogle suggest以及gmail等对ajax技术的广泛应用,催生了ajax的流行。而这也让微软感到无比的尴尬,因为早在97年,微软便已经发明了ajax中的关键技术,并且在99IE5推出之时,它便开始支持XmlHttpRequest对象,并且微软之前已经开始在它的一些产品中应用ajax,比如说MSDN网站菜单中的一些应用。遗憾的是,不知道出于什么想法,当时微软发明了ajax的核心技术之后,并没有看到它的潜力而加以发展和推广,而是将它搁置起来。对于这一点来说,我个人是觉得非常奇怪的,因为以微软的资源和它的战略眼光来说,应该不会看不到ajax技术的前景,唯一的解释也许就是因为当时它的主要竞争对手Netscape的消失反而使它变得麻痹和迟钝,毕竟巨人也有打盹的时候,比如IBM曾经在对微软战略上的失误。正是这一次的失误,成就了它现在的竞争对手googleajax方面的领先地位,而事实上google目前在ajax技术方面的领先是微软所无法达到的,这一点在后面我讲述ajax缺陷的时候也会提到。现在微软也意识到了这个问题,因此它也开始在ajax领域奋起直追,比如说推出它自己的ajax框架atlas,并且在.NET2.0也提供了一个用来实现异步回调的接口,即ICallBack接口。那么微软为什么对自己在ajax方面的落后如此紧张呢?现在就让我们来分析一下ajax技术后面隐藏的深刻意义。

     

    2ajax技术的意义

     

         我们在平时的开发中都多多少少的接触或者应用到了ajax,谈到ajax技术的意义,我们关注得最多的毫无疑问是提升用户的体验。但是,如果我们结合将来电脑和互联网的发展趋势,我们会发现ajax技术在某些方面正好代表了这种趋势。为什么这样说呢?我们知道,自从电脑出现以来,一直是桌面软件占据着绝对主导的地位,但是互联网的出现和成功使这一切开始发生着微妙的变化。相当一部分的人都相信,迟早有一天,数据和电脑软件将会从桌面转移到互联网。也就是说,将来的电脑有可能抛弃笨重的硬盘,而直接从互联网来获取数据和服务,我记得我念大学的时候,有位教授给我们上课的时候,曾经设想过这样一种情景,也许在将来的电脑桌面上,没有任何多余的软件和程序,而仅仅只有一个IE,虽然现在看起来我们距离这一天还很遥远,并且这其中还有很多的问题需要解决,但是我觉得这个并非梦想,而是迟早将实现的现实。那么,这其中的主要问题就是互联网的连接不稳定,谁也不愿意看着自己的电脑从服务器一点一滴的下载数据,那么,ajax是不是解决了这个问题呢,说实话,与其说ajax解决了这个问题,倒不如它只是掩盖了这个问题,它只是在服务器和客户端之间充当了一个缓冲器,让用户误以为服务没有中断。精确的说,ajax并不能提高从服务器端下载数据的速度,而只是使这个等待不那么令人沮丧。但是正是这一点就足以产生巨大的影响和震动,它实际上也对桌面软件产生了巨大的冲击。这一点我用一个例子来说明,我们可以比较一下Outlook ExpressGmail,前者是典型的桌面软件,后者是ajax所实现的B/S模式,实际上后者目前已经在慢慢取代前者了,Gmail在收发邮件的时候已经和Outlook Express的功能几乎没有差别了,而且它不需要安装客户端程序。这就是为什么微软对ajax所带来的冲击有着如此的恐惧心理,并且在它前不久所进行的调查之中,将google看做他们未来十年内的主要竞争对手的主要原因之一。当然,这种变化也并不会将桌面软件全部淘汰,现有的浏览器还没有一个能像PhotoShop等桌面程序那样处理复杂的图像。但是我们也不能忽视它带来的影响和冲击。

     

    3、关于ajax的名字

        ajax 的全称是Asynchronous JavaScript and XML,其中,Asynchronous 是异步的意思,它有别于传统web开发中采用的同步的方式。

    4、关于同步和异步

     

    异步传输是面向字符的传输,它的单位是字符;而同步传输是面向比特的传输,它的单位是桢,它传输的时候要求接受方和发送方的时钟是保持一致的。

    具体来说,异步传输是将比特分成小组来进行传送。一般每个小组是一个8位字符,在每个小组的头部和尾部都有一个开始位和一个停止位,它在传送过程中接收方和发送方的时钟不要求一致,也就是说,发送方可以在任何时刻发送这些小组,而接收方并不知道它什么时候到达。一个最明显的例子就是计算机键盘和主机的通信,按下一个键的同时向主机发送一个8比特位的ASCII代码,键盘可以在任何时刻发送代码,这取决于用户的输入速度,内部的硬件必须能够在任何时刻接收一个键入的字符。这是一个典型的异步传输过程。异步传输存在一个潜在的问题,即接收方并不知道数据会在什么时候到达。在它检测到数据并做出响应之前,第一个比特已经过去了。这就像有人出乎意料地从后面走上来跟你说话,而你没来得及反应过来,漏掉了最前面的几个词。因此,每次异步传输的信息都以一个起始位开头,它通知接收方数据已经到达了,这就给了接收方响应、接收和缓存数据比特的时间;在传输结束时,一个停止位表示该次传输信息的终止。按照惯例,空闲(没有传送数据)的线路实际携带着一个代表二进制1的信号。步传输的开始位使信号变成0,其他的比特位使信号随传输的数据信息而变化。最后,停止位使信号重新变回1,该信号一直保持到下一个开始位到达。例如在键盘上数字“1,按照8比特位的扩展ASCII编码,将发送“00110001,同时需要在8比特位的前面加一个起始位,后面一个停止位。

    同步传输的比特分组要大得多。它不是独立地发送每个字符,每个字符都有自己的开始位和停止位,而是把它们组合起来一起发送。我们将这些组合称为数据帧,或简称为帧。

      数据帧的第一部分包含一组同步字符,它是一个独特的比特组合,类似于前面提到的起始位,用于通知接收方一个帧已经到达,但它同时还能确保接收方的采样速度和比特的到达速度保持一致,使收发双方进入同步。

      帧的最后一部分是一个帧结束标记。与同步字符一样,它也是一个独特的比特串,类似于前面提到的停止位,用于表示在下一帧开始之前没有别的即将到达的数据了。

      同步传输通常要比异步传输快速得多。接收方不必对每个字符进行开始和停止的操作。一旦检测到帧同步字符,它就在接下来的数据到达时接收它们。另外,同步传输的开销也比较少。例如,一个典型的帧可能有500字节(即4000比特)的数据,其中可能只包含100比特的开销。这时,增加的比特位使传输的比特总数增加2.5%,这与异步传输中25 %的增值要小得多。随着数据帧中实际数据比特位的增加,开销比特所占的百分比将相应地减少。但是,数据比特位越长,缓存数据所需要的缓冲区也越大,这就限制了一个帧的大小。另外,帧越大,它占据传输媒体的连续时间也越长。在极端的情况下,这将导致其他用户等得太久。

     

    5ajax所包含的技术

        大家都知道ajax并非一种新的技术,而是几种原有技术的结合体。它由下列技术组合而成。

       1.使用CSSXHTML来表示。

       2. 使用DOM模型来交互和动态显示。

       3.使用XMLHttpRequest来和服务器进行异步通信。

       4.使用javascript来绑定和调用。

    在上面几中技术中,除了XmlHttpRequest对象以外,其它所有的技术都是基于web标准并且已经得到了广泛使用的,XMLHttpRequest虽然目前还没有被W3C所采纳,但是它已经是一个事实的标准,因为目前几乎所有的主流浏览器都支持它。

     

    December 21

    反伪科学为什么不全世界去反

    目前关于真伪科学的争论确实火药味道很浓,尤其是香港一虎竟然拉双方亮相,现眼至极。

    其实科学并不是都可以证明的,真正的证明只能靠客观实践。而现代科学也主要建立在第一原理基础之上,而第一原理却无法证明。(第一原理指量子力学的薛定鄂方程等)。当年浪荡公子德布罗意提出波是粒子的思想,完全违背传统科学思想,根本无法证明,弄得博士几乎不能毕业,但得到大物理学家郎之万和爱因斯坦的理解和宽容,顺利毕业。没有想到,这个被一些人当成玩笑的思想后来竟然被证明是正确的,并获得诺贝尔奖,防出璀璨的光芒,促成了量子力学的诞生和飞速发展。如果在中国,按几个反伪科学斗士的理论,早都打死了。即使按其理论不会一棍子打死,但小人物,小小的思想火花能抗得住多少棍子呢。

    中国文化确实有许多好东西,目前尚未研究清楚。如中医的穴位、经络等是确实存在的。据我所知,国外一些科学家已经将其当成重要的生命科学未解之迷在进行偷偷研究,期望突破,以占据科技制高点。反观我们,已经将其定义成伪科学了。

    其实,科学也不是什么都清楚的。越研究问题越多。当时牛顿就说,我只是在海滩上捡到点贝壳而已。大师都谦虚,可现在有些人竟然万能,想来真是可笑。

    现代科学也有黑箱子理论,就是有了现象,理论不明,需要研究,这也是科学方法之一。能把它看成伪科学吗。就如中医给人针灸,把病治好了,你还说针灸不科学。其实,中医就一个针灸那就是一个宝库。没有科学,你敢乱扎吗,万能大师去给扎几下看看。

    还有现代科学有个研究宇宙起源的超弦理论,认为宇宙物质都是弦构成的,现在还没有证明。

    在中国的土地上打自己老祖宗的这点东西,打吧,都打没有了,等到人家拿着获得诺贝尔奖的时候再反过来学吧。从中医到中华文化,断然一看就知道有90%是糟粕,太厉害了。


    能一下看出新东西是真科学还是伪科学,那是不容易的,有这样本领的人建议应该在全世界去反,不要从美国跑回来仅仅在中国反中国的东西,世界太大了,时不我待,快去完成你们的使命吧。
     
    --------------------------------------------------
     
     
    关闭评论
    因中医支持者在这里炸版、污言秽语满天飞,会对青少年读者造成不良影响,而新浪网又没有提供有效的屏蔽机制,所以我决定关闭这里的评论功能。欲留言、评论者请到我在牛博网的博客:
     
     
    -------------------------------------------------------
     
    这厮是越来越不象话了。你说你混个博士,也没见你搞出点啥名堂来,整天打这个打那个,最后竟然打到祖宗头上去了。逆子,该棒杀之!还是主席做得对,这种人就应该扔到农村去锻炼改造一下,才知道到底是吃干饭还是喝稀饭...
     
     
    October 17

    郁闷,DELL的服务支持...

    想给自己的LATITUDE D610升级一下内存条。第一次打DELL的800电话,问到说是要升级,就转到了另外,据说是配件部门去了。问了一下,那边很肯定的说是DDR I代的内存条。再问,加一条1G的内存,多少钱。答曰3K多。当时就疯了。一台电脑才几毛钱啊,加跟条子要这么多。当时就打120住进了积水潭。
     
    再打800电话,跑到报修的服务支持电话,报了机器服务码。一了解,还是说是DDR I代的,但是呢,说是DDR I 和DDR II都可以插。今天开了机器盖,才发现“DDR2 ONLY”写得很明显...
     
    郁闷,查了一下内存信息,原来是:HYMP532S646-E3 AA 0505N PC2-3200S-333-12。DDR II 400的条子。唉,郁闷。不过,现在的基本都是533了,400的条子还很难找。尤其是DDR I 代,价格高不说,还没货。
     
    给DELL的支持发邮件,他说记错了,说是533和400都可以用。郁闷,DELL的服务支持就这个水平?!不过,态度还算好。鉴于这点,就不公布这个哥们的名字和邮件地址了...
    August 23

    送女同事回家,要不要直接将她送上床?【转】

    某则社会新闻说,有一位雷锋式的好青年,晚上公司聚餐完毕,主动将一位漂亮的女同事送回家,这还不够,该热心肠青年意犹未尽,借口女同事老公不在家,怕她家里有贼,又将女同事送进屋,仍觉得欠缺点什么,开始参观并赞美女同事家的风格和布局。女同事给他倒来一杯水,并邀请他共同观看韩国言情片《你的老婆我做主》,可是,不巧的事情发生了,女同事的老公可能是顺着风向闻到了骚味,临时改变了出差计划,犹如天兵天将下凡,一举将两人拿获。可叹的是,这位绿帽子老公杀入的时机不对,未能捉奸在床。因而,热心青年和女同事都矢口否认他们之间有任何的不清不白,一口咬定那是同志般的友谊,比娃哈哈矿泉水还纯洁。绿帽子老公不是热心青年,但他是热血青年,所以,他找来一把菜刀,架在热心青年的脖子上,逼迫热心青年脱光衣服裤子,出去给街坊邻居看。又逼迫老婆,打电话叫来公司领导和同事到家里来,让热心青年当场写一张偷奸证明,外加一张3万元的欠条。事后,热心青年羞愤交加,遂打电话报警。结果,热血青年被判有勒索罪,入狱若干年。象江东周郎一样,热血青年赔了夫人又折兵。
     
    送女同事回家是无可厚非的,有句格言说,男人,你有义务保护身边的每一个女人,既然天黑,天下又不太平,你当一下护花使者,名正言顺。女同事的丈夫如果知道了,说不定还会感激你。因为你把他的活干了,他省了很多的麻烦。但是,把女同事送到家门口,这么晚了,还要上去坐坐的,那就已经是司马昭之心,路人皆知了。上去喝口水?你回去不能喝吗?上去聊聊天?我靠,十一二点谈理想,谈人生?要不要一起讨论一下黎以冲突和世界原油价格的新走向?找借口也得找点高明一点的嘛,比如,你家的电脑坏了吗,我帮忙修一修,比如,你家的马桶下水道堵没堵,需不需我上去帮忙通一通?夜深人静了,仍找拙劣的借口进入女同事的房间,实际上就是个淫荡的小偷,和一般的小偷不同的是,他要偷的是人。女同事的丈夫如果知道了,肯定会要用菜刀来感激你的,因为你不仅把他床下的活给帮忙干了,还想帮忙把他床上的活也给干了。而床上的活是他的自留地,神圣而不可侵犯,任何人插手,都是对他的亵渎和侮辱。热血青年捉奸是没有错的,那是出于维护一个男人的尊严,他的失败在于没有控制好自己的情绪,犯了王明式的左倾冒进错误,选择以可笑的武力来和强爱猫扑.爱生活律进行对抗,可以说,他可悲可怜,但咎由自取。
     
    这一幕《金瓶梅》2006年版上演得很惊心动魄,剧中的主角表演得也很到位,真实地反应了当代社会愈演愈烈的婚外情现象,或者是一夜情现象。随着经济的高速发展,传统的思想观念和价值体系正在某些人的脑海里逐渐崩溃,性解放在新一代的年轻人中确立了很大一块市场,追求身体的享受,追求感官的刺激,不再屈从于婚姻的束缚。伴随而来的,是居高不下,而且仍在逐年递增的离婚率。再过几年,见面的问候语就该由“吃了吗”变成“离了吗”。即使还在围城里面,也很少有几个是对婚姻放一百二十个心的,丈夫不知道妻子什么时候在外面松下裤带子,妻子不知道丈夫什么时候在外面变成了偷腥的猫。从摄象头,窃听器的热销,以及婚姻侦探公司的业务繁忙,可以看出,现代婚姻其实已经陷入深深的信任危机。维系婚姻的感情,已经在种种社会诱惑面前,变得敏感而脆弱。那种爱你一生一世,为你去生去死的爱情,已经成为传说,只能在电视电影里面找到,赚取一点点小女生小男生的眼泪。而现实的世界里,爱情就是“他有车吗,他有房吗”“她年轻漂亮吗?”一旦条件对等,成交,一笔买卖在投资方---双方父母的掌声中顺利完成。步入婚姻,也已经不再是白头偕老的起点,而是人生某个阶段某项任务的完成,一旦有风吹浪打,婚姻这条小船还是很容易触礁的,股东们说撤股就撤股。床还没睡热,拍屁股走人的,比比皆是。世风日下,人心不古,不少男的都有便宜不占白不占的心态,不少女的都有“淫妇荡妇,只要不被抓住就是好妇”的想法。这种侥幸心理促使他们红杏出墙,挑战婚姻道德极限,成为新时代的西门庆和潘金莲,不顾武大哥的感受,在王婆的家里,龙腾虎跃,把碗口粗的床柱压垮。
     
    我不是道德卫士,对此,我不便多说什么,多说也无益。我只是提醒西门大官人们,,勾引小娘子的时候,多多想一想打老虎的那位壮士,多想想他的钢刀和拳头,如果不想血洒狮子楼,最好还是少招惹家花。如果实在你精力旺盛,喜欢助淫为乐,那就采那些路边寂寞开放的野花吧。老祖宗有句古训,叫“人不淫我妇,我不淫人妻”,老惦记别人的妻子,小心报应。纵然你觉得老婆是别人的好,但也应该知道,别人不都是武大郎,兔子逼急了也是会咬人的。为了一点风流韵事送了小命,不值。
     
    所以,所有送女同事回家的热心青年们,将她送到门口就可以了,将她送上床呢,我看就免了吧。夜深了,天凉了,你请回吧。洗洗涮涮,早点睡吧。
    August 10

    ADO.NET连接字符串

    名称
    ADO.NET连接字符串
    说明 ADO.NET连接字符串:SQL Server,SQL Server 2005,ACCESS,Oracle,MySQL,Interbase,IBM DB2,Sybase,Informix,Ingres,Mimer SQL,Lightbase,PostgreSQL,Paradox,DNS,Firebird,Excel ,Text,DBF / FoxPro,AS/400 (iSeries),Exchange,Visual FoxPro,Pervasive,UDL。
    1 - SQL Server
    2 - SQL Server 2005
    3 - ACCESS, Oracle
    4 - MySQL, Interbase, IBM DB2
    5 - Sybase, Informix, Ingres, Mimer SQL, Lightbase, PostgreSQL, Paradox, DNS
    6 - Firebird, Excel , Text, DBF / FoxPro, AS/400 (iSeries), Exchange, Visual FoxPro, Pervasive, UDL
    1
    SQL Server
    ODBC
    标准安全 " Driver={SQL Server}; Server=Aron1; Database=pubs; Uid=sa; Pwd=asdasd; "
    信任的连接 " Driver={SQL Server}; Server=Aron1; Database=pubs; Trusted_Connection=yes; "
    提示输入用户名和密码 oConn.Properties(" Prompt" ) = adPromptAlways
    oConn.Open " Driver={SQL Server}; Server=Aron1; DataBase=pubs; "
    OLE DB, OleDbConnection (.NET)
    标准安全 " Provider=sqloledb; Data Source=Aron1; Initial Catalog=pubs; User Id=sa; Password=asdasd; "
    信任的连接 " Provider=sqloledb; Data Source=Aron1; Initial Catalog=pubs; Integrated Security=SSPI; "
    (use serverName\instanceName as Data Source to use an specifik SQLServer instance, only SQLServer2000)
    提示输入用户名和密码 oConn.Provider = " sqloledb"
    oConn.Properties(" Prompt" ) = adPromptAlways
    oConn.Open " Data Source=Aron1; Initial Catalog=pubs; "
    IP地址连接管道 " Provider=sqloledb; Data Source=190.190.200.100,1433; Network Library=DBMSSOCN; Initial Catalog=pubs; User ID=sa; Password=asdasd; "
    (DBMSSOCN=TCP/IP instead of Named Pipes, at the end of the Data Source is the port to use (1433 is the default))
    SqlConnection (.NET)
    标准安全 " Data Source=Aron1; Initial Catalog=pubs; User Id=sa; Password=asdasd; "
    - or -
    " Server=Aron1; Database=pubs; User ID=sa; Password=asdasd; Trusted_Connection=False"
    (both connection strings produces the same result)
    信任的连接 " Data Source=Aron1; Initial Catalog=pubs; Integrated Security=SSPI; "
    - or -
    " Server=Aron1; Database=pubs; Trusted_Connection=True; "
    (both connection strings produces the same result)
    (use serverName\instanceName as Data Source to use an specifik SQLServer instance, only SQLServer2000)
    IP地址连接管道 " Data Source=190.190.200.100,1433; Network Library=DBMSSOCN; Initial Catalog=pubs; User ID=sa; Password=asdasd; "
    (DBMSSOCN=TCP/IP instead of Named Pipes, at the end of the Data Source is the port to use (1433 is the default))
    定义SqlConnection对象 C#:
    using System.Data.SqlClient;
    SqlConnection oSQLConn = new SqlConnection();
    oSQLConn.ConnectionString=" my connection string" ;
    oSQLConn.Open();
    VB.NET:
    Imports System.Data.SqlClient
    Dim oSQLConn As SqlConnection = New SqlConnection()
    oSQLConn.ConnectionString=" my connection string"
    oSQLConn.Open()
    Data Shape
    MS Data Shape " Provider=MSDataShape; Data Provider=SQLOLEDB; Data Source=Aron1; Initial Catalog=pubs; User ID=sa; Password=asdasd; "
    2
    SQL Server 2005
    SQL Native Client ODBC Driver
    标准安全 " Driver={SQL Native Client}; Server=Aron1; Database=pubs; UID=sa; PWD=asdasd; "
    信任的连接 " Driver={SQL Native Client}; Server=Aron1; Database=pubs; Trusted_Connection=yes; "
    Equivalents
    Integrated Security=SSPI equals Trusted_Connection=yes
    提示输入用户名和密码 oConn.Properties(" Prompt" ) = adPromptAlways
    oConn.Open " Driver={SQL Native Client}; Server=Aron1; DataBase=pubs; "
    授权的MARS(多重活动结果集) " Driver={SQL Native Client}; Server=Aron1; Database=pubs; Trusted_Connection=yes; MARS_Connection=yes"
    Equivalents
    MultipleActiveResultSets=true equals MARS_Connection=yes
    加密数据网络传输 " Driver={SQL Native Client}; Server=Aron1; Database=pubs; Trusted_Connection=yes; Encrypt=yes"
    在本地SQL服务器实例附加数据库文件 " Driver={SQL Native Client}; Server=.\SQLExpress; AttachDbFilename=c:\asd\qwe\mydbfile.mdf; Database=dbname; Trusted_Connection=Yes; "
    - or -
    " Driver={SQL Native Client}; Server=.\SQLExpress; AttachDbFilename=|DataDirectory|mydbfile.mdf; Database=dbname; Trusted_Connection=Yes; "
    (use |DataDirectory| when your database file resides in the data directory)
    SQL Native Client OLE DB Provider
    标准安全 " Provider=SQLNCLI; Server=Aron1; Database=pubs; UID=sa; PWD=asdasd; "
    信任的连接 " Provider=SQLNCLI; Server=Aron1; Database=pubs; Trusted_Connection=yes; "
    Equivalents
    Integrated Security=SSPI equals Trusted_Connection=yes
    提示输入用户名和密码 oConn.Properties(" Prompt" ) = adPromptAlways
    oConn.Open " Provider=SQLNCLI; Server=Aron1; DataBase=pubs; "
    授权的MARS(多重活动结果集) " Provider=SQLNCLI; Server=Aron1; Database=pubs; Trusted_Connection=yes; MarsConn=yes"
    Equivalents
    MarsConn=yes equals MultipleActiveResultSets=true equals MARS_Connection=yes
    加密数据网络传输 " Provider=SQLNCLI; Server=Aron1; Database=pubs; Trusted_Connection=yes; Encrypt=yes"
    在本地SQL服务器实例附加数据库文件 " Provider=SQLNCLI; Server=.\SQLExpress; AttachDbFilename=c:\asd\qwe\mydbfile.mdf; Database=dbname; Trusted_Connection=Yes; "
    - or -
    " Provider=SQLNCLI; Server=.\SQLExpress; AttachDbFilename=|DataDirectory|mydbfile.mdf; Database=dbname; Trusted_Connection=Yes; "
    (use |DataDirectory| when your database file resides in the data directory)
    SqlConnection (.NET)
    标准安全 " Data Source=Aron1; Initial Catalog=pubs; User Id=sa; Password=asdasd; "
    - or -
    " Server=Aron1; Database=pubs; User ID=sa; Password=asdasd; Trusted_Connection=False"
    (both connection strings produces the same result)
    信任的连接 " Data Source=Aron1; Initial Catalog=pubs; Integrated Security=SSPI; "
    - or -
    " Server=Aron1; Database=pubs; Trusted_Connection=True; "
    (both connection strings produces the same result)
    IP地址连接管道 " Data Source=190.190.200.100,1433; Network Library=DBMSSOCN; Initial Catalog=pubs; User ID=sa; Password=asdasd; "
    (DBMSSOCN=TCP/IP instead of Named Pipes, at the end of the Data Source is the port to use (1433 is the default))
    授权的MARS(多重活动结果集) " Server=Aron1; Database=pubs; Trusted_Connection=True; MultipleActiveResultSets=true"
    Note! Use ADO.NET 2.0 for MARS functionality. MARS is not supported in ADO.NET 1.0 nor ADO.NET 1.1
    在本地SQL服务器实例附加数据库文件 " Server=.\SQLExpress; AttachDbFilename=c:\asd\qwe\mydbfile.mdf; Database=dbname; Database=dbname; Trusted_Connection=Yes; "
    - or -
    " Server=.\SQLExpress; AttachDbFilename=|DataDirectory|mydbfile.mdf; Database=dbname; Trusted_Connection=Yes; "
    Using " User Instance" on a local SQL Server Express instance " Data Source=.\SQLExpress; integrated security=true; attachdbfilename=|DataDirectory|\mydb.mdf; user instance=true; "
    The " User Instance" functionality creates a new SQL Server instance on the fly during connect. This works only on a local SQL Server 2005 instance and only when connecting using windows authentication over local named pipes. The purpose is to be able to create a full rights SQL Server instance to a user with limited administrative rights on the computer. To enable the functionality: sp_configure 'user instances enabled','1' (0 to disable)
    Using SQL Server 2005 Express? Don't miss the server name syntax: SERVERNAME\SQLEXPRESS (Substitute " SERVERNAME" with the name of the computer)
    Context Connection - connecting to " self" from within your CLR stored prodedure/function
    Context Connection - connecting to " self" from within your CLR stored prodedure/function
    C# using(SqlConnection connection = new SqlConnection("context connection=true"))
    {
    connection.Open();
    // Use the connection
    }
    Visual Basic Using connection as new SqlConnection("context connection=true")
    connection.Open()
    ' Use the connection
    End Using
    Read more
    When to use SQL Native Client? .Net applications
    Do not use the SQL Native Client. Use the .NET Framework Data Provider for SQL Server (SqlConnection).
    COM applications, all other then .Net applications
    COM applications, all other then .Net applications
    Use the SQL Native Client if you are accessing an SQL Server 2005 and need the new features of SQL Server 2005 such as MARS, encryption, XML data type etc. Continue use your current provider (OLE DB / ODBC through the MDAC package) if you are not connecting to an SQL Server 2005 (that's quite obvious eh..) or if you are connecting to an SQL Server 2005 but are not using any of the new SQL Server 2005 features.
    3
    ACCESS
    ODBC
    标准安全 "Driver={Microsoft Access Driver (*.mdb)}; Dbq=C:\mydatabase.mdb; Uid=Admin; Pwd=; "
    工作组 "Driver={Microsoft Access Driver (*.mdb)}; Dbq=C:\mydatabase.mdb; SystemDB=C:\mydatabase.mdw; "
    独占 "Driver={Microsoft Access Driver (*.mdb)}; Dbq=C:\mydatabase.mdb; Exclusive=1; Uid=admin; Pwd="
    OLE DB, OleDbConnection (.NET)
    标准安全 "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=\somepath\mydb.mdb; User Id=admin; Password=; "
    工作组 (system database) "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=\somepath\mydb.mdb; Jet OLEDB:System Database=system.mdw; "
    使用密码 "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=\somepath\mydb.mdb; Jet OLEDB:Database Password=MyDbPassword; "
     
    Oracle
    ODBC
    新版本 "Driver={Microsoft ODBC for Oracle}; Server=OracleServer.world; Uid=Username; Pwd=asdasd; "
    旧版本 "Driver={Microsoft ODBC Driver for Oracle}; ConnectString=OracleServer.world; Uid=myUsername; Pwd=myPassword; "
    OLE DB, OleDbConnection (.NET)
    标准安全 "Provider=msdaora; Data Source=MyOracleDB; User Id=UserName; Password=asdasd; "
    This one's from Microsoft, the following are from Oracle
    标准安全 "Provider=OraOLEDB.Oracle; Data Source=MyOracleDB; User Id=Username; Password=asdasd; "
    信任的连接 "Provider=OraOLEDB.Oracle; Data Source=MyOracleDB; OSAuthent=1; "
    OracleConnection (.NET)
    标准 "Data Source=MyOracleDB; Integrated Security=yes; "
    This one works only with Oracle 8i release 3 or later
    指定用户名和密码 "Data Source=MyOracleDB; User Id=username; Password=passwd; Integrated Security=no; "
    This one works only with Oracle 8i release 3 or later
    定义OracleConnection对象 C#:
    using System.Data.OracleClient;
    OracleConnection oOracleConn = new OracleConnection();
    oOracleConn.ConnectionString = "my connection string";
    oOracleConn.Open();
    VB.NET:
    Imports System.Data.OracleClient
    Dim oOracleConn As OracleConnection = New OracleConnection()
    oOracleConn.ConnectionString = "my connection string"
    oOracleConn.Open()
    Core Labs OraDirect (.NET)
    标准 "User ID=scott; Password=tiger; Host=ora; Pooling=true; Min Pool Size=0; Max Pool Size=100; Connection Lifetime=0"
    Data Shape
    微软数据模型 "Provider=MSDataShape.1; Persist Security Info=False; Data Provider=MSDAORA; Data Source=orac; user id=username; password=mypw"
    4
    MySQL
    MyODBC
    MyODBC 2.50 本地数据库 "Driver={mySQL}; Server=localhost; Option=16834; Database=mydatabase; "
    MyODBC 2.50 远程数据库: "Driver={mySQL}; Server=data.domain.com; Port=3306; Option=131072; Stmt=; Database=my-database; Uid=username; Pwd=password; "
    MyODBC 3.51 本地数据库 "DRIVER={MySQL ODBC 3.51 Driver}; SERVER=localhost; DATABASE=myDatabase; USER=myUsername; PASSWORD=myPassword; OPTION=3; "
    MyODBC 3.51 远程数据库 "DRIVER={MySQL ODBC 3.51 Driver}; SERVER=data.domain.com; PORT=3306; DATABASE=myDatabase; USER=myUsername; PASSWORD=myPassword; OPTION=3; "
    OLE DB, OleDbConnection (.NET)
    标准 "Provider=MySQLProv; Data Source=mydb; User Id=UserName; Password=asdasd; "
    Connector/Net 1.0 (.NET)
    标准 "Server=Server; Database=Test; Uid=UserName; Pwd=asdasd; "
    Download the driver at MySQL Developer Zone
    指定端口 "Server=Server; Port=1234; Database=Test; Uid=UserName; Pwd=asdasd; "
    Default port is 3306. Enter value -1 to use a named pipe connection.
    定义mysqlclient 连接对象 C#:
    using MySql.Data.MySqlClient;
    MySqlConnection oMySqlConn = new MySqlConnection();
    oMySqlConn.ConnectionString = "Server=Server; Database=Test; Uid=UserName; Pwd=asdasd; ";
    oMySqlConn.Open();
    VB.NET:
    Imports MySql.Data.MySqlClient
    Dim oMySqlConn As MySqlConnection = New MySqlConnection()
    oMySqlConn.ConnectionString = "Server=Server; Database=Test; Uid=UserName; Pwd=asdasd; "
    oMySqlConn.Open()
    MySqlConnection (.NET)
    eInfoDesigns.dbProvider "Data Source=server; Database=mydb; User ID=username; Password=pwd; Command Logging=false"
    This one is used with eInfoDesigns dbProvider, an add-on to .NET
    定义MySqlConnection连接对象 C#:
    using eInfoDesigns.dbProvider.MySqlClient;
    MySqlConnection oMySqlConn = new MySqlConnection();
    oMySqlConn.ConnectionString = "my connection string";
    oMySqlConn.Open();
    VB.NET:
    Imports eInfoDesigns.dbProvider.MySqlClient
    Dim oMySqlConn As MySqlConnection = New MySqlConnection()
    oMySqlConn.ConnectionString = "my connection string"
    oMySqlConn.Open()
    SevenObjects MySqlClient (.NET)
    标准 "Host=server; UserName=myusername; Password=mypassword; Database=mydb; "
    This is a freeware ADO.Net data provider from SevenObjects
    Core Labs MySQLDirect (.NET)
    标准 "User ID=root; Password=pwd; Host=localhost; Port=3306; Database=test; Direct=true; Protocol=TCP; Compress=false; Pooling=true; Min Pool Size=0; Max Pool Size=100; Connection Lifetime=0"
     
    Interbase
    ODBC, Easysoft
    本地计算机 "Driver={Easysoft IB6 ODBC}; Server=localhost; Database=localhost:C:\mydatabase.gdb; Uid=username; Pwd=password"
    远程计算机 "Driver={Easysoft IB6 ODBC}; Server=ComputerName; Database=ComputerName:C:\mydatabase.gdb; Uid=username; Pwd=password"
    ODBC, Intersolv
    本地计算机 "Driver={INTERSOLV InterBase ODBC Driver (*.gdb)}; Server=localhost; Database=localhost:C:\mydatabase.gdb; Uid=username; Pwd=password"
    远程计算机 "Driver={INTERSOLV InterBase ODBC Driver (*.gdb)}; Server=ComputerName; Database=ComputerName:C:\mydatabase.gdb; Uid=username; Pwd=password"
    OLE DB, SIBPROvider
    标准 "provider=sibprovider; location=localhost:; data source=c:\databases\gdbs\mygdb.gdb; user id=SYSDBA; password=masterkey"
    指定字符集 "provider=sibprovider; location=localhost:; data source=c:\databases\gdbs\mygdb.gdb; user id=SYSDBA; password=masterkey; character set=ISO8859_1"
    指定规则 "provider=sibprovider; location=localhost:; data source=c:\databases\gdbs\mygdb.gdb; user id=SYSDBA; password=masterkey; role=DIGITADORES"
     
    IBM DB2
    OLE DB, OleDbConnection (.NET) from ms
    TCP/IP "Provider=DB2OLEDB; Network Transport Library=TCPIP; Network Address=XXX.XXX.XXX.XXX; Initial Catalog=MyCtlg; Package Collection=MyPkgCol; Default Schema=Schema; User ID=MyUser; Password=MyPW"
    APPC "Provider=DB2OLEDB; APPC Local LU Alias=MyAlias; APPC Remote LU Alias=MyRemote; Initial Catalog=MyCtlg; Package Collection=MyPkgCol; Default Schema=Schema; User ID=MyUser; Password=MyPW"
    IBM's OLE DB Provider (shipped with IBM DB2 UDB v7 or above)
    TCP/IP "Provider=IBMDADB2; Database=sample; HOSTNAME=db2host; PROTOCOL=TCPIP; PORT=50000; uid=myUserName; pwd=myPwd;"
    ODBC
    标准 "driver={IBM DB2 ODBC DRIVER}; Database=myDbName; hostname=myServerName; port=myPortNum; protocol=TCPIP; uid=myUserName; pwd=myPwd"
    5
    Sybase
    ODBC
    标准 Sybase System 12 (or 12.5) Enterprise Open Client "Driver={SYBASE ASE ODBC Driver}; Srvr=Aron1; Uid=username; Pwd=password"
    标准 Sybase System 11 "Driver={SYBASE SYSTEM 11}; Srvr=Aron1; Uid=username; Pwd=password; Database=mydb"
    Intersolv 3.10 "Driver={INTERSOLV 3.10 32-BIT Sybase}; Srvr=Aron1; Uid=username; Pwd=password;"
    Sybase SQL Anywhere (former Watcom SQL ODBC driver) "ODBC; Driver=Sybase SQL Anywhere 5.0; DefaultDir=c:\dbfolder\; Dbf=c:\mydatabase.db; Uid=username; Pwd=password; Dsn="""""
    OLE DB
    Adaptive Server Anywhere (ASA) "Provider=ASAProv; Data source=myASA"
    Adaptive Server Enterprise (ASE) with Data Source .IDS file "Provider=Sybase ASE OLE DB Provider; Data source=myASE"
    Adaptive Server Enterprise (ASE) "Provider=Sybase.ASEOLEDBProvider; Srvr=myASEserver,5000; Catalog=myDBname; User Id=username; Password=password"
    - some reports on problem using the above one, try the following as an alternative -

    "Provider=Sybase.ASEOLEDBProvider; Server Name=myASEserver,5000; Initial Catalog=myDBname; User Id=username; Password=password"
    This one works only from Open Client 12.5 where the server port number feature works,following fully qualified connection strings to be used without definingfony .IDS Data Source files.

    AseConnection (.NET)
    标准 "Data Source='myASEserver'; Port=5000; Database='myDBname'; UID='username'; PWD='password'; "
    定义AseConnection连接对象 C#:
    using Sybase.Data.AseClient;
    AseConnection oCon = new AseConnection();
    oCon.ConnectionString="my connection string";
    oCon.Open();
    VB.NET:
    Imports System.Data.AseClient
    Dim oCon As AseConnection = New AseConnection()
    oCon.ConnectionString="my connection string"
    oCon.Open()
     
    Informix
    ODBC
    Informix 3.30 "Dsn=''; Driver={INFORMIX 3.30 32 BIT}; Host=hostname; Server=myserver; Service=service-name; Protocol=olsoctcp; Database=mydb; UID=username; PWD=myPwd"
    Informix-CLI 2.5 "Driver={Informix-CLI 2.5 (32 Bit)}; Server=myserver; Database=mydb; Uid=username; Pwd=myPwd"
    OLE DB
    IBM Informix OLE DB Provider "Provider=Ifxoledbc.2; password=myPw; User ID=myUser; Data Source=dbName@serverName; Persist Security Info=true"
     
    Ingres
    ODBC
    DSN-less "Provider=MSDASQL.1; DRIVER=Ingres; SRVR=xxxxx; DB=xxxxx; Persist Security Info=False; uid=xxxx; pwd=xxxxx; SELECTLOOPS=N; Extended Properties="""SERVER=xxxxx; DATABASE=xxxxx; SERVERTYPE=INGRES""
     
    Mimer SQL
    ODBC
    标准安全 "Driver={MIMER}; Database=mydb; Uid=myuser; Pwd=mypw; "
    提示输入用户名和密码 "Driver={MIMER}; Database=mydb;"
     
    Lightbase
    标准
    标准 "user=USERLOGIN; password=PASSWORD; UDB=USERBASE; server=SERVERNAME"
     
    PostgreSQL
    Core Labs PostgreSQLDirect (.NET)
    标准 "User ID=root; Password=pwd; Host=localhost; Port=5432; Database=testdb; Pooling=true; Min Pool Size=0; Max Pool Size=100; Connection Lifetime=0"
    PostgreSQL driver
    标准 "DRIVER={PostgreSQL}; SERVER=ipaddress; port=5432; DATABASE=dbname; UID=username; PWD=password; "
    Npgsql by pgFoundry (.NET)
    SSL activated "Server=127.0.0.1; Port=5432; Userid=myuserid; password=mypw; Protocol=3; SSL=true; Pooling=true; MinPoolSize=3; MaxPoolSize=20; Encoding=UNICODE; Timeout=20; SslMode=Require"
    Without SSL "Server=127.0.0.1; Port=5432; Userid=myuserid; password=mypw; Protocol=3; SSL=false; Pooling=true; MinPoolSize=1; MaxPoolSize=20; Encoding=UNICODE; Timeout=15; SslMode=Disable"
     
    Paradox
    ODBC
    5.X "Driver={Microsoft Paradox Driver (*.db )}; DriverID=538; Fil=Paradox 5.X; DefaultDir=c:\pathToDb\; Dbq=c:\pathToDb\; CollatingSequence=ASCII"
    7.X "Provider=MSDASQL.1; Persist Security Info=False; Mode=Read; Extended Properties='DSN=Paradox; DBQ=C:\myDb; DefaultDir=C:\myDb; DriverId=538; FIL=Paradox 7.X; MaxBufferSize=2048; PageTimeout=600; '; Initial Catalog=C:\myDb"
    OleDbConnection (.NET)
    标准 "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\myDb; Extended Properties=Paradox 5.x;"
     
    DNS
    ODBC
    DSN "DSN=myDsn; Uid=username; Pwd=; "
    File DSN "FILEDSN=c:\myData.dsn; Uid=username; Pwd=;"
    6
    Firebird
    ODBC - IBPhoenix Open Source
    标准 "DRIVER=Firebird/InterBase(r) driver; UID=SYSDBA; PWD=masterkey; DBNAME=D:\FIREBIRD\examples\TEST.FDB"
    .NET - Firebird .Net Data Provider
    标准 "User=SYSDBA; Password=masterkey; Database=SampleDatabase.fdb; DataSource=localhost; Port=3050; Dialect=3; Charset=NONE; Role=; Connection lifetime=15; Pooling=true; MinPoolSize=0; MaxPoolSize=50; Packet Size=8192; ServerType=0"
     
    Excel
    ODBC
    标准 "Driver={Microsoft Excel Driver (*.xls)}; DriverId=790; Dbq=C:\MyExcel.xls; DefaultDir=c:\mypath; "
    OLE DB
    标准 "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\MyExcel.xls; Extended Properties=""Excel 8.0; HDR=Yes; IMEX=1"""
    "HDR=Yes; " indicates that the first row contains columnnames, not data
    "IMEX=1; " tells the driver to always read "intermixed" data columns as text
    TIP! SQL syntax: "SELECT * FROM [sheet1$]" - i.e. worksheet name followed by a "$" and wrapped in "[" "]" brackets.
     
    Text
    ODBC
    标准 "Driver={Microsoft Text Driver (*.txt; *.csv)}; Dbq=c:\txtFilesFolder\; Extensions=asc,csv,tab,txt; "
    OLE DB
    标准 "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\txtFilesFolder\; Extended Properties=""text; HDR=Yes; FMT=Delimited"""
    "HDR=Yes; " indicates that the first row contains columnnames, not data
     
    DBF / FoxPro
    ODBC
    标准 "Driver={Microsoft dBASE Driver (*.dbf)}; DriverID=277; Dbq=c:\mydbpath; "
    OLE DB, OleDbConnection (.NET)
    标准 "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\folder; Extended Properties=dBASE IV; User ID=Admin; Password="
     
    AS/400 (iSeries)
    OLE DB, OleDbConnection (.NET)
    IBM Client Access OLE DB provider "PROVIDER=IBMDA400; DATA SOURCE=MY_SYSTEM_NAME; USER ID=myUserName; PASSWORD=myPwd"
    IBM Client Access OLE DB provider "PROVIDER=IBMDA400; DATA SOURCE=MY_SYSTEM_NAME; USER ID=myUserName; PASSWORD=myPwd; DEFAULT COLLECTION=MY_LIBRARY; "
    ODBC
    IBM Client Access ODBC driver "Driver={Client Access ODBC Driver (32-bit)}; System=my_system_name; Uid=myUserName; Pwd=myPwd"
     
    Exchange
    OLE DB
    Exchange OLE DB provider "ExOLEDB.DataSource"
    Specify store in the connection open command like this: conn.open "http://servername/mypublicstore"
     
    Visual FoxPro
    OLE DB, OleDbConnection (.NET)
    Database container (.DBC) "Provider=vfpoledb.1; Data Source=C:\MyDbFolder\MyDbContainer.dbc; Collating Sequence=machine"
    Free table directory "Provider=vfpoledb.1; Data Source=C:\MyDataDirectory\; Collating Sequence=general"
    Force the provider to use an ODBC DSN "Provider=vfpoledb.1; DSN=MyDSN"
    ODBC
    Database container (.DBC) "Driver={Microsoft Visual FoxPro Driver}; SourceType=DBC; SourceDB=c:\myvfpdb.dbc; Exclusive=No; NULL=NO; Collate=Machine; BACKGROUNDFETCH=NO; DELETED=NO"
    Free Table directory "Driver={Microsoft Visual FoxPro Driver}; SourceType=DBF; SourceDB=c:\myvfpdbfolder; Exclusive=No; Collate=Machine; NULL=NO; DELETED=NO; BACKGROUNDFETCH=NO"
     
    Pervasive
    ODBC
    标准: "Driver={Pervasive ODBC Client Interface}; ServerName=srvname; dbq=@dbname"
    OLD DB
    标准: "Provider=PervasiveOLEDB; Data Source=C:\path"
     
    UDL
    UDL
    UDL "File Name=c:\myDataLink.udl;"
    August 08

    BUG依旧--用于Oracle的.Net Framework数据提供程序

    在VS2003版本中,就发现System.Data.OracleClient下的OracleCommandBuilder.DeriveParameters存在BUG,在VS2005中实验,还是存在。原文:http://dotnba.spaces.live.com/blog/cns!30FC79445E6124EC!2024.entry?&&DI=6709&IG=caf12812b5bd4440945d1250b2a68053&POS=1&CM=WPU&CE=1&CS=OTH&SR=1
     
    VS2005下测试代码:
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.Common;
    using Microsoft.Practices.EnterpriseLibrary.Data;
    using Microsoft.Practices.EnterpriseLibrary.Data.Configuration;
    namespace ELStudy
    {
        public partial class DiscoverOracleParameters : Form
        {
            public DiscoverOracleParameters()
            {
                InitializeComponent();
            }
            private void btnDiscover_Click(object sender, EventArgs e)
            {
                //使用System.Data.OracleClient
                string spName = tbSP.Text;
                System.Data.OracleClient.OracleConnection oraConnection = new System.Data.OracleClient.OracleConnection(tbConnection.Text);
                System.Data.OracleClient.OracleCommand oraCmd = new System.Data.OracleClient.OracleCommand(spName, oraConnection);
                oraCmd.CommandType = CommandType.StoredProcedure;
                try
                {
                    oraConnection.Open();
                    System.Data.OracleClient.OracleCommandBuilder.DeriveParameters(oraCmd);
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message);
                }
                finally
                {
                    oraConnection.Dispose();
                }
                rtbParams.Text = "";
                foreach (System.Data.OracleClient.OracleParameter oraParam in oraCmd.Parameters)
                {
                    rtbParams.Text = rtbParams.Text + "," + oraParam.ParameterName;
                }
                oraCmd.Dispose();
            }
            private void btnDiscoverO_Click(object sender, EventArgs e)
            {
                //使用 Oracle 提供的.Net数据访问Dll
                string spName = tbSP.Text;
                Oracle.DataAccess.Client.OracleConnection oraConnection = new Oracle.DataAccess.Client.OracleConnection(tbConnection.Text);
                Oracle.DataAccess.Client.OracleCommand oraCmd = new Oracle.DataAccess.Client.OracleCommand(spName, oraConnection);
                oraCmd.CommandType = CommandType.StoredProcedure;
                try
                {
                    oraConnection.Open();
                    Oracle.DataAccess.Client.OracleCommandBuilder.DeriveParameters(oraCmd);
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message);
                }
                finally
                {
                    oraConnection.Dispose();
                }
                rtbParams.Text = "";
                foreach (Oracle.DataAccess.Client.OracleParameter oraParam in oraCmd.Parameters)
                {
                    rtbParams.Text = rtbParams.Text + "," + oraParam.ParameterName;
                }
                oraCmd.Dispose();
            }
            private void btnDiscover1_Click(object sender, EventArgs e)
            {
                //使用Enterprise Library(也是System.Data.OracleClient)
                string spName = tbSP.Text;
                Database db = DatabaseFactory.CreateDatabase("OracleConnectionString");
                DbCommand Procdbcomm = db.GetStoredProcCommand(spName);
                db.DiscoverParameters(Procdbcomm);
                rtbParams.Text = "";
                foreach (System.Data.OracleClient.OracleParameter oraParam in Procdbcomm.Parameters)
                {
                    rtbParams.Text = rtbParams.Text + "," + oraParam.ParameterName;
                }
                Procdbcomm.Dispose();
            }
        }
    }
     
    namespace ELStudy
    {
        partial class DiscoverOracleParameters
        {
            /// <summary>
            /// 必需的设计器变量。
            /// </summary>
            private System.ComponentModel.IContainer components = null;
            /// <summary>
            /// 清理所有正在使用的资源。
            /// </summary>
            /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
            #region Windows 窗体设计器生成的代码
            /// <summary>
            /// 设计器支持所需的方法 - 不要
            /// 使用代码编辑器修改此方法的内容。
            /// </summary>
            private void InitializeComponent()
            {
                this.btnDiscover = new System.Windows.Forms.Button();
                this.tbSP = new System.Windows.Forms.TextBox();
                this.rtbParams = new System.Windows.Forms.RichTextBox();
                this.label1 = new System.Windows.Forms.Label();
                this.label2 = new System.Windows.Forms.Label();
                this.label3 = new System.Windows.Forms.Label();
                this.tbConnection = new System.Windows.Forms.TextBox();
                this.btnDiscoverO = new System.Windows.Forms.Button();
                this.btnDiscover1 = new System.Windows.Forms.Button();
                this.SuspendLayout();
                //
                // btnDiscover
                //
                this.btnDiscover.Location = new System.Drawing.Point(371, 79);
                this.btnDiscover.Name = "btnDiscover";
                this.btnDiscover.Size = new System.Drawing.Size(75, 23);
                this.btnDiscover.TabIndex = 0;
                this.btnDiscover.Text = "查找...";
                this.btnDiscover.UseVisualStyleBackColor = true;
                this.btnDiscover.Click += new System.EventHandler(this.btnDiscover_Click);
                //
                // tbSP
                //
                this.tbSP.Location = new System.Drawing.Point(70, 29);
                this.tbSP.Name = "tbSP";
                this.tbSP.Size = new System.Drawing.Size(376, 21);
                this.tbSP.TabIndex = 1;
                this.tbSP.Text = "sys.subptxt";
                //
                // rtbParams
                //
                this.rtbParams.Location = new System.Drawing.Point(6, 79);
                this.rtbParams.Name = "rtbParams";
                this.rtbParams.Size = new System.Drawing.Size(345, 115);
                this.rtbParams.TabIndex = 2;
                this.rtbParams.Text = "";
                //
                // label1
                //
                this.label1.AutoSize = true;
                this.label1.Location = new System.Drawing.Point(4, 34);
                this.label1.Name = "label1";
                this.label1.Size = new System.Drawing.Size(65, 12);
                this.label1.TabIndex = 3;
                this.label1.Text = "存储过程:";
                //
                // label2
                //
                this.label2.AutoSize = true;
                this.label2.Location = new System.Drawing.Point(4, 60);
                this.label2.Name = "label2";
                this.label2.Size = new System.Drawing.Size(65, 12);
                this.label2.TabIndex = 4;
                this.label2.Text = "参    数:";
                //
                // label3
                //
                this.label3.AutoSize = true;
                this.label3.Location = new System.Drawing.Point(4, 7);
                this.label3.Name = "label3";
                this.label3.Size = new System.Drawing.Size(65, 12);
                this.label3.TabIndex = 6;
                this.label3.Text = "连接字符:";
                //
                // tbConnection
                //
                this.tbConnection.Location = new System.Drawing.Point(70, 2);
                this.tbConnection.Name = "tbConnection";
                this.tbConnection.Size = new System.Drawing.Size(376, 21);
                this.tbConnection.TabIndex = 5;
                this.tbConnection.Text = "Data Source=adim_qs;user id=adimoper;password=adim;";
                //
                // btnDiscoverO
                //
                this.btnDiscoverO.Location = new System.Drawing.Point(371, 107);
                this.btnDiscoverO.Name = "btnDiscoverO";
                this.btnDiscoverO.Size = new System.Drawing.Size(75, 23);
                this.btnDiscoverO.TabIndex = 7;
                this.btnDiscoverO.Text = "查找...";
                this.btnDiscoverO.UseVisualStyleBackColor = true;
                this.btnDiscoverO.Click += new System.EventHandler(this.btnDiscoverO_Click);
                //
                // btnDiscover1
                //
                this.btnDiscover1.Location = new System.Drawing.Point(371, 135);
                this.btnDiscover1.Name = "btnDiscover1";
                this.btnDiscover1.Size = new System.Drawing.Size(75, 23);
                this.btnDiscover1.TabIndex = 8;
                this.btnDiscover1.Text = "查找...";
                this.btnDiscover1.UseVisualStyleBackColor = true;
                this.btnDiscover1.Click += new System.EventHandler(this.btnDiscover1_Click);
                //
                // DiscoverOracleParameters
                //
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(448, 196);
                this.Controls.Add(this.btnDiscover1);
                this.Controls.Add(this.btnDiscoverO);
                this.Controls.Add(this.label3);
                this.Controls.Add(this.tbConnection);
                this.Controls.Add(this.label2);
                this.Controls.Add(this.label1);
                this.Controls.Add(this.rtbParams);
                this.Controls.Add(this.tbSP);
                this.Controls.Add(this.btnDiscover);
                this.Name = "DiscoverOracleParameters";
                this.Text = "DiscoverOracleParameters";
                this.ResumeLayout(false);
                this.PerformLayout();
            }
            #endregion
            private System.Windows.Forms.Button btnDiscover;
            private System.Windows.Forms.TextBox tbSP;
            private System.Windows.Forms.RichTextBox rtbParams;
            private System.Windows.Forms.Label label1;
            private System.Windows.Forms.Label label2;
            private System.Windows.Forms.Label label3;
            private System.Windows.Forms.TextBox tbConnection;
            private System.Windows.Forms.Button btnDiscoverO;
            private System.Windows.Forms.Button btnDiscover1;
        }
    }
    August 04

    给李博士的一封信

    亲爱的李博士:

    你在资本主义的纽约还好吗,是否也象我一样想你。我的朋友傻大木经理现在有一个问题,希望你能为他这只为爱迷途的羔羊点燃一盏灯。

    有一组人,每个人都可以用一个唯一的数字来表示他们。同时,还有一堆事情,每件事情也可以用一个数字来代表。然后这些人中每个人都可能去做这些事情中的任何一件或者几件,甚至全部(可怜),也可以一件不做。有个组长(就是傻大木以前的工作)在记录每个人参与的事情。组长想迅速知道任何一个人做了哪些事情,或者偷懒什么都没做,抑或是哪件事情有哪些人在做。

    一开始组长这样来记录:

             

    U1                 T1

    U8                 T5

    U2                 T1

    U2                 T3

    …………………

    但是组长很快发现,自己的纸不够用了,因为这个记录实在很长。同时要找到一个人做了哪些事也实在不容易。于是,他就想,他手头有5件事情,那么每件事情用1位来表示好了。并且每件事情都在位置的固定位置。比如:00000代表没做一件事,00010表示做了第二件事。呵呵这个聪明的组长就是二进制的发明者了。那么上面的情况组长只要这样记录就好了:

             

    U1                 1 (00001)

    U2                 5(00101)

    U8                 16(10000)

    …………………

    这样,组长就将最先最坏情况下是Ux * TY 条记录减少成了与人员数一样了。组长的管理效率从此大幅提高,并且减少纸张的消耗,受到了上级领导的赏识。领导在酒后一高兴,就让组长升作经理。一作经理,事情也多了,原来的五件一下子变成了10件,甚至更多。如果还按照原来的办法,这个数字可能会很庞大。由于傻大木只上过本科,所以他就不会计算了,在那里干愁。为了让傻大木开心,我就挺身而出,为他推荐了李博士

    亲爱的李博士,你是否有主意了呢?

    June 11

    What Gender Is Your Brain?

    Your Brain is 47% Female, 53% Male
    Your brain is a healthy mix of male and female
    You are both sensitive and savvy
    Rational and reasonable, you tend to keep level headed
    But you also tend to wear your heart on your sleeve
     
     
    Your Quirk Factor: 38%
    You have a few little quirks, but you generally blend in well with society.
    Only those who know you well know how weird you can be.
    June 07

    了解几个概念_转

    ADSL概念

      "超级一线通" ADSL业务是新一代超强型宽带接入服务。ADSL(Asymmetrical Digital Subscriber Line)中文全称为非对称数字用户线环路。

     

    ADSL优点

    1、具有很高的传输速率: 理论上,ADSL的传输速率上行最高可达640Kpbs,下行最高可达8Mbps。用户可以在因特网自由冲浪,浏览新闻,娱乐,游戏,下载图片无需等待.进入北京通信的宽带网站,用户可以在家中享受高质量的视频点播服务。

    2、 独享带宽安全可靠: 与某些网络的共享网络带宽相比,ADSL直接连接到电信宽带网的机房,用户独享带宽。ADSL利用中国网通深入千家万户的电话网络,骨干网采用中国网通遍布全城全国的光纤传输,各节点采用ATM宽带交换机处理交换信息,独享带宽,信息传递快速可靠安全。

    3、 上网打电话互不干扰: ADSL数据信号和电话音频信号以频分复用原理调制于各自频段互不干扰。您上网的同时可以使用电话,避免了拨号上网的烦恼。而且,由于数据传输不通过电话交换机,因此使用ADSL上网不需要缴纳拨号上网的电话费用,为您节省了通信费用。

    4、 安装快捷方便:在现有电话线上安装ADSL,只需在用户端安装一台ADSL MODEM和一只分离器,用户线路不用任何改动,极其方便。

    5  价格实惠
    ADSL业务上网资费构成为基本月租费+信息费,无需支付上网通信费(即电话费)。

     

    ADSL的接入模式

      提供两种用户接入模式:虚拟拨号方式和准专线方式。采用虚拟拨号的用户需要安装PPPOE(宽带通)客户端软件,与MODEM和ISDN的类似拨号程序,输入用户名称和用户密码即可连接到宽带接入门户站点,上网遨游。采用准专线方式的用户使用电信部门分配的固定IP地址,开机即可接入INTERNET。(目前仅提供虚拟拨号方式业务)

     

    DDN概念
      DDN(Digital Data Network)即数字数据网,利用数字信道提供永久性电路,以传输数据信号为主的数字传输网络,其中包括了数据通信、数字通信、数字传输、数字交叉连接、计算机、带宽管理等技术,可以为客户提供专用的数字数据传输通道,为客户建立自己的专用数据网提供条件。

    DDN特点
      (1)面向各类数据客户的公用通信网,连续传输数据信号的透明传输网;
      (2)可支持数据、语音、图像等多种业务;
      (3)同步数据传输,传输速率高,网络时延小,可靠性高;
      (4)具体很强的抗燥声和减小失真的能力,很小的传输比特差错率。

    办理流程  DDN(FR)办理流程
      签定DDN(FR)服务协议->缴纳一次性费用->向北京电报局提交申请及购买基带Modem->开始施工->安装调试->用户在开通纪录表上签字-> 按期缴纳使用费;

     

    FR概念
      帧中继技术是在分组交换技术充分发展,数字与光纤传输线路逐渐代替已有的模拟线路,用户终端日益智能化的条件下诞生并发展起来的。帧中继是一种简单的面向连接的分组电路,是基于开放系统互联模型的数据链路层,此项技术的开发既可以满足局域网互联所需的大容量的传送,也可以满足用户对数据传输时延小的要求。其具有吞吐量大、时延小、适合突发性业务等特点,能充分利用网络资源。

    FR特点

      高效性:帧中继技术是在一条物理通道上采用统计时分复用技术,可提供多条虚通路、虚连接。可支持突发性业务,特别适用于用户互连的需要。

      可靠性:虽然帧中继基于X.25协议并对其进行了简化,无纠错和流量控制,但网内中继电路动态分配带宽,并且在最佳路径上对虚连接进行自动路由和重新路由选择。适用于高速率、低误码、时延小的光纤为基础的网络。
      经济性:网络采用动态按需分配带宽的方式,且价格便宜。
      灵活性:用户接入方式多样,端口类型丰富,速率广泛。
      长远性:在将来ATM成为主要网络技术后,帧中继仍能与ATM相辅相成,成为以ATM为交换技术的骨干网的用户接入层。

    FR办公流程
      
    DDN(FR)办理流程
      签定专线接入合同->缴纳一次性费用->向北京电报局提交申请及购买基带Modem->开始施工->安装调试->用户在开通纪录表上签字-> 按期缴纳使用费;

     

    FDDI接入说明

       随着Internet技术的迅猛发展,通过光纤接入互联网技术已经成熟。光纤接入是指服务器端与用户之间完全以光纤作为传输媒体,主要技术是光波传输技术,是为了满足高速宽带业务以及双向宽带业务的需要。目前首都公共信息平台(CPIP)在光纤接入互联网方面技术先进,服务优质,经验丰富,已经有众多大型公司、商住社区、办公楼宇、宾馆饭店等通过光纤接入CPIP平台。首信公司本着优质高效、价格合理的政策为客户提供服务。

     

     

    June 06

    06年06月06日

    06年06月06日, 千年等一回的日子,衷心祝愿各位博友:
    顺风顺水,天天顺心,事事顺利,天天^_^^_^
    May 30

    Steps taken to cool down real-estate market

    By Zheng Lifei (China Daily)
    Updated: 2006-05-30 06:10

    The cabinet has decided to significantly tighten the rules regarding mortgage down payments and housing transactions, in a bid to cool down the country's over-heated property sector.


    New residential buildings are erected along Maoming Road in Shanghai, which is on the list of five cities that recorded the biggest drop in housing prices last month. [Shanghai Daily]

    According to a statement issued by the State Council yesterday, as of June 1 the minimum down payment for a new apartment larger than 90 square metres will be raised from 20 per cent to 30 per cent.

    The ratio for an apartment smaller than 90 square metres will remain unchanged at 20 per cent, to cater to "the needs of middle- and low-income groups," the statement said.

    In another important move, a transaction tax will be imposed on people attempting to resell their properties within five years of purchase. The current period is two years. The tax rate will stay unchanged at 5.5 per cent of the sale value.

    The move, also effective June 1, is aimed at "curbing speculative and investment-oriented housing demand," according to the statement.

    "The transaction tax will certainly do something to combat investment-oriented housing demand, although it will depend on how effectively the new rules are enforced," said Wang Deyong, a real-estate industry analyst with CITIC Securities.

    "This tax on sales of second-hand houses, together with other measures in the State Council statement, are likely to have an impact on the market, but it won't be dramatic," said Richard Wang, associate director of Consultancy and Research Department with global real-estate advisor DTZ's Beijing office.

    However, for high-income earners the down payment increase may not be a major deterrent.

    "It will have little, if any, impact on my home-buying plan," said Zhao Guocheng, 28, an Internet service company employee in Beijing.

    "If it were raised to 50 per cent, as was rumoured one week ago, then I would have to rethink my purchase plan. Perhaps I would have to work hard for many more years to buy a flat," said Zhao.

    Earlier, in an executive meeting chaired by Premier Wen Jiabao on May 17, the State Council vowed to use a mix of tax, credit and land policies for this purpose.

    The State Administration of Taxation also issued a directive on May 19 reiterating its call on local governments to impose a 20 per cent capital-gain tax on sales of second-hand property, which requires sellers to pay 20 per cent of the profit they make from housing sales as tax.

    Property prices in China's major cities have soared in recent years, raising concerns about an overheated market.

    In the first quarter this year housing prices jumped 15 per cent in Beijing and 35 per cent in Shenzhen, a booming city in Guangdong Province.

    The latest moves, which also cover bank lending, are "the most detailed policies that the government has ever taken towards the housing market," said an executive with a Beijing-based property developer, who refused to be named,

    "It may make life harder for the less competitive and smaller developers, but it will not have much impact on the strong and competitive ones," he added.

    The statement also called for strengthened supervision on land used for housing developments.

    A policy has been issued to require that developers of land slated for development be charged a high "idle land fee" if it remains unused for one year, while rights will be revoked if it remains unused for 2 years.

    The State Council paper also asked local governments to make 70 per cent of its annual land supply available for the development of low-cost housing.

    "The land supply policy may be the most effective way to rein in surging property prices," said DTZ's Wang.

    "The land market should be better regulated. In some places, the land auction floor price offered by local governments is too high, which will inevitably push up prices," he said.

    (China Daily 05/30/2006 page1)

    May 23

    貔貅开光

    貔貅开光的几种说法:

    第一种说法:

      貔貅开光的方法:

      1、选择一个吉日,将貔貅清洗干净。
      2、取半桶井水,再取半桶雨水。
      3、倒入一个事先准备好的容器中,这个容器要清洁干净。
      4、将清洁干净的貔貅放入容器中,浸泡三天。
      5、取出后,用干净的毛巾擦干净。
      6、取一些茶油,涂在貔貅的眼睛上,这叫开光。
      7、貔貅通人性,开光时要只能自己一个人在场,貔貅开光后,第一个看到的是你,就会始终保佑你。


      另一种方法:

      貔貅开光法:把新买的貔貅放在阳台上白天太阳光,夜间月光最容易照射到的位置,摆放16天貔貅便可自然开光,此种方法开光的貔貅吸取日月之精华拥有极强的抗煞和招财能力。


    第二种说法:

      一、貔貅开光唯一的办法就是去庙里请师傅给开光。
      因为貔貅开光不同于财神,麒麟等,貔貅一般不容易开光,财神开光一般烧符,念咒就可以了,但是貔貅要先念经,请神要不然开不了。

      二、貔貅摆放位置:貔貅摆放有三忌。
      1.不要头冲正门(从外面进来的门其他无所谓,但不要冲厕所),因为正门是门神或财神执掌的地方,貔貅无权过问。
      2.不要冲镜子,因为镜子会产生光煞,貔貅忌讳。
      3.不要对着床,这样会对自己不利。

      三、貔貅的供养
      1.香炉里不能放沙子,泥土,要放姜米,珍珠米,黑米。
      2.供奉果品中不能有梨,草莓。其他不忌,酒肉亦可供奉。
      3.女人有月经或者怀孕时严禁给貔貅上香,抚摩(貔貅忌光煞,血煞,胎煞)。
      4.不要经常打扫貔貅,每年只有四次打扫时间2.6/6.2/7.14/9.12都是以农历计算。
      5.不的随意搬动貔貅,不得抚摩貔貅嘴及头部,需要搬动时可先用红绸布包其头部再搬动。

     

    ---

    貔貅挂坠佩带:
    1、用红绳佩带在手腕、颈项上。
    2、用无根水(雨水)和江河水清洗其身。
    3、貔貅最得观音之宠,所以在观音前烧香开光(最好能每月15放到观音前烧香祈福)。
    4、貔貅不能摸其嘴,因为用嘴叼钱;不可摸其眼,因为用眼寻宝。

    ---

    请回家一个貔貅后,先要摸一摸它的耳朵,但千万不能遮着它的眼睛,然后顺着它的翅膀摸下去,一直摸到屁股处,再把手一抓,赶忙放到口袋里,这样财气就到你的口袋里了。 应该朝外面,这样才能吸灵气啊!

    May 20

    名词解释:容积率

      所谓“容积率”,是指一个小区的总建筑面积与用地面积的比率。对于发展商来说,容积率决定地价成本在房屋中占的比例,而对于住户来说,容积率直接涉及到居住的舒适度。绿化率也是如此。绿化率较高,容积率较低,建筑密度一般也就较低,发展商可用于回收资金的面积就越少,而住户就越舒服。这两个比率决定了这个项目是从人的居住需求角度,还是从纯粹赚钱的角度来设计一个社区。一个良好的居住小区,高层住宅容积率应不超过5,多层住宅应不超过3,绿化率应不低于30%。但由于受土地成本的限制,并不是所有项目都能做得到。

    May 18

    中国的GPS:“北斗”卫星导航定位系统

     
    作者:沙龙   原载于《中国科技信息》
     

        2003年5月25日零时34分,我国在西昌卫星发射中心用“长征三号甲”运载火箭,成功地将第三颗“北斗一号”导航定位卫星送入太空。前两颗“北斗一号”卫星分别于2000年10月31日和12月21日发射升空,运行至今导航定位系统工作稳定,状态良好。这次发射的是导航定位系统的备份星。它与前两颗“北斗一号”工作星组成了完整的卫星导航定位系统,确保全天候、全天时提供卫星导航信息。这标志着我国成为继美国全球卫星定位系统(GPS)和前苏联的全球导航卫星系统(GLONASS)后,在世界上第三个建立了完善的卫星导航系统的国家,该系统的建立对我国国民国防和经济建设将起到积极作用。我国早在60年代末就开展了卫星导航系统的研制工作,但由于多种原因而天折。在自行研制“子午仪”定位设备方面起步较晚,以致后来使用的大量设备中,基本上依赖进口。70年代后期以来,国内开展了探讨适合国情的卫星导航定位系统的体制研究。先后提出过单星、双星、三星和3-5星的区域性系统方案,以及多星的全球系统的设想,并考虑到导航定位与通信等综合运用问题,但是由于种种原因,这些方案和设想都没能够得到实现。1982年7月由美国三位科学家提出并于12月定名的GEOSTAR系统,就是这种两颗卫星的主动式卫星定位系统。他们在实施的过程中,由于有更优越的GPS卫星导航系统的兴起并且发展相当迅速,使GEOSTAR系统不得不在1991年9月撤走资金,导致正在实施中的GEOSTA及系统宣告失败。而我国的“北斗一号”卫星导航系统正是80年代提出的“双星快速定位系统”的发展计划。北斗导航系统的方案于1983年提出,突出持点是构成系统的空间卫星数目少、用户终端设备简单、一切复杂性均集中于地面中心处理站。“北斗一号”卫星定位系统是利用地球同步卫星为用户提供快速定位、简短数字报文通信和授时服务的一种全天候、区域性的卫星定位系统。系统的主要功能是:

        1、定时:快速确定用户所在地的地理位置,向用户及主管部门提供导航信息。

        2、通讯:用户与用户、用户与中心控制系统间均可实现双向简短数字报文通信。

        3、授时:中心控制系统定时播发授时信息,为定时用户提供时延修正值。

        “北斗一号”卫星定位系统工作原理“北斗一号”卫星定位系统由两颗地球静止卫星(800E和1400E)、一颗在轨备份卫星(110.50E)、中心控制系统、标校系统和各类用户机等部分组成。系统的工作过程是:首先由中心控制系统向卫星I和卫星II同时发送询问信号,径卫星转发器项服务区内的用户广播。用户响应其中一颗卫星的询问信号,并同时向两颗卫星发送响应信号,径卫星转发回中心控制系统。中心控制系统接收并解调用户发来的信号,然后根据用的申请服务内容进行相应的数据处理。 对定位申请,中心控制系统测出两个时间延迟:即从中心控制系统发出询问信号,经某一颗卫星转发到达用户,用户发出定位响应信号,经同一颗卫星转发回中心控制系统的延迟;和从中心控制发出询问信号,经上述同一卫星到达用户,用户发出响应信号,经另一颗卫星转发回中心控制系统的延迟。由于中心控制系统和两颗卫星的位置均是已知的,因此由上面两个延迟量可以算出用户到第一颗卫星的距离,以及用户到两颗卫星距离之和,从而知道用户处于一个以第一颗卫星为球心的一个球面,和以两颗卫星为焦点的椭球面之间的交线上。另外中心控制系统从存储在计算机内的数字化地形图查寻到用户高程值,又可知道用户出于某一与地球基准椭球面平行的椭球面上。从而中心控制系统可最终计算出用户所在点的三维坐标,这个坐标经加密由出站信号发送给用户。

        “北斗一号”的覆盖范围是北纬5°一55°,东经70°一140°之间的心脏地区,上打下小,最宽处在北纬35°左右。其定位精度为水平精度100米(1σ),设立标校站之后为20米(类似差分状态)。工作频率:2491.75MHz。系统能容纳的用户数为每小时540000户。

         “北斗一号”卫星导航系统与GPS系统比较

         1、覆盖范围:北斗导航系统是覆盖我国本土的区域导航系统。覆盖范围东经约70°一140°,北纬5°一55°。GPS是覆盖全球的全天候导航系统。能够确保地球上任何地点、任何时间能同时观测到6-9颗卫星(实际上最多能观测到11颖)。

        2、卫星数量和轨道特性:北斗导航系统是在地球赤道平面上设置2颗地球同步卫星颗卫星的赤道角距约60°。GPS是在6个轨道平面上设置24颗卫星,轨道赤道倾角55°,轨道面赤道角距60°。航卫星为准同步轨道,绕地球一周11小时58分。

        3、定位原理:北斗导航系统是主动式双向测距二维导航。地面中心控制系统解算,供用户三维定位数据。GPS是被动式伪码单向测距三维导航。由用户设备独立解算自己三维定位数据。“北斗一号”的这种工作原理带来两个方面的问题,一是用户定位的同时失去了无线电隐蔽性,这在军事上相当不利,另一方面由于设备必须包含发射机,因此在体积、重量上、价格和功耗方面处于不利的地位。

        4、定位精度:北斗导航系统三维定位精度约几十米,授时精度约100ns。GPS三维定位精度P码目前己由16m提高到6m,C/A码目前己由25-100m提高到12m,授时精度日前约20ns。

        5、用户容量:北斗导航系统由于是主动双向测距的询问--应答系统,用户设备与地球同步卫星之间不仅要接收地面中心控制系统的询问信号,还要求用户设备向同步卫星发射应答信号,这样,系统的用户容量取决于用户允许的信道阻塞率、询问信号速率和用户的响应频率。因此,北斗导航系统的用户设备容量是有限的。GPS是单向测距系统,用户设备只要接收导航卫星发出的导航电文即可进行测距定位,因此GPS的用户设备容量是无限的。

        6、生存能力:和所有导航定位卫星系统一样,“北斗一号”基于中心控制系统和卫星的工作,但是“北斗一号”对中心控制系统的依赖性明显要大很多,因为定位解算在那里而不是由用户设备完成的。为了弥补这种系统易损性,GPS正在发展星际横向数据链技术,使万一主控站被毁后GPS卫星可以独立运行。而“北斗一号”系统从原理上排除了这种可能性,一旦中心控制系统受损,系统就不能继续工作了。

        7、实时性:“北斗一号”用户的定位申请要送回中心控制系统,中心控制系统解算出用户的三维位置数据之后再发回用户,其间要经过地球静止卫星走一个来回,再加上卫星转发,中心控制系统的处理,时间延迟就更长了,因此对于高速运动体,就加大了定位的误差。此外,“北斗一号”卫星导航系统也有一些自身的特点,其具备的短信通讯功能就是GPS所不具备的。

         综上所述,北斗导航系统具有卫星数量少、投资小、用户设备简单价廉、能实现一定区域的导航定位、通讯等多用途,可满足当前我国陆、海、空运输导航定位的需求。缺点是不能覆盖两极地区,赤道附近定位精度差,只能二维主动式定位,且需提供用户高程数据,不能满足高动态和保密的军事用户要求,用户数量受一定限制。但最重要的是,“北斗一号”导航系统是我国独立自主建立的卫星导航系统,它的研制成功标志着我国打破了美、俄在此领域的垄断地位,解决了中国自主卫星导航系统的有无问题。它是一个成功的、实用的、投资很少的初步起步系统。此外,该系统并不排斥国内民用市场对GPS的广泛使用。相反,在此基础上还将建立中国的GPS广域差分系统。可以使受SA干扰的GPS民用码接收机的定位精度由百米级修正到数米级,可以更好的促进GPS在民间的利用。当然,我们也需要认识到,随着我军高技术武器的不断发展,对导航定位的信息支持要求越来越高。北斗导航系统仅是我国近期满足四化建设需要的自主简易导航系统,因此,我们必须在发展“北斗一号”的基础上,借鉴国外GPS、GLONASS的成功经验,开发我国二代卫星导航系统,我们有理由相信,在不久的将来,具备先进性、适用性、军民两用、抗干扰性、抗继毁性等特征的,适合我国的国情的“北斗二号”将会展现在大家面前,更加完善的我国卫星导航系统也必将建立。

    May 16

    《论语·泰伯篇》《民可使由之,不可使知之》析疑

    作者:公翼
     
          在《论语·泰伯篇》中有一句令人十分费解的话,那就是“子曰:民可使由之,不可使知之。”几多年来使人迷惑至深,至今犹未能解惑。而这句话却又成了封建统治者推行愚民政策的绝妙借口。这究竟是怎样一回事呢?难道说这会是儒家的学说吗?不见得吧!绝对不可能,它与孔子的政治主张是如此的不一致,与整部《论语》的精神是如此的不合拍。那究竟为什么呢?我说问题就出在朱熹身上,由于朱熹不懂古文的结构,连如何分段都不会,只要看到“子曰”二字,就不由自主地习惯成自然地对原文作了分割,结果造成断章取义的错误,再加上解释上的错误,因而造成今天这种结局。今天我们要澄清这个问题,先要恢复整段全文的面貌,然后才能作出符合逻辑的解释。整段全文是这样的。“子曰:兴于诗,立于礼,成于乐。子曰:民可使由之,不可使知之。”我们从这段全文的内容来分析,发现这正是孔子与学生们谈论乐理,谈论音乐的作用与效果的记述。从记述中可以看出,这正是《乐经》的精华所在。所以才被孔子的学生记述在《论语》中的。这后二句话,正是表明了音乐所能起到效果的述说。可惜的是《乐经》已经失传,要不,拿来一对照,也就不会发生被朱熹先生断章取义的事了。
          解释这段文字,先要知道制作乐曲的步序,这就是先作词,有了词再去谱曲,看来三千年前的古人也不例外。所以孔子说了“兴于诗”。“诗”就是歌词的意思。“兴于诗”就是说制作乐曲先要从作词开始。“立于礼”,“礼”就是政治制度。“立于礼”意思就是说:   要立足于政治制度的需要。用今天的话来说,就是文艺创作要服从于政治的需要。“成于乐”,意思就是说摆正了文艺创作的政治立场,创作出来的乐曲,才能受到人民的欢迎,才会有所成就,才会有成绩,才能传之于世,才能久而不衰,才能起到感化人民的作用。这种感化人民于无形,使人在不知不觉中改造了自己的行为,这就是音乐的作用与效果。所以孔子说了:“民可使由之,不可使知之。”这就是说“人民是可以通过音乐去诱导他人生向往的方向”。“由”就是诱导的意思。但他自己不会知道,“你也不用去告诉他知道这是怎么回事”。这就是音乐给人带来潜移默化的神奇效果。这正是儒家学说的精华。呜呼!朱熹又何知其中之奥妙哉!
          附带要说明白的,音乐,不是所有的音乐都能起到感化作用的,只有健康、舒美、温馨、柔和的音乐,才能熏陶人们的情操,才能感化人的灵魂。孔子一向反对粗犷的音乐,因为它能使人发狂。也一向反对靡靡之音,因为它能使人意志消沉。孔子之所以要纂辑《诗经》,正因为在全国成千上万首歌词中,鱼龙混杂,良莠不齐,所以孔子只选择了既富有地方色彩,又富含人情味,既不致使人淫佚,又不致使人颓废的作品三百零五首,使之传诸于世。只有选择好的歌词,才能配上好的乐曲。孔子说了《关雎》乐而不淫,哀而不伤。这即孔子选择的标准吧!可惜《乐经》失传,我们已经无缘听到这种雅乐了。
    May 06

    ISO 13406-2 Guidelines for Pixel Defects

    LCD displays are made up of a set number of pixels and each pixel is made from 3 sub-pixels; one Red, one Blue and one Green.  Every sub-pixel is addressed by its own transistor and so the manufacture of a glass substrate is very complex.  Due to the nature of the manufacturing process, occasional defects can occur.  Pixel defects or failures cannot be fixed or repaired and can happen at any stage in the LCD’s life.

    To regulate the acceptability of defects and to protect the end user, ISO have created a standard for manufacturers to follow.  ISO 13406-2 recommends how many defaults are acceptable in a display before it should be replaced, within the terms & conditions of warranty. 
    All reputable manufacturers conform to and support the ISO 13406-2 standard.

    The table below shows the allowable number of malfunctioning pixels that are acceptable, depending on the native resolution of the LCD and allowing for 2 malfunctioning pixels per million pixels.
    Native resolution No. of pixels No. of million pixels Acceptable defects
    1024 x 768 786,432 0.8 2
    1280 x 1024 1,310,720 1.3 3
    1600 x 1200 1,920,200 1.9 4
    2048 x 1536 3,145,728 3.1 6

    The table below shows the allowable number of malfunctioning sub-pixels that are acceptable, depending on the native resolution of the LCD and allowing for 5 malfunctioning sub-pixels per million pixels.

    Native resolution No. of pixels No. of million pixels Acceptable defects
    1024 x768 786,432  0.8 4
    1280 x 1024 1,310,720 1.3 7
    1600 x 1200 1,920,200 1.9 10
    2048 x 1536 3,145,728 3.1 16

    The table below shows the allowable number of malfunctioning sub-pixels that are acceptable within a 5 x 5 block of pixels, depending on the native resolution and allowing for 2 malfunctioning sub-pixels within a 5 x 5 block, per million pixels.

    Native resolution No. of pixels No. of million pixels Acceptable defects
    1024 x 768 786,432 0.8 2
    1280 x 1024 1,310,720 1.3 3
    1600 x 1200 1,920,200 1.9 4
    2048 x 1536 3,145,728 3.1 6

    The above is relevant to Class II LCD panels.
     

    依照2001年修订完成的ISO(国际标准组织)13406-2标准,这个标准定义了有关LCD屏幕影像质量与人体工学规范。这个规范包含了亮度、对比、反射、亮度与色彩的一致性、闪烁、特性分析与屏幕坏点等。

    在屏幕坏点方面,ISO 13406-2共定义了4个等级的质量。Class 1是最高等级,(不允许有任何坏点)Class 4是最差等级,一般不会有厂商使用此两种规格。以目前的制造技术,几乎所有厂商都是引用介于Class 2Class 3之间的规格当作产品故障保固的标准。

    谈到屏幕的坏点,必须先了解屏幕的的构成单元:PIXEL(Picture element,译做屏幕的象素)。以15吋屏幕的面积为例,共有1024*768 (786,432)个象素。每一个象素则分别由红(R;red)、绿(Ggreen)、蓝(BBlue)三原色光点(dot;或称次象素,subpixel)所构成。依照光的原理,三原色光点全亮则构成白光,反之,三原色光点全不亮则是黑色。三原色光点不同程度的明亮则形成不同的颜色。每一个原色光点目前制造技术是以八位去控制其变化,因此每一个原色光点可以有二的八次方(256)种变化,则每一个象素的三个次象素总共可以让一个屏幕象素表现出256*256*256=16,777,216,即一般所谓的16.7百万色彩。因此不难理解ISO国际标准组织制定标准的逻辑所在。

    当一个屏幕象素的三原色光点丧失其256种亮度变化时,即会对于该象素的表现造成影响(或称为瑕疵),屏幕象素瑕疵共有亮点、暗点、或色点三种。

    亮点: RGB全部三个原色光点永远只能固定表现某一种亮度。
    暗点: RGB全部三个原色光点永远不亮。
    色点: 一至二个原色光点部份程度的亮或不亮。因为另外一至二个原色光点仍旧可以呈现256(两个原色光点无作用)256*256(一个原色光点无作用)种变化,因此色点仍是会有不同色彩的表现。相较于亮点或暗点的三个原色光点全部停摆,色点发生的机率远超过亮点或暗点的机率,这也是何以营销说明上只强调保证无亮点(不保证无色点或暗点)

    其实不少品牌在国外就是按这个标准执行,只是在国内对此标准则装聋作哑。我想Motorola就是其中的一个。

    April 28

    权限系统概要

    作者: 代文龙        转自网络

    -----------------------------------------------

    前言:
      权限往往是一个极其复杂的问题,但也可简单表述为这样的逻辑表达式:判断“Who对What(Which)进行How的操作”的逻辑表达式是否为真。针对不同的应用,需要根据项目的实际情况和具体架构,在维护性、灵活性、完整性等N多个方案之间比较权衡,选择符合的方案。

    目标:
      直观,因为系统最终会由最终用户来维护,权限分配的直观和容易理解,显得比较重要,系统不辞劳苦的实现了组的继承,除了功能的必须,更主要的就是因为它足够直观。
      简单,包括概念数量上的简单和意义上的简单还有功能上的简单。想用一个权限系统解决所有的权限问题是不现实的。设计中将常常变化的“定制”特点比较强的部分判断为业务逻辑,而将常常相同的“通用”特点比较强的部分判断为权限逻辑就是基于这样的思路。
      扩展,采用可继承在扩展上的困难。的Group概念在支持权限以组方式定义的同时有效避免了重定义时

    现状:
      对于在企业环境中的访问控制方法,一般有三种:
      1.自主型访问控制方法。目前在我国的大多数的信息系统中的访问控制模块中基本是借助于自主型访问控制方法中的访问控制列表(ACLs)。
      2.强制型访问控制方法。用于多层次安全级别的军事应用。
      3.基于角色的访问控制方法(RBAC)。是目前公认的解决大型企业的统一资源访问控制的有效方法。其显著的两大特征是:1.减小授权管理的复杂性,降低管理开销。2.灵活地支持企业的安全策略,并对企业的变化有很大的伸缩性。

    名词:
      粗粒度:表示类别级,即仅考虑对象的类别(the type of object),不考虑对象的某个特定实例。比如,用户管理中,创建、删除,对所有的用户都一视同仁,并不区分操作的具体对象实例。
      细粒度:表示实例级,即需要考虑具体对象的实例(the instance of object),当然,细粒度是在考虑粗粒度的对象类别之后才再考虑特定实例。比如,合同管理中,列表、删除,需要区分该合同实例是否为当前用户所创建。

    原则:
      权限逻辑配合业务逻辑。即权限系统以为业务逻辑提供服务为目标。相当多细粒度的权限问题因其极其独特而不具通用意义,它们也能被理解为是“业务逻辑”的一部分。比如,要求:“合同资源只能被它的创建者删除,与创建者同组的用户可以修改,所有的用户能够浏览”。这既可以认为是一个细粒度的权限问题,也可以认为是一个业务逻辑问题。在这里它是业务逻辑问题,在整个权限系统的架构设计之中不予过多考虑。当然,权限系统的架构也必须要能支持这样的控制判断。或者说,系统提供足够多但不是完全的控制能力。即,设计原则归结为:“系统只提供粗粒度的权限,细粒度的权限被认为是业务逻辑的职责”。
      需要再次强调的是,这里表述的权限系统仅是一个“不完全”的权限系统,即,它不提供所有关于权限的问题的解决方法。它提供一个基础,并解决那些具有“共性”的(或者说粗粒度的)部分。在这个基础之上,根据“业务逻辑”的独特权限需求,编码实现剩余部分(或者说细粒度的)部分,才算完整。回到权限的问题公式,通用的设计仅解决了Who+What+How 的问题,其他的权限问题留给业务逻辑解决。

    概念:
      Who:权限的拥用者或主体(Principal、User、Group、Role、Actor等等)
      What:权限针对的对象或资源(Resource、Class)。
      How:具体的权限(Privilege, 正向授权与负向授权)。
      Role:是角色,拥有一定数量的权限。
      Operator:操作。表明对What的How 操作。

    说明:
      User:与 Role 相关,用户仅仅是纯粹的用户,权限是被分离出去了的。User是不能与 Privilege 直接相关的,User 要拥有对某种资源的权限,必须通过Role去关联。解决 Who 的问题。
      Resource:就是系统的资源,比如部门新闻,文档等各种可以被提供给用户访问的对象。资源可以反向包含自身,即树状结构,每一个资源节点可以与若干指定权限类别相关可定义是否将其权限应用于子节点。
      Privilege:是Resource Related的权限。就是指,这个权限是绑定在特定的资源实例上的。比如说部门新闻的发布权限,叫做"部门新闻发布权限"。这就表明,该Privilege是一个发布权限,而且是针对部门新闻这种资源的一种发布权限。Privilege是由Creator在做开发时就确定的。权限,包括系统定义权限和用户自定义权限用户自定义权限之间可以指定排斥和包含关系(如:读取,修改,管理三个权限,管理 权限 包含 前两种权限)。Privilege 如"删除" 是一个抽象的名词,当它不与任何具体的 Object 或 Resource 绑定在一起时是没有任何意义的。拿新闻发布来说,发布是一种权限,但是只说发布它是毫无意义的。因为不知道发布可以操作的对象是什么。只有当发布与新闻结合在一起时,才会产生真正的 Privilege。这就是 Privilege Instance。权限系统根据需求的不同可以延伸生很多不同的版本。
      Role:是粗粒度和细粒度(业务逻辑)的接口,一个基于粗粒度控制的权限框架软件,对外的接口应该是Role,具体业务实现可以直接继承或拓展丰富Role的内容,Role不是如同User或Group的具体实体,它是接口概念,抽象的通称。
      Group:用户组,权限分配的单位与载体。权限不考虑分配给特定的用户。组可以包括组(以实现权限的继承)。组可以包含用户,组内用户继承组的权限。Group要实现继承。即在创建时必须要指定该Group的Parent是什么Group。在粗粒度控制上,可以认为,只要某用户直接或者间接的属于某个Group那么它就具备这个Group的所有操作许可。细粒度控制上,在业务逻辑的判断中,User仅应关注其直接属于的Group,用来判断是否“同组” 。Group是可继承的,对于一个分级的权限实现,某个Group通过“继承”就已经直接获得了其父Group所拥有的所有“权限集合”,对这个Group而言,需要与权限建立直接关联的,仅是它比起其父Group需要“扩展”的那部分权限。子组继承父组的所有权限,规则来得更简单,同时意味着管理更容易。为了更进一步实现权限的继承,最直接的就是在Group上引入“父子关系”。
      User与Group是多对多的关系。即一个User可以属于多个Group之中,一个Group可以包括多个User。子Group与父Group是多对一的关系。Operator某种意义上类似于Resource + Privilege概念,但这里的Resource仅包括Resource Type不表示Resource Instance。Group 可以直接映射组织结构,Role 可以直接映射组织结构中的业务角色,比较直观,而且也足够灵活。Role对系统的贡献实质上就是提供了一个比较粗颗粒的分配单位。
      Group与Operator是多对多的关系。各概念的关系图示如下:

    解释:
      Operator的定义包括了Resource Type和Method概念。即,What和How的概念。之所以将What和How绑定在一起作为一个Operator概念而不是分开建模再建立关联,这是因为很多的How对于某What才有意义。比如,发布操作对新闻对象才有意义,对用户对象则没有意义。
      How本身的意义也有所不同,具体来说,对于每一个What可以定义N种操作。比如,对于合同这类对象,可以定义创建操作、提交操作、检查冲突操作等。可以认为,How概念对应于每一个商业方法。其中,与具体用户身份相关的操作既可以定义在操作的业务逻辑之中,也可以定义在操作级别。比如,创建者的浏览视图与普通用户的浏览视图要求内容不同。既可以在外部定义两个操作方法,也可以在一个操作方法的内部根据具体逻辑进行处理。具体应用哪一种方式应依据实际情况进行处理。
      这样的架构,应能在易于理解和管理的情况下,满足绝大部分粗粒度权限控制的功能需要。但是除了粗粒度权限,系统中必然还会包括无数对具体Instance的细粒度权限。这些问题,被留给业务逻辑来解决,这样的考虑基于以下两点:
      一方面,细粒度的权限判断必须要在资源上建模权限分配的支持信息才可能得以实现。比如,如果要求创建者和普通用户看到不同的信息内容,那么,资源本身应该有其创建者的信息。另一方面,细粒度的权限常常具有相当大的业务逻辑相关性。对不同的业务逻辑,常常意味着完全不同的权限判定原则和策略。相比之下,粗粒度的权限更具通用性,将其实现为一个架构,更有重用价值;而将细粒度的权限判断实现为一个架构级别的东西就显得繁琐,而且不是那么的有必要,用定制的代码来实现就更简洁,更灵活。
      所以细粒度控制应该在底层解决,Resource在实例化的时候,必需指定Owner和GroupPrivilege在对Resource进行操作时也必然会确定约束类型:究竟是OwnerOK还是GroupOK还是AllOK。Group应和Role严格分离User和Group是多对多的关系,Group只用于对用户分类,不包含任何Role的意义;Role只授予User,而不是Group。如果用户需要还没有的多种Privilege的组合,必须新增Role。Privilege必须能够访问Resource,同时带User参数,这样权限控制就完备了。

    思想:
      权限系统的核心由以下三部分构成:1.创造权限,2.分配权限,3.使用权限,然后,系统各部分的主要参与者对照如下:1.创造权限 - Creator创造,2.分配权限 - Administrator 分配,3.使用权限 - User:
      1. Creator 创造 Privilege, Creator 在设计和实现系统时会划分,一个子系统或称为模块,应该有哪些权限。这里完成的是 Privilege 与 Resource 的对象声明,并没有真正将 Privilege 与具体Resource 实例联系在一起,形成Operator。
      2. Administrator 指定 Privilege 与 Resource Instance 的关联。在这一步, 权限真正与资源实例联系到了一起, 产生了Operator(Privilege Instance)。Administrator利用Operator这个基本元素,来创造他理想中的权限模型。如,创建角色,创建用户组,给用户组分配用户,将用户组与角色关联等等...这些操作都是由 Administrator 来完成的。
      3. User 使用 Administrator 分配给的权限去使用各个子系统。Administrator 是用户,在他的心目中有一个比较适合他管理和维护的权限模型。于是,程序员只要回答一个问题,就是什么权限可以访问什么资源,也就是前面说的 Operator。程序员提供 Operator 就意味着给系统穿上了盔甲。Administrator 就可以按照他的意愿来建立他所希望的权限框架可以自行增加,删除,管理Resource和Privilege之间关系。可以自行设定用户User和角色Role的对应关系。(如果将 Creator看作是 Basic 的发明者, Administrator 就是 Basic 的使用者,他可以做一些脚本式的编程) Operator是这个系统中最关键的部分,它是一个纽带,一个系在Programmer,Administrator,User之间的纽带。

    用一个功能模块来举例子。
      一.建立角色功能并做分配:
        1.如果现在要做一个员工管理的模块(即Resources),这个模块有三个功能,分别是:增加,修改,删除。给这三个功能各自分配一个ID,这个ID叫做功能代号:
          Emp_addEmp,Emp_deleteEmp,Emp_updateEmp。
        2.建立一个角色(Role),把上面的功能代码加到这个角色拥有的权限中,并保存到数据库中。角色包括系统管理员,测试人员等。
        3.建立一个员工的账号,并把一种或几种角色赋给这个员工。比如说这个员工既可以是公司管理人员,也可以是测试人员等。这样他登录到系统中将会只看到他拥有权限的那些模块。
      二.把身份信息加到Session中。
        登录时,先到数据库中查找是否存在这个员工,如果存在,再根据员工的sn查找员工的权限信息,把员工所有的权限信息都入到一个Hashmap中,比如就把上面的Emp_addEmp等放到这个Hashmap中。然后把Hashmap保存在一个UserInfoBean中。最后把这个UserInfoBean放到Session中,这样在整个程序的运行过程中,系统随时都可以取得这个用户的身份信息。
      三.根据用户的权限做出不同的显示。
        可以对比当前员工的权限和给这个菜单分配的“功能ID”判断当前用户是否有打开这个菜单的权限。例如:如果保存员工权限的Hashmap中没有这三个ID的任何一个,那这个菜单就不会显示,如果员工的Hashmap中有任何一个ID,那这个菜单都会显示。
        对于一个新闻系统(Resouce),假设它有这样的功能(Privilege):查看,发布,删除,修改;假设对于删除,有"新闻系统管理者只能删除一月前发布的,而超级管理员可删除所有的这样的限制,这属于业务逻辑(Business logic),而不属于用户权限范围。也就是说权限负责有没有删除的Permission,至于能删除哪些内容应该根据UserRole or UserGroup来决定(当然给UserRole or UserGroup分配权限时就应该包含上面两条业务逻辑)。
        一个用户可以拥有多种角色,但同一时刻用户只能用一种角色进入系统。角色的划分方法可以根据实际情况划分,按部门或机构进行划分的,至于角色拥有多少权限,这就看系统管理员赋给他多少的权限了。用户—角色—权限的关键是角色。用户登录时是以用户和角色两种属性进行登录的(因为一个用户可以拥有多种角色,但同一时刻只能扮演一种角色),根据角色得到用户的权限,登录后进行初始化。这其中的技巧是同一时刻某一用户只能用一种角色进行登录。
        针对不同的“角色”动态的建立不同的组,每个项目建立一个单独的Group,对于新的项目,建立新的 Group 即可。在权限判断部分,应在商业方法上予以控制。比如:不同用户的“操作能力”是不同的(粗粒度的控制应能满足要求),不同用户的“可视区域”是不同的(体现在对被操作的对象的权限数据,是否允许当前用户访问,这需要对业务数据建模的时候考虑权限控制需要)。

    扩展性:
      有了用户/权限管理的基本框架,Who(User/Group)的概念是不会经常需要扩展的。变化的可能是系统中引入新的 What (新的Resource类型)或者新的How(新的操作方式)。那在三个基本概念中,仅在Permission上进行扩展是不够的。这样的设计中Permission实质上解决了How 的问题,即表示了“怎样”的操作。那么这个“怎样”是在哪一个层次上的定义呢?将Permission定义在“商业方法”级别比较合适。比如,发布、购买、取消。每一个商业方法可以意味着用户进行的一个“动作”。定义在商业逻辑的层次上,一方面保证了数据访问代码的“纯洁性”,另一方面在功能上也是“足够”的。也就是说,对更低层次,能自由的访问数据,对更高层次,也能比较精细的控制权限。
      确定了Permission定义的合适层次,更进一步,能够发现Permission实际上还隐含了What的概念。也就是说,对于What的How操作才会是一个完整的Operator。比如,“发布”操作,隐含了“信息”的“发布”概念,而对于“商品”而言发布操作是没有意义的。同样的,“购买”操作,隐含了“商品”的“购买”概念。这里的绑定还体现在大量通用的同名的操作上,比如,需要区分“商品的删除”与“信息的删除”这两个同名为“删除”的不同操作。
      提供权限系统的扩展能力是在Operator (Resource + Permission)的概念上进行扩展。Proxy 模式是一个非常合适的实现方式。实现大致如下:在业务逻辑层(EJB Session Facade [Stateful SessionBean]中),取得该商业方法的Methodname,再根据Classname和 Methodname 检索Operator 数据,然后依据这个Operator信息和Stateful中保存的User信息判断当前用户是否具备该方法的操作权限。
      应用在 EJB 模式下,可以定义一个很明确的 Business层次,而一个Business 可能意味着不同的视图,当多个视图都对应于一个业务逻辑的时候,比如,Swing Client以及 Jsp Client 访问的是同一个 EJB 实现的 Business。在 Business 层上应用权限较能提供集中的控制能力。实际上,如果权限系统提供了查询能力,那么会发现,在视图层次已经可以不去理解权限,它只需要根据查询结果控制界面就可以了。

    灵活性:
      Group和Role,只是一种辅助实现的手段,不是必需的。如果系统的Role很多,逐个授权违背了“简单,方便”的目的,那就引入Group,将权限相同的Role组成一个Group进行集中授权。Role也一样,是某一类Operator的集合,是为了简化针对多个Operator的操作。
      Role把具体的用户和组从权限中解放出来。一个用户可以承担不同的角色,从而实现授权的灵活性。当然,Group也可以实现类似的功能。但实际业务中,Group划分多以行政组织结构或业务功能划分;如果为了权限管理强行将一个用户加入不同的组,会导致管理的复杂性。
      Domain的应用。为了授权更灵活,可以将Where或者Scope抽象出来,称之为Domain,真正的授权是在Domain的范围内进行,具体的Resource将分属于不同的Domain。比如:一个新闻机构有国内与国外两大分支,两大分支内又都有不同的资源(体育类、生活类、时事政治类)。假如所有国内新闻的权限规则都是一样的,所有国外新闻的权限规则也相同。则可以建立两个域,分别授权,然后只要将各类新闻与不同的域关联,受域上的权限控制,从而使之简化。
      权限系统还应该考虑将功能性的授权与资源性的授权分开。很多系统都只有对系统中的数据(资源)的维护有权限控制,但没有对系统功能的权限控制。
      权限系统最好是可以分层管理而不是集中管理。大多客户希望不同的部门能且仅能管理其部门内部的事务,而不是什么都需要一个集中的Administrator或Administrators组来管理。虽然你可以将不同部门的人都加入Administrators组,但他们的权限过大,可以管理整个系统资源而不是该部门资源。
      正向授权与负向授权:正向授权在开始时假定主体没有任何权限,然后根据需要授予权限,适合于权限要求严格的系统。负向授权在开始时假定主体有所有权限,然后将某些特殊权限收回。
      权限计算策略:系统中User,Group,Role都可以授权,权限可以有正负向之分,在计算用户的净权限时定义一套策略。
      系统中应该有一个集中管理权限的AccessService,负责权限的维护(业务管理员、安全管理模块)与使用(最终用户、各功能模块),该AccessService在实现时要同时考虑一般权限与特殊权限。虽然在具体实现上可以有很多,比如用Proxy模式,但应该使这些Proxy依赖于AccessService。各模块功能中调用AccessService来检查是否有相应的权限。所以说,权限管理不是安全管理模块自己一个人的事情,而是与系统各功能模块都有关系。每个功能模块的开发人员都应该熟悉安全管理模块,当然,也要从业务上熟悉本模块的安全规则。

    技术实现:
      1.表单式认证,这是常用的,但用户到达一个不被授权访问的资源时,Web容器就发出一个html页面,要求输入用户名和密码。
      2.一个基于Servlet Sign in/Sign out来集中处理所有的Request,缺点是必须由应用程序自己来处理。
      3.用Filter防止用户访问一些未被授权的资源,Filter会截取所有Request/Response,
      然后放置一个验证通过的标识在用户的Session中,然后Filter每次依靠这个标识来决定是否放行Response。

    这个模式分为:
      Gatekeeper :采取Filter或统一Servlet的方式。
      Authenticator: 在Web中使用JAAS自己来实现。

    用户资格存储LDAP或数据库:
      1. Gatekeeper拦截检查每个到达受保护的资源。首先检查这个用户是否有已经创建好的Login Session,如果没有,Gatekeeper 检查是否有一个全局的和Authenticator相关的session?
      2. 如果没有全局的session,这个用户被导向到Authenticator的Sign-on 页面,要求提供用户名和密码。
      3. Authenticator接受用户名和密码,通过用户的资格系统验证用户。
      4. 如果验证成功,Authenticator将创建一个全局Login session,并且导向Gatekeeper来为这个用户在他的web应用中创建一个Login Session。
      5. Authenticator和Gatekeepers联合分享Cookie,或者使用Tokens在Query字符里。

    -------------------------------------------

    这篇文章写得很不错。可惜之前没有看到这篇文章,否则应该对此前设计权限管理系统时具有很大的指导作用。

    April 26

    如何验证身份证号是否正确

    本文非原创,转贴。

    我们要验证身份证号是否正确,就得先了解身份证号的含意。

    身份证号都代表什么意思?

    1、号码的结构
    公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。

    2、地址码(前六位数)
    表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。

    3、出生日期码(第七位至十四位)
    表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。

    4、顺序码(第十五位至十七位)
    表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。

    5、校验码(第十八位数)
    (1)十七位数字本体码加权求和公式
    S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和
    Ai:表示第i位置上的身份证号码数字值
    Wi:表示第i位置上的加权因子
    Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
    (2)计算模
    Y = mod(S, 11)
    (3)通过模得到对应的校验码
    Y: 0 1 2 3 4 5 6 7 8 9 10
    校验码: 1 0 X 9 8 7 6 5 4 3 2

    所以我们就可以大致写一个函数来校验是否正确了。