精华内容
下载资源
问答
  • 报文结构HTTP报文的结构分为请求和响应两种,...请求报文的起始行说明要做什么,结构为方法 + 请求URL + 协议版本,中间用空格做分隔:响应报头的起始行说明发生了什么,结构为协议版本 + 状态码 + 描述文本中间...

    56bd217e1b343ef1d909d06d47dba5ed.png

    报文结构

    HTTP报文的结构分为请求和响应两种,请求报文封装用户操作产生的动作,告知服务器应采取什么行为,响应报文来告知客户端请求的结果。请求报文格式:

    8dd11b69d64d1e240e7e7a1af81cc2ba.png

    响应报文格式:

    17e0b36d101f5b2e90fbeb5a6bb696bf.png

    报文的起始行表明了报文的开始,请求和响应各自的起始行的格式也不相同。请求报文的起始行说明要做什么,结构为方法 + 请求URL + 协议版本,中间用空格做分隔:

    f66d01d54f9723e1079cd0e74dca7087.png

    响应报头的起始行说明发生了什么,结构为协议版本 + 状态码 + 描述文本,中间用空格做分隔:

    aa6ad36358cb4ac8e4232f3375af3adb.png

    方法与状态码

    方法来告诉服务端请求报文要做的事情,状态码来通知客户端服务端依据请求报文完成动作之后的大致结果。常见的HTTP方法如下:

    1.| 方法 | 含义 | 有无主体 | | ------- | ---------------------------------------------- | -------- | | GET | 从服务端获取资源 | 无 | | HEAD | 只获取资源头部 | 无 | | POST | 向服务端发送数据 | 有 | | PUT | 将客户端发送的数据存到服务端,应用场景多为修改 | 有 | | OPTIONS | 对服务端进行预检,例如服务端支持哪些方法 | 无 | | DELETE | 从服务端删除资源 | 无 |

    2. 请求完成时,响应报文中会有一个状态码,用来表示此次请求的状态,是成功了还是失败了,或者时需要重定向。状态码的范围从100到599, 其中有部分是已经定义的。不同的范围表示的含义也不同:

    3. | 范围 | 已定义范围 | 含义 | | ------- | ---------------------------------------------- | ---------- | | 100~199 | 100~101 | 信息提示 | | 200~299 | 200~206 | 成功 | | 300~399 | 300~305 | 重定向 | | 400~499 | 400~415 | 客户端错误 | | 500~599 | 500~505 | 服务端错误 |

    首部

    首部是请求和响应报文中的一些信息,形式为键值对,每对键值结尾是CRLF换行符,它决定了请求或者响应报文的属性,比如Content-Type表明了请求主体的数据类型,Date说明了请求的创建时间。客户端与服务端通过首部来协商具体行为。可以根据请求、响应、结构等,将首部分为五种。

    · 请求首部:是放在请求报文中的首部,它被用来告诉服务端一些信息。

    · 响应首部:为客户端提供一些可能用到的信息。

    · 通用首部:请求与响应报文都包含的首部,例如Date首部

    · 实体首部:对于报文实体主体部分的描述,比如Content-Type,表明其数据类型。

    · 扩展首部:开发者自己添加的首部字段,用来满足定制化需求。

    实体

    2b9847269d887448f5e88096e4441e55.png

    实体部分是可选的,它被用来运送请求或者响应的数据,实体由实体首部 + 实体主体组成,实体首部对实体主体做描述。HTTP/1.1定义了以下的基本实体首部字段:

    · Content-Type: 实体主体中的数据类型。

    · Content-Length: 实体主体的长度或者大小。

    · Content-Language: 和传输的数据最匹配的语言。

    · Content-Encoding: 来标识服务端编码时所用的编码方式。

    · Content-Location: 要返回的数据的地址。

    · Content-Range: 如果是部分实体,用来标记它是实体的哪个部分。

    · Content-MD5: 实体主体内容的校验和。

    · Last-Modified: 所传输内容在服务器上创建或者最后修改的日期时间。

    · Expires: 实体数据试下的日期时间。

    · Allow: 所请求资源允许的请求方法。

    · ETag: 资源的特定版本的标识符。可以让缓存更高效,并节省带宽。

    · Cache-Control: 控制缓存机制的指令。

    以上是HTTP报文包含的主要结构,当请求报文到达服务器时,服务器会对报文中的内容解析出来,根据方法、资源路径、首部、和主体来处理请求,然后通过对请求资源的访问结果,来构建响应,回送给客户端。

    传输层-TCP

    HTTP连接是建立在TCP连接的基础之上的,TCP提供可靠的数据连接。当要传输一个HTTP报文时,报文数据会以流的形式通过一条已经打开的TCP连接按顺序传输,TCP会将收到的数据分成小块,每块是一个TCP分组。

    由于数据是分成小块发送的,所以完整可靠的数据传输主要体现在:分组是否完整、分组顺序是否正常、分组是否损坏、分组数据是否重复。这些可以通过TCP的检验和、序列号、确认应答、重发控制、连接管理和窗口机制来控制。

    TCP是传输控制协议,传输控制主要依赖首部包含的6个标志,它们控制报文的传输状态,以及发送端和接收端应对数据采取的动作。当它们的值为1时,标志对应的各自功能才允许被执行,比如当URG为1时,报文首部的紧急指针部分才有效。

    · URG 紧急指针

    · ACK 确认序号有效

    · PSH 接收方应该尽快将这个报文段交给应用层。

    · RST 重建连接

    · SYN 同步序号用来发起一个连接

    · FIN 发端完成发送任务

    11f500b3cb26bd709d246d7610cce515.png

    源端口和目的端口:标识发送方和接收方的端口号,一个TCP连接通过4个值确认:源IP、源端口、目的IP、目的端口,其中源IP和目的IP包含在IP分组内。

    首部长度:表示TCP首部的字节长度,也能标记出从多少个字节开始,才是需要传输的数据。

    TCP段序号:本段报文发送的数据第一个字节的序号,每段报文中的数据的每个字节都有序号,第一个字节的序号从0开始,依次加1,加到2的32次方减1后再次从0开始。

    TCP段确认序号:当首部标志ACK为1时,确认序号有效。TCP段被接收端接收后,会回送给发送端一个确认号,为上次接受的最后一个字节序号加1。

    检验和:由发送端计算,接收端验证,如果接收方检测到检验和不正确,表明该TCP段可能有损坏,会被丢弃,同时接收端向回送一个重复的确认号(与最近的一次正确的报文传输的确认号重复),表明接收到的TCP段是错误的,并告知自己希望收到的序号。这时发送端需要立即重传出错的TCP段。

    紧急指针:当首部标志URG为1时,紧急指针有效,表示发送端向接收端要发送紧急数据。紧急指针是一个正偏移量,它和TCP段序号相加,计算出紧急数据的最后一个字节的序号。比如接收方接收到数据,从序号为1000的字节开始读取,紧急指针为1000,那么紧急数据就是序号从1000到2000之间的字节。这些数据由接收方决定如何处理。

    窗口尺寸:决定了TCP一次成块数据流的吞吐量。需要注意的是,它表示的是发送一方的允许对方发送的数据量,比如发送方首部中的窗口大小为1000,就表示发送方最多可以接受对方发来的1000个字节的数据量。这与发送方的数据缓存空间有关,会影响TCP的性能。

    首部标志PSH:如果需要告诉接收方将数据立即全部提交给接收进程,发送方需要将PSH置为1,这里的数据是和PSH一起传送的数据以及之前接收到的全部数据。如果接收方收到了PSH为1的标志,需要立即将数据提交给接收进程,不用再等待有没有其他数据进来。

    复位标志RST:当RST为1时,表示连接出现了异常情况,接收方将终止连接,通知应用层重新建立连接。

    同步序号SYN:用来建立连接,涉及到TCP的三次握手。

    1. 开始建立连接时,客户端向服务器发送一个TCP分组,分组首部的SYN为1,并携带一个初始序号,表明这是一个连接请求。

    2. 如果服务器接受了连接,会向客户端发送一个TCP分组,分组中会包含SYN和ACK,都为1,同时包含一个确认序号,值为来自客户端的初始序号 + 1,表示连接已经被接受。

    3. 客户端收到上一步发来的分组后,会再向服务器发送一段确认报文分组,ACK为1,会再次携带确认序号,值是第二步来自客户端的确认序号+ 1。服务端收到确认信息后,进入已经连接的状态。

    在第三步的确认分组中,是可以携带要发送的数据的。

    连接终止标志FIN:用来关闭连接,当一端完成数据发送任务后会发送一个FIN标志来终止连接,但因为TCP在两个方向(C-S,S-C)上会有数据传递,每个方向有各自的发送FIN & 确认关闭流程,所以会有四次交互,也称为四次挥手。

    1. 如果客户端应用层的数据发送完毕,会导致客户端的TCP报文发送一个FIN,告知服务器准备关闭数据传送。

    2. 服务器接收到这个标志后,它发回一个ACK,确认序号为收到的序号加1,同时TCP还要向应用程序发一个文件结束符。

    3. 此时服务器关闭这个方向的连接,导致它的TCP也会发送一个FIN。

    4. 客户端接收到之后发回一个确认ACK,序号为收到的序号 + 1,连接完全关闭。

    TCP段序号与确认序号保证了数据的顺序,检验和确保数据的完整性,紧急指针保证紧急数据可被及时处理。另外,TCP还有一些超时重传、 拥塞避免、慢启动的机制,都可以保证分组数据按照顺序完整的传到目标端。

    网络层-IP

    如果说TCP分组是包装货物的集装箱,那么IP就是运送集装箱的卡车。IP协议提供了两个节点之间的连接,保证将TCP数据尽可能快地从源端送到终端,但却不能保证传输的可靠性。

    IP层会将上层传过来的TCP分组封装,带上自己的首部,再进行选路、是否分片以及重组的工作,最终到达目的地,这个过程中,IP首部起了重要的作用,下面让我们看一下首部的结构。

    IP

    fb90b25fed47e7bbd771ba985f43600e.png

    版本:表示当前IP协议的版本,目前版本号是4,还有一种是6,也就是IPV4和IPV6,如果发送和接收这两端的版本不一致,那么当前IP数据报会被丢弃。

    首部长度:整个首部的长度,最长为60字节。

    服务类型(TOS):用来区分服务的类型,但其实IP层在工作的时候一直没有实际使用过,现有的TOS只有4bit的子字段,和1bit的未用位。未用位必须置为0。TOS的4个bit中只能将一个置成1,用来表示当前服务类型。4bit对应的4个服务类型分别为:最小时延、最大吞吐量、最高可靠性和最小费用。

    路由选择

    因为IP首部只包含了目的IP地址,并不体现完整的路径,当向外发送数据时,IP层会根据目的IP在本机路由表中的查询结果来做出选路决策,数据报会逐跳地被运送到目的地,这里的每一跳,就是一次路由选择。

    IP层既可配置成路由器,也可以配置成主机。当配置成路由功能时,可以对数据报进行转发,配置成主机时,如果目的IP不是本机IP,数据报会被丢弃。

    具有路由功能的IP层在当目标IP不是本机地址的时候是根据什么判断转发到哪一站呢?要理解这个问题,需要先明白路由表的结构,以下是IP层维护的路由表,(windows系统可以在控制台输入netstat -r来查看路由表)

    | Destination | Gateway | Flags| Refcnt| Use | Interface| | ------------------ | --------------- | -----|------ |---- | ---------| | 140.252.13.65 | 140.252.13.35 | UGH | 0 | 0 | emd0 | | 127.0.0.1 | 127.0.0.1 | UH | 1 | 0 | lo0 | | default | 140.252.13.33 | UG | 0 | 0 | emd0 | | 140.252.13.32 | 140.252.13.34 | U | 4 |25043| emd0 |

    (路由表数据来源于《TCP/IP详解卷一:协议》)

    · Destination(目的IP):表示IP数据报最终要到达或者经过的网络地址或者主机地址。

    · Gateway(下一跳地址):当前维护路由表设备的相邻路由器的地址

    · Flags(标志):表示当前这一条路由记录的属性,具体用五个不同的标志来表示:

    U:该路由可以使用

    G:如果有这个标志,表示是下一跳是一个网关,如果没有,表示下一跳是和当前设备在一个网段,也就是可以直接把数据报发过去

    H: 下一跳是一个主机还是一个网络,有这个标志,表示主机,没有,则表示下一跳的路由是一个网络

    D:该路由是由重定向报文创建的

    M:该路由已被重定向报文修改

    Interface:当前路由项的物理端口

    每收到一个数据报时候,IP层就会根据目的IP在路由表里查询,根据查询状态会导向三种结果:

    1. 找到了与目的IP完全匹配的路由项,将报文发给该路由项的下一站路由(Gateway)或者网络接口(Interface)

    2.找到了与目的IP的网络号匹配的路由项,将报文发给该路由项的下一站路由(Gateway)或者网络接口(Interface)

    3. 前两者都没有找到,就看路由表里有没有默认路由项(default),有的话发给它指定的下一站路由(Gateway)

    要是上边三个都没有结果,那么数据报就不能被发送。IP数据报就是这样一跳一跳地被送往目的主机的,但数据报有固有的长度,一旦超出了目的主机的MTU,就会被分片。

    最后

    一个网络请求从源端一层层封装,再到终端一层层拆分,最后的所有过程基本梳理清楚,文章只是简单梳理了一下大概流程,并且只以HTTP报文通过TCP协议经过IP传送这一过程为例,实际还有很多概念没有覆盖,比如链路层的尾部封装、 IP的动态选路、逆地址解析协议RARP、UDP协议相关的概念,建议大家可以阅读下面列出的参考资料,相信会有更多收获。

    展开全文
  • 因为人们手写的(或者程序生成的)HTML都直接被排版引擎解析的,中间并没有语法格式或者编码方式的变换。换句话说你写的代码就是直接被执行的代码,所以看上去“公开的”。 JavaScript也类似,和C++/Java不同的...

    HTML是一种标记语言,以文本形式存储,在浏览器里经由排版引擎解析后渲染成网页。因为人们手写的(或者程序生成的)HTML都是直接被排版引擎解析的,中间并没有语法格式或者编码方式的变换。换句话说你写的代码就是直接被执行的代码,所以看上去是“公开的”。

    JavaScript也类似,和C++/Java不同的是,作为脚本语言,解释器是直接读取源代码解释执行的,所以看起来也是“公开的”。

    当然和HTML不同的是,现代JavaScript语言已经变得非常复杂,为了节约网络传输的时间,JavaScript代码部署到服务器上之前会被“编译”一下,比如在保持逻辑等价的前提下,把变量名替换成更短的,去掉换行符,多余的空格,注释和一些没有用的代码。这时候你在浏览器里看到的代码已经不是最人写的那个样子的。不借助其他工具的话,很难读懂,这种情况下就不再算“公开的”了。

    展开全文
  • 这个开源系统的目的集众人智慧,将文本挖掘、文本分类前沿领域效果非常好的算法实现并有效组织,形成一条完整系统将文本挖掘尤其是文本分类的过程自动化。该系统提供了Python和Java两种版本。 主要特征 该系统在...
  • 1.Web Service属于RPC的一种,说它效率不高应该与其它RPC手段相比而言的吧 Web Service最大的特点一般情况下采用XML序列化数据进行传输,而XML是文本格式,其效率比特化的二进制肯定要低的。 另外,在数据类型较...
    1.Web Service属于RPC的一种,说它效率不高应该是与其它RPC手段相比而言的吧 Web Service最大的特点是一般情况下采用XML序列化数据进行传输,而XML是文本格式,其效率比特化的二进制肯定要低的。 另外,在数据类型较少的情况下,XML的解析时间可能要多于按约定的读取时间
    2.c/s,你直接就可以连接数据库,但ws,你就要通过ws的机器去访问数据库,有了中间一环,怎么能快的起来。
    3.和传输应该没有关系,webservice因为要跨平台,要兼容,中间的机制导致效率低这个和C++比C效率低下的道理差不多
    4.在传输效率上稍逊一筹,综合表现还是很不错的。如果系统涉及大量二进制数据传输,webservice就不是很适合了。
    5.XML序列化本来就会是数据膨胀. XML的强项在乎数据描述.

    转载于:https://www.cnblogs.com/cuihongyu3503319/archive/2007/02/08/644760.html

    展开全文
  • 设计模式-小王搞设计

    2019-10-24 15:16:17
    客户要求:导出数据可能存储成不同的文件格式,例如:文本格式、数据库备份形式、Excel格式、Xml格式等等,并且,不管什么格式,导出数据文件都分成三个部分,分别文件头、文件体和文件尾,在文件头部分,需要描述...

    小王正在设计一个导出数据的应用框架。客户要求:导出数据可能存储成不同的文件格式,例如:文本格式、数据库备份形式、Excel格式、Xml格式等等,并且,不管什么格式,导出数据文件都分成三个部分,分别是文件头、文件体和文件尾,在文件头部分,需要描述如下信息:分公司或门市点编号、导出数据的日期,对于文本格式,中间用逗号分隔,在文件体部分,需要描述如下信息:表名称、然后分条描述数据,对于文本格式,表名称单独占一行,数据描述一行算一条数据,字段间用逗号分隔,在文件尾部分,需要描述如下信息:输出人。请你选择恰当的设计模式帮助小王进行设计。

    /**
     * 描述输出到文件头的内容的对象
     */
    public class ExportHeaderModel {
        /**
         * 分公司或门市点编号
         */
        private String depId;
        /**
         * 导出数据的日期
         */
        private String exportDate;
        public String getDepId() {
           return depId;
        }
        public void setDepId(String depId) {
           this.depId = depId;
        }
        public String getExportDate() {
           return exportDate;
        }
        public void setExportDate(String exportDate) {
           this.exportDate = exportDate;
        }
    }
    
    /**
     * 描述输出数据的对象
     */
    public class ExportDataModel {
        /**
         * 产品编号
         */
        private String productId;
        /**
         * 销售价格
         */
        private double price;
        /**
         * 销售数量
         */
        private double amount;
       
        public String getProductId() {
           return productId;
        }
        public void setProductId(String productId) {
           this.productId = productId;
        }
        public double getPrice() {
           return price;
        }
        public void setPrice(double price) {
           this.price = price;
        }
        public double getAmount() {
           return amount;
        }
        public void setAmount(double amount) {
           this.amount = amount;
        }
    }
    
    /**
     * 描述输出到文件尾的内容的对象
     */
    public class ExportFooterModel {
        /**
         * 输出人
         */
        private String exportUser;
        public String getExportUser() {
           return exportUser;
        }
        public void setExportUser(String exportUser) {
           this.exportUser = exportUser;
        }
    }
    
    /**
     * 生成器接口,定义创建一个输出文件对象所需的各个部件的操作
     */
    public interface Builder {
        /**
         * 构建输出文件的Header部分
         * @param ehm 文件头的内容
         */
        public void buildHeader(ExportHeaderModel ehm);
        /**
         * 构建输出文件的Body部分
         * @param mapData 要输出的数据的内容
         */
        public void buildBody(Map<String,Collection<ExportDataModel>> mapData);
        /**
         * 构建输出文件的Footer部分
         * @param efm 文件尾的内容
         */
        public void buildFooter(ExportFooterModel efm);
    }
    
    /**
     * 实现导出数据到文本文件的的生成器对象
     */
    public class TxtBuilder implements Builder {
        /**
         * 用来记录构建的文件的内容,相当于产品
         */
        private StringBuffer buffer = new StringBuffer();
     
        public void buildBody(Map<String, Collection<ExportDataModel>> mapData) {
           for(String tblName : mapData.keySet()){
               //先拼接表名称
               buffer.append(tblName+"\n");
               //然后循环拼接具体数据
               for(ExportDataModel edm : mapData.get(tblName)){
                  buffer.append(edm.getProductId()+","+edm.getPrice()+","+edm.getAmount()+"\n");
               }
           }
        }
        public void buildFooter(ExportFooterModel efm) {
           buffer.append(efm.getExportUser());
        }
        public void buildHeader(ExportHeaderModel ehm) {
           buffer.append(ehm.getDepId()+","+ehm.getExportDate()+"\n");
        }  
        public StringBuffer getResult(){
           return buffer;
        }  
    }
    
    /**
     * 实现导出数据到XML文件的的生成器对象
     */
    public class XmlBuilder implements Builder {
        /**
         * 用来记录构建的文件的内容,相当于产品
         */
        private StringBuffer buffer = new StringBuffer();
     
        public void buildBody(Map<String, Collection<ExportDataModel>> mapData){
           buffer.append("  <Body>\n");
           for(String tblName : mapData.keySet()){
               //先拼接表名称
               buffer.append("    <Datas TableName=\""+tblName+"\">\n");
               //然后循环拼接具体数据
               for(ExportDataModel edm : mapData.get(tblName)){
                  buffer.append("      <Data>\n");
                  buffer.append("        <ProductId>"+edm.getProductId()+"</ProductId>\n");
                  buffer.append("        <Price>"+edm.getPrice()+"</Price>\n");
                  buffer.append("        <Amount>"+edm.getAmount()+"</Amount>\n");
                  buffer.append("      </Data>\n");
               }
               buffer.append("    </Datas>\n");
           }
           buffer.append("  </Body>\n");
        }
        public void buildFooter(ExportFooterModel efm) {
           buffer.append("  <Footer>\n");
           buffer.append("    <ExportUser>"+efm.getExportUser()+"</ExportUser>\n");
           buffer.append("  </Footer>\n");
           buffer.append("</Report>\n");
        }
        public void buildHeader(ExportHeaderModel ehm) {
           buffer.append("<?xml version='1.0' encoding='gb2312'?>\n");
           buffer.append("<Report>\n");
           buffer.append("  <Header>\n");
           buffer.append("    <DepId>"+ehm.getDepId()+"</DepId>\n");
           buffer.append("    <ExportDate>"+ehm.getExportDate()+"</ExportDate>\n");
           buffer.append("  </Header>\n");
        }
        public StringBuffer getResult(){
           return buffer;
        }
    }
    
    /**
     * 指导者,指导使用生成器的接口来构建输出的文件的对象
     */
    public class Director {
        /**
         * 持有当前需要使用的生成器对象
         */
        private Builder builder;
        /**
         * 构造方法,传入生成器对象
         * @param builder 生成器对象
         */
        public Director(Builder builder) {
           this.builder = builder;
        }
     
        /**
         * 指导生成器构建最终的输出的文件的对象
         * @param ehm 文件头的内容
         * @param mapData 数据的内容
         * @param efm 文件尾的内容
         */
        public void construct(ExportHeaderModel ehm,Map<String,Collection<ExportDataModel>> mapData,
    ExportFooterModel efm) {
           //1:先构建Header
           builder.buildHeader(ehm);
           //2:然后构建Body
           builder.buildBody(mapData);
           //3:然后构建Footer
           builder.buildFooter(efm);
        }
    }
    
    public class Client {
        public static void main(String[] args) {
           //准备测试数据
           ExportHeaderModel ehm = new ExportHeaderModel();
           ehm.setDepId("一分公司");
           ehm.setExportDate("2010-05-18");
          
           Map<String,Collection<ExportDataModel>> mapData = new HashMap<String,Collection<ExportDataModel>>();
           Collection<ExportDataModel> col =new ArrayList<ExportDataModel>();
          
           ExportDataModel edm1 = new ExportDataModel();
           edm1.setProductId("产品001号");
           edm1.setPrice(100);
           edm1.setAmount(80);
           ExportDataModel edm2 = new ExportDataModel();
           edm2.setProductId("产品002号");
           edm2.setPrice(99);
           edm2.setAmount(55);     
           //把数据组装起来
           col.add(edm1);
           col.add(edm2);      
           mapData.put("销售记录表", col);
          
           ExportFooterModel efm = new ExportFooterModel();
           efm.setExportUser("张三");
          
           //测试输出到文本文件
           TxtBuilder txtBuilder = new TxtBuilder();
           //创建指导者对象
           Director director = new Director(txtBuilder);
           director.construct(ehm, mapData, efm);
           //把要输出的内容输出到控制台看看
           System.out.println("输出到文本文件的内容:\n"+txtBuilder.getResult());
           //测试输出到xml文件
           XmlBuilder xmlBuilder = new XmlBuilder();
           Director director2 = new Director(xmlBuilder);
           director2.construct(ehm, mapData, efm);
           //把要输出的内容输出到控制台看看
           System.out.println("输出到XML文件的内容:\n"+xmlBuilder.getResult());
        }
    }
    2. 单例模式的本质是控制实例数目。
    /** 
    * 简单演示如何扩展单例模式,控制实例数目为3个  
    */  
    public class OneExtend {  
        /** 
        * 定义一个缺省的key值的前缀 
        */  
        private final static String DEFAULT_PREKEY = "Cache";  
        /** 
        * 缓存实例的容器 
        */  
        private static Map<String,OneExtend> map = new HashMap<String,OneExtend>();  
        /** 
        * 用来记录当前正在使用第几个实例,到了控制的最大数目,就返回从1开始 
        */  
        private static int num = 1;  
        /** 
        * 定义控制实例的最大数目 
        */  
        private final static int NUM_MAX = 3;   
        private OneExtend(){}  
        public static OneExtend getInstance(){  
            String key = DEFAULT_PREKEY+num;  
            //缓存的体现,通过控制缓存的数据多少来控制实例数目  
            OneExtend oneExtend = map.get(key);  
            if(oneExtend==null){  
                oneExtend = new OneExtend();  
                map.put(key, oneExtend);  
            }  
            //把当前实例的序号加1  
            num++;  
            if(num > NUM_MAX){  
                //如果实例的序号已经达到最大数目了,那就重复从1开始获取  
                num = 1;  
            }  
            return oneExtend;         
        }  
          
        public static void main(String[] args) {  
            //测试是否能满足功能要求  
            OneExtend t1 = getInstance ();  
            OneExtend t2 = getInstance ();  
            OneExtend t3 = getInstance ();  
            OneExtend t4 = getInstance ();  
            OneExtend t5 = getInstance ();  
            OneExtend t6 = getInstance ();  
              
            System.out.println("t1=="+t1);  
            System.out.println("t2=="+t2);  
            System.out.println("t3=="+t3);  
            System.out.println("t4=="+t4);  
            System.out.println("t5=="+t5);  
            System.out.println("t6=="+t6);  
        }  
    }  
    


     

    展开全文
  • 设计模式作业3

    2019-10-03 22:32:48
    客户要求:导出数据可能存储成不同的文件格式,例如:文本格式、数据库备份形式、Excel格式、Xml格式等等,并且,不管什么格式,导出数据文件都分成三个部分,分别文件头、文件体和文件尾,在文件头部分,需要描述...
  • 并且,不管什么格式,导出数据文件都分成三个部分,分别文件头、文件体和文件尾 在文件头部分,需要描述如下信息:分公司或门市点编号、导出数据的日期,对于文本格式中间用逗号分隔 在文件体部...
  • 一.什么是http http(Hypertext transfer protocol)超文本传输协议,通过浏览器和服务器进行数据交互,进行超...从输入url到加载页面中间发生了什么了 1、输入URL,http协议已经规定了URL的格式,通过http协议中的...
  • Markdown一种标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式。简单的理解类似于C语言一样的编程语言,通过一定的编译工具解释为:引言,图片,标题和正文等格式。 Mar...
  • 什么是莎莎? Salsa一个开放源代码库,可呈现iOS视图并将其导出到Sketch文件中。... 有两个步骤,我们可以定义自己的中间文件格式,该格式比完整的草图文件格式更容易使用。 这意味着,如果我们想将该工具扩
  • HTML入门 文章目录一、HTML是什么?二、入门实例1.新建html文档2.html常用标签三、属性总结 一、HTML是什么? HTML全称:Hyper Text Markup ...中文名:超文本标记语言 ...网页编码格式,一般为UTF-8 中间内容就是这个h
  • Markdown : 一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式。 简单地说就是通过一些符号使你的文章排版更加清晰、简洁。 我第一次接触它在有道云笔记上,...
  • 简单网管介绍

    千次阅读 2006-07-03 16:38:00
     网管是什么?网管有两个对象,一个是对网络计算机软件的管理,另一个是对硬件的管理。a. 被管理的设备b.代理Agent 用于屏蔽设备差异c.协议 一般用简单网管协议snmpd.管理端2.网管的体系结构最下层是设备,中间是...
  • 报文多多个系统之间需要通信时,在此中间承担装载数据、传输数据的功能。在多个系统中报文的格式互不相同,但是其承载的数据一样的。 三、什么是http? HTTP文本传输协议的简写,...
  • 1.1 什么是Windows Sockets 1.2 Windows Sockets的发展历史 1.3 Windows Sockets的优势 1.3.1 Windows Sockets一个开放的标准 1.3.2 Windows Sockets提供源代码可移植性 1.3.3 Windows Sockets支持动态链接 1.3.4 ...
  • 1. ajax是什么? asynchronous javascript and xml:异步的js和xml 它能使用js访问服务器,而且是异步访问 服务器给客户端的响应一般是整个页面,一个html完整页面!但在ajax中因为是局部刷新,那么服务器就不用再...
  • Html 标签初知

    2019-02-19 12:09:00
     超文本标记语言(外国语简称:HTML)标记标签通常被称为HTML标签,HTML标签HTML语言中最基本的单位,HTML标签HTML(标准通用标记语言下的一个应用)最重要的组成部分。两个括号有开头结尾中间有内容,则为标签...
  • Servlet基础(执行原理)

    2020-06-06 07:23:40
    Servlet是什么 java Servlet是运行在服务器上的程序,它是HTTP客户端/Web浏览器与HTTP服务器/应用程序之间的中间层。 使用Servlet可以搜集网页表单的用户输入,还可以呈现数据库等源的记录。 Servlet任务 -读取...
  • JSON的使用

    2018-06-10 17:50:14
    JSON是什么 JSON的全称是”JavaScript Object Notation”,意思是JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式 JSON有哪两种结构 JSON有两种表示结构,对象和数组 对象结构以{...
  • JSON

    2018-06-11 16:09:22
    JSON是什么JSON的全称是”JavaScript Object Notation”,意思是JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式。JSON有哪两种结构JSON有两种表示结构,对象和数组。对象结构以{开始,以}...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 121
精华内容 48
关键字:

中间格式文本是什么