-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.xml
More file actions
277 lines (277 loc) · 121 KB
/
search.xml
File metadata and controls
277 lines (277 loc) · 121 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[计算机网络--传输层]]></title>
<url>%2F2019%2F10%2F16%2F%E7%BD%91%E7%BB%9C%2F%E3%80%90%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E3%80%91%2F%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C-%E4%BC%A0%E8%BE%93%E5%B1%82%2F</url>
<content type="text"><![CDATA[> 网络层只把分组发送到目的主机,但是真正通信的并不是主机而是主机中的进程。传输层提供了进程间的逻辑通信,传输层向高层用户屏蔽了下面网络层的核心细节,使应用程序看起来像是在两个传输层实体之间有一条端到端的逻辑通信信道。UDP 和 TCP 的特点用户数据报协议 UDP(User Datagram Protocol)是无连接的,尽最大可能交付,没有拥塞控制,面向报文(对于应用程序传下来的报文不合并也不拆分,只是添加 UDP 首部),支持一对一、一对多、多对一和多对多的交互通信。传输控制协议 TCP(Transmission Control Protocol)是面向连接的,提供可靠交付,有流量控制,拥塞控制,提供全双工通信,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块),每一条 TCP 连接只能是点对点的(一对一)。UDP 首部格式 首部字段只有 8 个字节,包括源端口、目的端口、长度、检验和。12 字节的伪首部是为了计算检验和临时添加的。TCP 首部格式 序号 :用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。确认号 :期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。数据偏移 :指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度。确认 ACK :当 ACK=1 时确认号字段有效,否则无效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置 1。同步 SYN :在连接建立时用来同步序号。当 SYN=1,ACK=0 时表示这是一个连接请求报文段。若对方同意建立连接,则响应报文中 SYN=1,ACK=1。终止 FIN :用来释放一个连接,当 FIN=1 时,表示此报文段的发送方的数据已发送完毕,并要求释放连接。窗口 :窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。TCP 的三次握手 假设 A 为客户端,B 为服务器端。首先 B 处于 LISTEN(监听)状态,等待客户的连接请求。A 向 B 发送连接请求报文,SYN=1,ACK=0,选择一个初始的序号 x。B 收到连接请求报文,如果同意建立连接,则向 A 发送连接确认报文,SYN=1,ACK=1,确认号为 x+1,同时也选择一个初始的序号 y。A 收到 B 的连接确认报文后,还要向 B 发出确认,确认号为 y+1,序号为 x+1。B 收到 A 的确认后,连接建立。三次握手的原因第三次握手是为了防止失效的连接请求到达服务器,让服务器错误打开连接。客户端发送的连接请求如果在网络中滞留,那么就会隔很长一段时间才能收到服务器端发回的连接确认。客户端等待一个超时重传时间之后,就会重新请求连接。但是这个滞留的连接请求最后还是会到达服务器,如果不进行三次握手,那么服务器就会打开两个连接。如果有第三次握手,客户端会忽略服务器之后发送的对滞留连接请求的连接确认,不进行第三次握手,因此就不会再次打开连接。TCP 的四次挥手 以下描述不讨论序号和确认号,因为序号和确认号的规则比较简单。并且不讨论 ACK,因为 ACK 在连接建立之后都为 1。A 发送连接释放报文,FIN=1。B 收到之后发出确认,此时 TCP 属于半关闭状态,B 能向 A 发送数据但是 A 不能向 B 发送数据。当 B 不再需要连接时,发送连接释放报文,FIN=1。A 收到后发出确认,进入 TIME-WAIT 状态,等待 2 MSL(最大报文存活时间)后释放连接。B 收到 A 的确认后释放连接。四次挥手的原因客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。TIME_WAIT客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:确保最后一个确认报文能够到达。如果 B 没收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。TCP 可靠传输TCP 使用超时重传来实现可靠传输:如果一个已经发送的报文段在超时时间内没有收到确认,那么就重传这个报文段。一个报文段从发送再到接收到确认所经过的时间称为往返时间 RTT,加权平均往返时间 RTTs 计算如下: 其中,0 ≤ a < 1,RTTs 随着 a 的增加更容易受到 RTT 的影响。超时时间 RTO 应该略大于 RTTs,TCP 使用的超时时间计算如下: 其中 RTTd 为偏差的加权平均值。TCP 滑动窗口窗口是缓存的一部分,用来暂时存放字节流。发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小。发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口。接收窗口只会对窗口内最后一个按序到达的字节进行确认,例如接收窗口已经收到的字节为 {31, 34, 35},其中 {31} 按序到达,而 {34, 35} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收。 TCP 流量控制流量控制是为了控制发送方发送速率,保证接收方来得及接收。接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。TCP 拥塞控制如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。 TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量,注意拥塞窗口与发送方窗口的区别:拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。为了便于讨论,做如下假设:接收方有足够大的接收缓存,因此不会发生流量控制;虽然 TCP 的窗口基于字节,但是这里设窗口的大小单位为报文段。 1. 慢开始与拥塞避免发送的最初执行慢开始,令 cwnd = 1,发送方只能发送 1 个报文段;当收到确认后,将 cwnd 加倍,因此之后发送方能够发送的报文段数量为:2、4、8 …注意到慢开始每个轮次都将 cwnd 加倍,这样会让 cwnd 增长速度非常快,从而使得发送方发送的速度增长速度过快,网络拥塞的可能性也就更高。设置一个慢开始门限 ssthresh,当 cwnd >= ssthresh 时,进入拥塞避免,每个轮次只将 cwnd 加 1。如果出现了超时,则令 ssthresh = cwnd / 2,然后重新执行慢开始。2. 快重传与快恢复在接收方,要求每次接收到报文段都应该对最后一个已收到的有序报文段进行确认。例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。在发送方,如果收到三个重复确认,那么可以知道下一个报文段丢失,此时执行快重传,立即重传下一个报文段。例如收到三个 M2,则 M3 丢失,立即重传 M3。在这种情况下,只是丢失个别报文段,而不是网络拥塞。因此执行快恢复,令 ssthresh = cwnd / 2 ,cwnd = ssthresh,注意到此时直接进入拥塞避免。慢开始和快恢复的快慢指的是 cwnd 的设定值,而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1,而快恢复 cwnd 设定为 ssthresh。]]></content>
<categories>
<category>网络</category>
<category>【计算机网络】</category>
</categories>
<tags>
<tag>网络</tag>
</tags>
</entry>
<entry>
<title><![CDATA[计算机网络--应用层]]></title>
<url>%2F2019%2F10%2F16%2F%E7%BD%91%E7%BB%9C%2F%E3%80%90%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E3%80%91%2F%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C-%E5%BA%94%E7%94%A8%E5%B1%82%2F</url>
<content type="text"><![CDATA[域名系统DNS 是一个分布式数据库,提供了主机名和 IP 地址之间相互转换的服务。这里的分布式数据库是指,每个站点只保留它自己的那部分数据。域名具有层次结构,从上到下依次为:根域名、顶级域名、二级域名。 DNS 可以使用 UDP 或者 TCP 进行传输,使用的端口号都为 53。大多数情况下 DNS 使用 UDP 进行传输,这就要求域名解析器和域名服务器都必须自己处理超时和重传从而保证可靠性。在两种情况下会使用 TCP 进行传输:如果返回的响应超过的 512 字节(UDP 最大只支持 512 字节的数据)。区域传送(区域传送是主域名服务器向辅助域名服务器传送变化的那部分数据)。文件传送协议FTP 使用 TCP 进行连接,它需要两个连接来传送一个文件:控制连接:服务器打开端口号 21 等待客户端的连接,客户端主动建立连接后,使用这个连接将客户端的命令传送给服务器,并传回服务器的应答。数据连接:用来传送一个文件数据。根据数据连接是否是服务器端主动建立,FTP 有主动和被动两种模式:主动模式:服务器端主动建立数据连接,其中服务器端的端口号为 20,客户端的端口号随机,但是必须大于 1024,因为 0~1023 是熟知端口号。 被动模式:客户端主动建立数据连接,其中客户端的端口号由客户端自己指定,服务器端的端口号随机。 主动模式要求客户端开放端口号给服务器端,需要去配置客户端的防火墙。被动模式只需要服务器端开放端口号即可,无需客户端配置防火墙。但是被动模式会导致服务器端的安全性减弱,因为开放了过多的端口号。动态主机配置协议DHCP (Dynamic Host Configuration Protocol) 提供了即插即用的连网方式,用户不再需要手动配置 IP 地址等信息。DHCP 配置的内容不仅是 IP 地址,还包括子网掩码、网关 IP 地址。DHCP 工作过程如下:客户端发送 Discover 报文,该报文的目的地址为 255.255.255.255:67,源地址为 0.0.0.0:68,被放入 UDP 中,该报文被广播到同一个子网的所有主机上。如果客户端和 DHCP 服务器不在同一个子网,就需要使用中继代理。DHCP 服务器收到 Discover 报文之后,发送 Offer 报文给客户端,该报文包含了客户端所需要的信息。因为客户端可能收到多个 DHCP 服务器提供的信息,因此客户端需要进行选择。如果客户端选择了某个 DHCP 服务器提供的信息,那么就发送 Request 报文给该 DHCP 服务器。DHCP 服务器发送 Ack 报文,表示客户端此时可以使用提供给它的信息。 远程登录协议TELNET 用于登录到远程主机上,并且远程主机上的输出也会返回。TELNET 可以适应许多计算机和操作系统的差异,例如不同操作系统系统的换行符定义。电子邮件协议一个电子邮件系统由三部分组成:用户代理、邮件服务器以及邮件协议。邮件协议包含发送协议和读取协议,发送协议常用 SMTP,读取协议常用 POP3 和 IMAP。 1. SMTPSMTP 只能发送 ASCII 码,而互联网邮件扩充 MIME 可以发送二进制文件。MIME 并没有改动或者取代 SMTP,而是增加邮件主体的结构,定义了非 ASCII 码的编码规则。 2. POP3POP3 的特点是只要用户从服务器上读取了邮件,就把该邮件删除。但最新版本的 POP3 可以不删除邮件。3. IMAPIMAP 协议中客户端和服务器上的邮件保持同步,如果不手动删除邮件,那么服务器上的邮件也不会被删除。IMAP 这种做法可以让用户随时随地去访问服务器上的邮件。常用端口应用应用层协议端口号传输层协议备注域名解析DNS53UDP/TCP长度超过 512 字节时使用 TCP动态主机配置协议DHCP67/68UDP简单网络管理协议SNMP161/162UDP文件传送协议FTP20/21TCP控制连接 21,数据连接 20远程终端协议TELNET23TCP超文本传送协议HTTP80TCP简单邮件传送协议SMTP25TCP邮件读取协议POP3110TCP网际报文存取协议IMAP143TCPWeb 页面请求过程1. DHCP 配置主机信息假设主机最开始没有 IP 地址以及其它信息,那么就需要先使用 DHCP 来获取。主机生成一个 DHCP 请求报文,并将这个报文放入具有目的端口 67 和源端口 68 的 UDP 报文段中。该报文段则被放入在一个具有广播 IP 目的地址(255.255.255.255) 和源 IP 地址(0.0.0.0)的 IP 数据报中。该数据报则被放置在 MAC 帧中,该帧具有目的地址 FF:FF:FF:FF:FF:FF,将广播到与交换机连接的所有设备。连接在交换机的 DHCP 服务器收到广播帧之后,不断地向上分解得到 IP 数据报、UDP 报文段、DHCP 请求报文,之后生成 DHCP ACK 报文,该报文包含以下信息:IP 地址、DNS 服务器的 IP 地址、默认网关路由器的 IP 地址和子网掩码。该报文被放入 UDP 报文段中,UDP 报文段有被放入 IP 数据报中,最后放入 MAC 帧中。该帧的目的地址是请求主机的 MAC 地址,因为交换机具有自学习能力,之前主机发送了广播帧之后就记录了 MAC 地址到其转发接口的交换表项,因此现在交换机就可以直接知道应该向哪个接口发送该帧。主机收到该帧后,不断分解得到 DHCP 报文。之后就配置它的 IP 地址、子网掩码和 DNS 服务器的 IP 地址,并在其 IP 转发表中安装默认网关。2. ARP 解析 MAC 地址主机通过浏览器生成一个 TCP 套接字,套接字向 HTTP 服务器发送 HTTP 请求。为了生成该套接字,主机需要知道网站的域名对应的 IP 地址。主机生成一个 DNS 查询报文,该报文具有 53 号端口,因为 DNS 服务器的端口号是 53。该 DNS 查询报文被放入目的地址为 DNS 服务器 IP 地址的 IP 数据报中。该 IP 数据报被放入一个以太网帧中,该帧将发送到网关路由器。DHCP 过程只知道网关路由器的 IP 地址,为了获取网关路由器的 MAC 地址,需要使用 ARP 协议。主机生成一个包含目的地址为网关路由器 IP 地址的 ARP 查询报文,将该 ARP 查询报文放入一个具有广播目的地址(FF:FF:FF:FF:FF:FF)的以太网帧中,并向交换机发送该以太网帧,交换机将该帧转发给所有的连接设备,包括网关路由器。网关路由器接收到该帧后,不断向上分解得到 ARP 报文,发现其中的 IP 地址与其接口的 IP 地址匹配,因此就发送一个 ARP 回答报文,包含了它的 MAC 地址,发回给主机。3. DNS 解析域名知道了网关路由器的 MAC 地址之后,就可以继续 DNS 的解析过程了。网关路由器接收到包含 DNS 查询报文的以太网帧后,抽取出 IP 数据报,并根据转发表决定该 IP 数据报应该转发的路由器。因为路由器具有内部网关协议(RIP、OSPF)和外部网关协议(BGP)这两种路由选择协议,因此路由表中已经配置了网关路由器到达 DNS 服务器的路由表项。到达 DNS 服务器之后,DNS 服务器抽取出 DNS 查询报文,并在 DNS 数据库中查找待解析的域名。找到 DNS 记录之后,发送 DNS 回答报文,将该回答报文放入 UDP 报文段中,然后放入 IP 数据报中,通过路由器反向转发回网关路由器,并经过以太网交换机到达主机。4. HTTP 请求页面有了 HTTP 服务器的 IP 地址之后,主机就能够生成 TCP 套接字,该套接字将用于向 Web 服务器发送 HTTP GET 报文。在生成 TCP 套接字之前,必须先与 HTTP 服务器进行三次握手来建立连接。生成一个具有目的端口 80 的 TCP SYN 报文段,并向 HTTP 服务器发送该报文段。HTTP 服务器收到该报文段之后,生成 TCP SYN ACK 报文段,发回给主机。连接建立之后,浏览器生成 HTTP GET 报文,并交付给 HTTP 服务器。HTTP 服务器从 TCP 套接字读取 HTTP GET 报文,生成一个 HTTP 响应报文,将 Web 页面内容放入报文主体中,发回给主机。浏览器收到 HTTP 响应报文后,抽取出 Web 页面内容,之后进行渲染,显示 Web 页面。]]></content>
<categories>
<category>网络</category>
<category>【计算机网络】</category>
</categories>
<tags>
<tag>网络</tag>
</tags>
</entry>
<entry>
<title><![CDATA[计算机网络--数据链路层]]></title>
<url>%2F2019%2F10%2F16%2F%E7%BD%91%E7%BB%9C%2F%E3%80%90%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E3%80%91%2F%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82%2F</url>
<content type="text"><![CDATA[解决的三大基本问题1. 封装成帧将网络层传下来的分组添加首部和尾部,用于标记帧的开始和结束。在一段数据的前后分别添加首部和尾部(帧定界),这样就构成了一个帧。 最大传送单元MTU —- 数据部分长度上限 2. 透明传输透明表示一个实际存在的事物看起来好像不存在一样。表示无论什么样的比特组合的数据,都能按照原样没有差错地通过这个数据链路图进行传送。 帧使用首部和尾部进行定界,如果帧的数据部分含有和首部尾部相同的内容,那么帧的开始和结束位置就会被错误的判定。需要在数据部分出现首部尾部相同的内容前面插入转义字符。如果数据部分出现转义字符,那么就在转义字符前面再加个转义字符。可以通过字节填充或者字符填充的方法进行处理,在接收端进行处理之后可以还原出原始数据。这个过程透明传输的内容是转义字符,用户察觉不到转义字符的存在。 3. 差错检测比特差错:11可能变成0,0可能变成1目前数据链路层广泛使用了循环冗余检验(CRC)来检查比特差错。凡是接收端数据链路层接受的帧均无差错。 异或运算。除数有4为,所以需要加3个0。 信道分类1. 广播信道一对多通信,一个节点发送的数据能够被广播信道上所有的节点接收到。所有的节点都在同一个广播信道上发送数据,因此需要有专门的控制方法进行协调,避免发生冲突(冲突也叫碰撞)。主要有两种控制方法进行协调,一个是使用信道复用技术,一是使用 CSMA/CD 协议。 2. 点对点信道一对一通信。 因为不会发生碰撞,因此也比较简单,使用 PPP 协议进行控制。 CSMA/CD 协议CSMA/CD 表示载波监听多点接入 / 碰撞检测。 多点接入 :说明这是总线型网络,许多主机以多点的方式连接到总线上。载波监听 :每个主机都必须不停地监听信道。在发送前,如果监听到信道正在使用,就必须等待。碰撞检测 :在发送中,如果监听到信道已有其它主机正在发送数据,就表示发生了碰撞。虽然每个主机在发送数据之前都已经监听到信道为空闲,但是由于电磁波的传播时延的存在,还是有可能会发生碰撞。记端到端的传播时延为 τ,最先发送的站点最多经过 2τ 就可以知道是否发生了碰撞,称 2τ 为 争用期 。只有经过争用期之后还没有检测到碰撞,才能肯定这次发送不会发生碰撞。 当发生碰撞时,站点要停止发送,等待一段时间再发送。这个时间采用 截断二进制指数退避算法 来确定。从离散的整数集合 {0, 1, .., (2k-1)} 中随机取出一个数,记作 r,然后取 r 倍的争用期作为重传等待时间。 PPP 协议互联网用户通常需要连接到某个 ISP 之后才能接入到互联网,PPP 协议是用户计算机和 ISP 进行通信时所使用的数据链路层协议。 PPP 的帧格式: F 字段为帧的定界符A 和 C 字段暂时没有意义FCS 字段是使用 CRC 的检验序列信息部分的长度不超过 1500 MAC 地址MAC 地址是链路层地址,长度为 6 字节(48 位),用于唯一标识网络适配器(网卡)。 一台主机拥有多少个网络适配器就有多少个 MAC 地址。例如笔记本电脑普遍存在无线网络适配器和有线网络适配器,因此就有两个 MAC 地址。 局域网局域网是一种典型的广播信道,主要特点是网络为一个单位所拥有,且地理范围和站点数目均有限。 主要有以太网、令牌环网、FDDI 和 ATM 等局域网技术,目前以太网占领着有线局域网市场。 可以按照网络拓扑结构对局域网进行分类: 以太网以太网是一种星型拓扑结构局域网。 早期使用集线器进行连接,集线器是一种物理层设备, 作用于比特而不是帧,当一个比特到达接口时,集线器重新生成这个比特,并将其能量强度放大,从而扩大网络的传输距离,之后再将这个比特发送到其它所有接口。如果集线器同时收到两个不同接口的帧,那么就发生了碰撞。 目前以太网使用交换机替代了集线器,交换机是一种链路层设备,它不会发生碰撞,能根据 MAC 地址进行存储转发。 以太网帧格式: 类型 :标记上层使用的协议;数据 :长度在 46-1500 之间,如果太小则需要填充;FCS :帧检验序列,使用的是 CRC 检验方法; 交换机交换机具有自学习能力,学习的是交换表的内容,交换表中存储着 MAC 地址到接口的映射。 正是由于这种自学习能力,因此交换机是一种即插即用设备,不需要网络管理员手动配置交换表内容。 下图中,交换机有 4 个接口,主机 A 向主机 B 发送数据帧时,交换机把主机 A 到接口 1 的映射写入交换表中。为了发送数据帧到 B,先查交换表,此时没有主机 B 的表项,那么主机 A 就发送广播帧,主机 C 和主机 D 会丢弃该帧,主机 B 回应该帧向主机 A 发送数据包时,交换机查找交换表得到主机 A 映射的接口为 1,就发送数据帧到接口 1,同时交换机添加主机 B 到接口 2 的映射。 虚拟局域网虚拟局域网可以建立与物理位置无关的逻辑组,只有在同一个虚拟局域网中的成员才会收到链路层广播信息。 例如下图中 (A1, A2, A3, A4) 属于一个虚拟局域网,A1 发送的广播会被 A2、A3、A4 收到,而其它站点收不到。 使用 VLAN 干线连接来建立虚拟局域网,每台交换机上的一个特殊接口被设置为干线接口,以互连 VLAN 交换机。IEEE 定义了一种扩展的以太网帧格式 802.1Q,它在标准以太网帧上加进了 4 字节首部 VLAN 标签,用于表示该帧属于哪一个虚拟局域网。]]></content>
<categories>
<category>网络</category>
<category>【计算机网络】</category>
</categories>
<tags>
<tag>网络</tag>
</tags>
</entry>
<entry>
<title><![CDATA[计算机网络--概述]]></title>
<url>%2F2019%2F10%2F16%2F%E7%BD%91%E7%BB%9C%2F%E3%80%90%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E3%80%91%2F%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C-%E6%A6%82%E8%BF%B0%2F</url>
<content type="text"><![CDATA[计算机网络是什么?有什么作用?计算机网络是由若干结点和连接这些这些结点的链路组成,是信息交流的基础。具有连通性和共享(资源共享) 网络的网络 网络把主机连接起来,而互连网(internet)是把多种不同的网络通过路由器连接起来,因此互连网是网络的网络。而互联网(Internet)是全球范围的互连网。 互联网服务提供商ISP互联网服务提供商 ISP 可以从互联网管理机构获得许多 IP 地址,同时拥有通信线路以及路由器等联网设备,个人或机构向 ISP 缴纳一定的费用就可以接入互联网。 目前的互联网是一种多层次 ISP 结构,ISP 根据覆盖面积的大小分为第一层 ISP、区域 ISP 和接入 ISP。互联网交换点 IXP 允许两个 ISP 直接相连而不用经过第三个 ISP。 主机之间的通信方式客户-服务器(C/S):客户是服务的请求方,服务器是服务的提供方。 对等连接(P2P):不区分客户和服务器。 电路交换与分组交换1. 电路交换电路交换用于电话通信系统,两个用户要通信之前需要建立一条专用的物理链路,并且在整个通信过程中始终占用该链路。需要经过“建立连接(占用通信资源)”->“通话(一直占用通信资源)”->“释放连接(归还通信资源)”三个步骤。由于通信的过程中不可能一直在使用传输线路,因此电路交换对线路的利用率很低,往往不到 10%。 2. 分组交换每个分组都有首部和尾部,包含了源地址和目的地址等控制信息,在同一个传输线路上同时传输多个分组互相不会影响,因此在同一条传输线路上允许同时传输多个分组,也就是说分组交换不需要占用传输线路。 在一个邮局通信系统中,邮局收到一份邮件之后,先存储下来,然后把相同目的地的邮件一起转发到下一个目的地,这个过程就是存储转发过程,分组交换也使用了存储转发过程。 3.三种交换方式在数据传送阶段的主要特点如下: 计算机网络的类别 按照网络作用范围划分为:广域网、城域网、局域网、个人区域网 按照网络的使用者进行划分为:公用网、专用网。 计算机网路的性能指标 计算机网络体系结构1. 五层协议应用层 :为特定应用程序提供数据传输服务,例如 HTTP、DNS 等协议。数据单位为报文。 传输层 :为进程提供通用数据传输服务。由于应用层协议很多,定义通用的传输层协议就可以支持不断增多的应用层协议。运输层包括两种协议:传输控制协议 TCP,提供面向连接、可靠的数据传输服务,数据单位为报文段;用户数据报协议 UDP,提供无连接、尽最大努力的数据传输服务,数据单位为用户数据报。TCP 主要提供完整性服务,UDP 主要提供及时性服务。 网络层 :为主机提供数据传输服务。而传输层协议是为主机中的进程提供数据传输服务。网络层把传输层传递下来的报文段或者用户数据报封装成分组。 数据链路层 :网络层针对的还是主机之间的数据传输服务,而主机之间可以有很多链路,链路层协议就是为同一链路的主机提供数据传输服务。数据链路层把网络层传下来的分组封装成帧。 物理层 :考虑的是怎样在传输媒体上传输数据比特流,而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异。 2. OSI七层结构其中表示层和会话层用途如下: 表示层 :数据压缩、加密以及数据描述,这使得应用程序不必关心在各台主机中数据内部格式不同的问题。 会话层 :建立及管理会话。 五层协议没有表示层和会话层,而是将这些功能留给应用程序开发者处理。 3. TCP/IP结构它只有四层,相当于五层协议中数据链路层和物理层合并为网络接口层。 TCP/IP 体系结构不严格遵循 OSI 分层概念,应用层可能会直接使用 IP 层或者网络接口层。 三种分层结构图: 4. 数据在各层之间的传递过程在向下的过程中,需要添加下层协议所需要的首部或者尾部,而在向上的过程中不断拆开首部和尾部。 路由器只有下面三层协议,因为路由器位于网络核心中,不需要为进程或者应用程序提供服务,因此也就不需要传输层和应用层。]]></content>
<categories>
<category>网络</category>
<category>【计算机网络】</category>
</categories>
<tags>
<tag>网络</tag>
</tags>
</entry>
<entry>
<title><![CDATA[计算机网络--物理层]]></title>
<url>%2F2019%2F10%2F16%2F%E7%BD%91%E7%BB%9C%2F%E3%80%90%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E3%80%91%2F%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C-%E7%89%A9%E7%90%86%E5%B1%82%2F</url>
<content type="text"><![CDATA[物理层所要解决的问题?解决如何在连接各种计算机的传输媒体上传输数据比特流,而不是指具体的传输媒体。 确定与接口相关的一些特性 机械特性:接口形状大小、引线数目 电气特性:接口电缆上的各条线出现的电压的范围。例如电压范围 -5 -> +5 功能特性:指明某条线上出现的某一电平的电压的意义 过程特性:规程特性,规定建立连接时各个相关部件的工作步骤 数据通信1.通信系统模型数据通信系统可划分为:源系统、传输系统、目的系统。 12345678910111213数据通信模型 目的 传送消息 数据 运送消息的实体 信号 数据的电气的或电磁的表现 模拟信号 代表消息的参数的取值是连续的 数字信号 代表消息的参数的取值是离散的 码元 在使用时间域的波形表示数字信号时,代表不同离散数值的基本波形就成为码元 2.信道相关知识点123456789101112131415161718192021信道 信道一般表示向一个方向传送信息的媒体 平常的通信线路 包含一条发送消息的信道 一条接受信号的信道 分类 单向通信(单工通信) 只能有一个方向的通信而灭有反方向的交互 双向交替通信(半双工通信) 通信的双方都可以发送信息,但不能双方同时发送(当然也不能同时接收) 双向同时通信(全双工通信) 通信的双方可以同时发送和接收信息 基带信号(基本频带信号) 来自信源的信号 计算机输出的代表各种文字或图像文件的数据信号都属于基带信号 发出的直接表达了要传输的信息的信号。 带通信号 把基带信号经过载波调制后,把信号的频率范围移到较高的频段以便在信道中传输 带通调制 模拟信号是连续的信号,数字信号是离散的信号。带通调制把数字信号转换为模拟信号。 调制方法 调幅、调频、调相 3.常见编码方式 单极性/双极性不归零码:正电平表示1,负电平代表0. 单极性/双极性归零码:正脉冲代表1,负脉冲代表0. 曼彻斯特编码:bit中间有信号。低到高 -> 0,高到低 -> 1 差分曼彻斯特编码 4.信道极限容量 奈氏准则:在任何信道中,码元传输的速率是有上限的,传输速率超过此上限,就会出现严重的码间串扰的问题,使接收端对码元的判决成为不可能 信噪比 香农公式:信道的带宽或信道中的信噪比越大,信号的极限传输速率就越高 传输媒体 导向/导引型传输媒体:电磁波沿着固体媒体传播 双绞线 屏蔽双绞线STP 、无屏蔽双绞线UTP 同轴电缆 有线电视 光缆 非引导型传输媒体:无线电微波。例如地面微波接力通信和卫星通信 信道复用技术复用是通信技术中的基本概念。 1.频分复用FDM所有用户在同样时间占用不同的带宽资源。 2.时分复用TDM(同步时分复用)所用用户在不同的时间占用同样的频带宽度 使用频分复用和时分复用进行通信,在通信的过程中主机会一直占用一部分信道资源。但是由于计算机数据的突发性质,通信过程没必要一直占用信道资源而不让出给其它用户使用,因此这两种方式对信道的利用率都不高。可能造成线路资源的浪费 3.统计时分复用STDM(异步时分复用)是对时分复用的一种改进,不固定每个用户在时分复用帧中的位置,只要有数据就集中起来组成统计时分复用帧然后发送。 4.波分复用(光的频分复用)光的频分复用。由于光的频率很高,因此习惯上用波长而不是频率来表示所使用的光载波。 5.码分复用码分复用有很强的抗干扰能力,不易被发现(常用于传送机密)。码分复用CDMA:码片:每一个比特事件再划分为m个短的间隔。 码片序列的正交关系 工作原理 一些技术了解]]></content>
<categories>
<category>网络</category>
<category>【计算机网络】</category>
</categories>
<tags>
<tag>网络</tag>
</tags>
</entry>
<entry>
<title><![CDATA[计算机网络--网络层]]></title>
<url>%2F2019%2F10%2F16%2F%E7%BD%91%E7%BB%9C%2F%E3%80%90%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E3%80%91%2F%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C-%E7%BD%91%E7%BB%9C%E5%B1%82%2F</url>
<content type="text"><![CDATA[概述IP 数据报格式IP 地址编址方式1. 分类2. 子网划分3. 无分类地址解析协议 ARP网际控制报文协议 ICMP1. Ping2. Traceroute虚拟专用网 VPN网络地址转换 NAT路由器的结构路由器分组转发流程路由选择协议1. 内部网关协议 RIP2. 内部网关协议 OSPF3. 外部网关协议 BGP概述因为网络层是整个互联网的核心,因此应当让网络层尽可能简单。网络层向上只提供简单灵活的、无连接的、尽最大努力交互的数据报服务。使用 IP 协议,可以把异构的物理网络连接起来,使得在网络层看起来好像是一个统一的网络。 与 IP 协议配套使用的还有三个协议:地址解析协议 ARP(Address Resolution Protocol)网际控制报文协议 ICMP(Internet Control Message Protocol)网际组管理协议 IGMP(Internet Group Management Protocol)IP 数据报格式 版本 : 有 4(IPv4)和 6(IPv6)两个值;首部长度 : 占 4 位,因此最大值为 15。值为 1 表示的是 1 个 32 位字的长度,也就是 4 字节。因为固定部分长度为 20 字节,因此该值最小为 5。如果可选字段的长度不是 4 字节的整数倍,就用尾部的填充部分来填充。区分服务 : 用来获得更好的服务,一般情况下不使用。总长度 : 包括首部长度和数据部分长度。生存时间 :TTL,它的存在是为了防止无法交付的数据报在互联网中不断兜圈子。以路由器跳数为单位,当 TTL 为 0 时就丢弃数据报。协议 :指出携带的数据应该上交给哪个协议进行处理,例如 ICMP、TCP、UDP 等。首部检验和 :因为数据报每经过一个路由器,都要重新计算检验和,因此检验和不包含数据部分可以减少计算的工作量。标识 : 在数据报长度过长从而发生分片的情况下,相同数据报的不同分片具有相同的标识符。片偏移 : 和标识符一起,用于发生分片的情况。片偏移的单位为 8 字节。 IP 地址编址方式IP 地址的编址方式经历了三个历史阶段:分类子网划分无分类1. 分类由两部分组成,网络号和主机号,其中不同分类具有不同的网络号长度,并且是固定的。IP 地址 ::= {< 网络号 >, < 主机号 >} 2. 子网划分通过在主机号字段中拿一部分作为子网号,把两级 IP 地址划分为三级 IP 地址。IP 地址 ::= {< 网络号 >, < 子网号 >, < 主机号 >}要使用子网,必须配置子网掩码。一个 B 类地址的默认子网掩码为 255.255.0.0,如果 B 类地址的子网占两个比特,那么子网掩码为 11111111 11111111 11000000 00000000,也就是 255.255.192.0。注意,外部网络看不到子网的存在。3. 无分类无分类编址 CIDR 消除了传统 A 类、B 类和 C 类地址以及划分子网的概念,使用网络前缀和主机号来对 IP 地址进行编码,网络前缀的长度可以根据需要变化。IP 地址 ::= {< 网络前缀号 >, < 主机号 >}CIDR 的记法上采用在 IP 地址后面加上网络前缀长度的方法,例如 128.14.35.7/20 表示前 20 位为网络前缀。CIDR 的地址掩码可以继续称为子网掩码,子网掩码首 1 长度为网络前缀的长度。一个 CIDR 地址块中有很多地址,一个 CIDR 表示的网络就可以表示原来的很多个网络,并且在路由表中只需要一个路由就可以代替原来的多个路由,减少了路由表项的数量。把这种通过使用网络前缀来减少路由表项的方式称为路由聚合,也称为 构成超网 。在路由表中的项目由“网络前缀”和“下一跳地址”组成,在查找时可能会得到不止一个匹配结果,应当采用最长前缀匹配来确定应该匹配哪一个。地址解析协议 ARP网络层实现主机之间的通信,而链路层实现具体每段链路之间的通信。因此在通信过程中,IP 数据报的源地址和目的地址始终不变,而 MAC 地址随着链路的改变而改变。 ARP 实现由 IP 地址得到 MAC 地址。 每个主机都有一个 ARP 高速缓存,里面有本局域网上的各主机和路由器的 IP 地址到 MAC 地址的映射表。如果主机 A 知道主机 B 的 IP 地址,但是 ARP 高速缓存中没有该 IP 地址到 MAC 地址的映射,此时主机 A 通过广播的方式发送 ARP 请求分组,主机 B 收到该请求后会发送 ARP 响应分组给主机 A 告知其 MAC 地址,随后主机 A 向其高速缓存中写入主机 B 的 IP 地址到 MAC 地址的映射。 网际控制报文协议 ICMPICMP 是为了更有效地转发 IP 数据报和提高交付成功的机会。它封装在 IP 数据报中,但是不属于高层协议。 ICMP 报文分为差错报告报文和询问报文。 1. PingPing 是 ICMP 的一个重要应用,主要用来测试两台主机之间的连通性。Ping 的原理是通过向目的主机发送 ICMP Echo 请求报文,目的主机收到之后会发送 Echo 回答报文。Ping 会根据时间和成功响应的次数估算出数据包往返时间以及丢包率。2. TracerouteTraceroute 是 ICMP 的另一个应用,用来跟踪一个分组从源点到终点的路径。Traceroute 发送的 IP 数据报封装的是无法交付的 UDP 用户数据报,并由目的主机发送终点不可达差错报告报文。源主机向目的主机发送一连串的 IP 数据报。第一个数据报 P1 的生存时间 TTL 设置为 1,当 P1 到达路径上的第一个路由器 R1 时,R1 收下它并把 TTL 减 1,此时 TTL 等于 0,R1 就把 P1 丢弃,并向源主机发送一个 ICMP 时间超过差错报告报文;源主机接着发送第二个数据报 P2,并把 TTL 设置为 2。P2 先到达 R1,R1 收下后把 TTL 减 1 再转发给 R2,R2 收下后也把 TTL 减 1,由于此时 TTL 等于 0,R2 就丢弃 P2,并向源主机发送一个 ICMP 时间超过差错报文。不断执行这样的步骤,直到最后一个数据报刚刚到达目的主机,主机不转发数据报,也不把 TTL 值减 1。但是因为数据报封装的是无法交付的 UDP,因此目的主机要向源主机发送 ICMP 终点不可达差错报告报文。之后源主机知道了到达目的主机所经过的路由器 IP 地址以及到达每个路由器的往返时间。虚拟专用网 VPN由于 IP 地址的紧缺,一个机构能申请到的 IP 地址数往往远小于本机构所拥有的主机数。并且一个机构并不需要把所有的主机接入到外部的互联网中,机构内的计算机可以使用仅在本机构有效的 IP 地址(专用地址)。有三个专用地址块:10.0.0.0 ~ 10.255.255.255172.16.0.0 ~ 172.31.255.255192.168.0.0 ~ 192.168.255.255VPN 使用公用的互联网作为本机构各专用网之间的通信载体。专用指机构内的主机只与本机构内的其它主机通信;虚拟指好像是,而实际上并不是,它有经过公用的互联网。下图中,场所 A 和 B 的通信经过互联网,如果场所 A 的主机 X 要和另一个场所 B 的主机 Y 通信,IP 数据报的源地址是 10.1.0.1,目的地址是 10.2.0.3。数据报先发送到与互联网相连的路由器 R1,R1 对内部数据进行加密,然后重新加上数据报的首部,源地址是路由器 R1 的全球地址 125.1.2.3,目的地址是路由器 R2 的全球地址 194.4.5.6。路由器 R2 收到数据报后将数据部分进行解密,恢复原来的数据报,此时目的地址为 10.2.0.3,就交付给 Y。 网络地址转换 NAT专用网内部的主机使用本地 IP 地址又想和互联网上的主机通信时,可以使用 NAT 来将本地 IP 转换为全球 IP。在以前,NAT 将本地 IP 和全球 IP 一一对应,这种方式下拥有 n 个全球 IP 地址的专用网内最多只可以同时有 n 台主机接入互联网。为了更有效地利用全球 IP 地址,现在常用的 NAT 转换表把传输层的端口号也用上了,使得多个专用网内部的主机共用一个全球 IP 地址。使用端口号的 NAT 也叫做网络地址与端口转换 NAPT。 路由器的结构路由器从功能上可以划分为:路由选择和分组转发。分组转发结构由三个部分组成:交换结构、一组输入端口和一组输出端口。 路由器分组转发流程从数据报的首部提取目的主机的 IP 地址 D,得到目的网络地址 N。若 N 就是与此路由器直接相连的某个网络地址,则进行直接交付;若路由表中有目的地址为 D 的特定主机路由,则把数据报传送给表中所指明的下一跳路由器;若路由表中有到达网络 N 的路由,则把数据报传送给路由表中所指明的下一跳路由器;若路由表中有一个默认路由,则把数据报传送给路由表中所指明的默认路由器;报告转发分组出错。 路由选择协议路由选择协议都是自适应的,能随着网络通信量和拓扑结构的变化而自适应地进行调整。互联网可以划分为许多较小的自治系统 AS,一个 AS 可以使用一种和别的 AS 不同的路由选择协议。可以把路由选择协议划分为两大类:自治系统内部的路由选择:RIP 和 OSPF自治系统间的路由选择:BGP1. 内部网关协议 RIPRIP 是一种基于距离向量的路由选择协议。距离是指跳数,直接相连的路由器跳数为 1。跳数最多为 15,超过 15 表示不可达。RIP 按固定的时间间隔仅和相邻路由器交换自己的路由表,经过若干次交换之后,所有路由器最终会知道到达本自治系统中任何一个网络的最短距离和下一跳路由器地址。距离向量算法:对地址为 X 的相邻路由器发来的 RIP 报文,先修改报文中的所有项目,把下一跳字段中的地址改为 X,并把所有的距离字段加 1;对修改后的 RIP 报文中的每一个项目,进行以下步骤:若原来的路由表中没有目的网络 N,则把该项目添加到路由表中;否则:若下一跳路由器地址是 X,则把收到的项目替换原来路由表中的项目;否则:若收到的项目中的距离 d 小于路由表中的距离,则进行更新(例如原始路由表项为 Net2, 5, P,新表项为 Net2, 4, X,则更新);否则什么也不做。若 3 分钟还没有收到相邻路由器的更新路由表,则把该相邻路由器标为不可达,即把距离置为 16。RIP 协议实现简单,开销小。但是 RIP 能使用的最大距离为 15,限制了网络的规模。并且当网络出现故障时,要经过比较长的时间才能将此消息传送到所有路由器。2. 内部网关协议 OSPF开放最短路径优先 OSPF,是为了克服 RIP 的缺点而开发出来的。开放表示 OSPF 不受某一家厂商控制,而是公开发表的;最短路径优先表示使用了 Dijkstra 提出的最短路径算法 SPF。OSPF 具有以下特点:向本自治系统中的所有路由器发送信息,这种方法是洪泛法。发送的信息就是与相邻路由器的链路状态,链路状态包括与哪些路由器相连以及链路的度量,度量用费用、距离、时延、带宽等来表示。只有当链路状态发生变化时,路由器才会发送信息。所有路由器都具有全网的拓扑结构图,并且是一致的。相比于 RIP,OSPF 的更新过程收敛的很快。3. 外部网关协议 BGPBGP(Border Gateway Protocol,边界网关协议)AS 之间的路由选择很困难,主要是由于:互联网规模很大;各个 AS 内部使用不同的路由选择协议,无法准确定义路径的度量;AS 之间的路由选择必须考虑有关的策略,比如有些 AS 不愿意让其它 AS 经过。BGP 只能寻找一条比较好的路由,而不是最佳路由。每个 AS 都必须配置 BGP 发言人,通过在两个相邻 BGP 发言人之间建立 TCP 连接来交换路由信息。]]></content>
<categories>
<category>网络</category>
<category>【计算机网络】</category>
</categories>
<tags>
<tag>网络</tag>
</tags>
</entry>
<entry>
<title><![CDATA[一个神奇的安全框架Shiro]]></title>
<url>%2F2019%2F08%2F18%2FWeb%E5%90%8E%E7%AB%AF%E6%8A%80%E6%9C%AF%2F%E3%80%90Shiro%E5%AD%A6%E4%B9%A0%E3%80%91%2F%E4%B8%80%E4%B8%AA%E7%A5%9E%E5%A5%87%E7%9A%84%E5%AE%89%E5%85%A8%E6%A1%86%E6%9E%B6shiro%2F</url>
<content type="text"><![CDATA[安全框架:Apache Shiro什么是Apache Shiro?Apache Shiro是一个功能强大且易于使用的Java安全框架,可执行身份验证,授权,加密和会话管理,并可用于保护任何应用程序。从命令行应用程序,移动应用程序到最大的Web和企业应用程序。Shiro提供了应用程序安全API来执行以下方面: 身份验证 - 证明用户身份,通常称为用户“登录”。 授权 - 访问控制 密码学 - 保护或隐藏窥探数据的数据 会话管理 - 每用户时间敏感状态]]></content>
<categories>
<category>Web后端技术</category>
<category>【Shiro学习】</category>
</categories>
<tags>
<tag>安全框架</tag>
</tags>
</entry>
<entry>
<title><![CDATA[IDEA创建第一个maven-web项目]]></title>
<url>%2F2019%2F06%2F18%2FIntellij-IDEA%2Fidea%E5%88%9B%E5%BB%BA%E7%AC%AC%E4%B8%80%E4%B8%AAmaven-web%E9%A1%B9%E7%9B%AE%2F</url>
<content type="text"><![CDATA[IDEA创建WEB项目 用惯了eclipse,这段时间刚接触Idea编辑工具,这款神器是真的好用,兄弟们用起来!!! 但在创建maven web项目的一些步骤有些不熟悉,在这里介绍一下常用的maven web项目的创建过程。 1.步骤一:首先先创建一个project,在这里就是创建一个maven的工作空间 2.步骤二:选择左边的maven,然后在右边Creater from archetype选项前面打个勾,并且选择(maven-archetype-webapp),接着点击next 3.步骤三:填写你的Group Id(一般写公司名)跟 ArtifictId(一般写项目名) 4.步骤四:选择自己下载好的apache-maven. 5.步骤五:继续一路finish,等待idea加载出目录结构 如果目录没有出来,则点击更新操作。 6.步骤六:项目的基本目录结构出来后,我们还需为项目配置下编译路径还有artifact,操作如下 7.步骤七:配置tomcat本地服务器,运行项目]]></content>
<categories>
<category>Intellij IDEA</category>
</categories>
<tags>
<tag>编辑器</tag>
</tags>
</entry>
<entry>
<title><![CDATA[逆向工程在idea开发项目的使用]]></title>
<url>%2F2019%2F06%2F18%2FWeb%E5%90%8E%E7%AB%AF%E6%8A%80%E6%9C%AF%2F%E5%B7%A5%E7%A8%8B%E6%8A%80%E6%9C%AF-%E3%80%90%E9%80%86%E5%90%91%E5%B7%A5%E7%A8%8B%E3%80%91%2F%E9%80%86%E5%90%91%E5%B7%A5%E7%A8%8B%E5%9C%A8idea%E5%BC%80%E5%8F%91%E9%A1%B9%E7%9B%AE%E7%9A%84%E4%BD%BF%E7%94%A8%2F</url>
<content type="text"><![CDATA[逆向工程技术的使用一、逆向工程 逆向工程:mybaits需要程序员自己编写sql语句,编写过程比较繁琐。因此mybatis官方提供逆向工程mybatis-generator,可以根据表与表之间的关系,自动生成mybatis执行所需要的代码(mapper.java,mapper.xml,pojo) 二、逆向工程的准备1.建立一个数据库表(你要操作的) 2.jar包准备(pom.xml引入依赖包,下面引入包比较多,可根据需要引入)123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yy</groupId> <artifactId>YYcoder</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>YYcoder Maven Webapp</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>4.1.4.RELEASE</spring.version> <jackson.version>2.5.0</jackson.version> </properties> <dependencies> <!-- junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- spring 所有核心包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency> <!-- mybatis 包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.8</version> </dependency> <!--mybatis spring 整合 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.2</version> </dependency> <!-- mysql连接 注意版本--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <!-- 数据源 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.12</version> </dependency> <!-- aspectjweaver是spring的切入点表达式需要用的包, --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.4</version> </dependency> <!-- log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>3.0-alpha-1</version> <scope>provided</scope> </dependency> <!-- jstl --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- java对象和json相互转化 --> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency> <!-- 后台转化为json格式 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.3</version> </dependency> <!-- springmvc框架整合AJAX使用@ResponseBody需要此包 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${jackson.version}</version> </dependency> <!-- 基本的序列化和反序列化 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency> <!-- 将JSON格式的数据转化为类对象 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <!-- 文件上传 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <!-- mybatis-generator-core 反向生成java代码--> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.5</version> </dependency> <!-- 文件上传 --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2.2</version> </dependency> <!-- mybatis-redis整合依赖 --> <dependency> <groupId>org.mybatis.caches</groupId> <artifactId>mybatis-redis</artifactId> <version>1.0.0-beta2</version> </dependency> <!-- spring 整合 redis --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.0.2.RELEASE</version> </dependency> <!-- jedis 依赖 --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.1.0</version> </dependency> </dependencies> <build> <finalName>YYcoder</finalName> <plugins> <!-- 资源文件拷贝插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.7</version> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> <!-- java编译插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!-- 配置Tomcat插件 --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <uriEncoding>UTF-8</uriEncoding> </configuration> </plugin> <!--逆向工程插件--> <!-- mybatis generator 自动生成代码插件 --> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.5</version> <configuration> <!-- 配置文件路径 --> <overwrite>true</overwrite> <verbose>true</verbose> </configuration> </plugin> </plugins> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </build></project> 3.编写generatorConfig.xml123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" ><generatorConfiguration > <!-- mysql jar 文件位置 --> <context id="store" targetRuntime="MyBatis3"> <commentGenerator> <!-- 是否去除自动生成的注释 true:是 : false:否 --> <property name="suppressAllComments" value="true" /> <!-- 是否去除所有自动生成的文件的时间戳,默认为false --> <property name="suppressDate" value="true"/> </commentGenerator> <!--数据库连接的信息:驱动类、连接地址、用户名、密码 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/yy_mysql" userId="root" password="cyy493610"> </jdbcConnection> <!-- targetPackage:包名称(自定义) targetProject:项目路径(自定义) --> <!--定义model的包名称--> <javaModelGenerator targetPackage="com.YYcoder.entity" targetProject="src/main/java"> <!-- enableSubPackages:是否让schema作为包的后缀 --> <property name="enableSubPackages" value="false" /> <!-- 从数据库返回的值被清理前后的空格 --> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- 配置生成相应的实体Mapper.xml,对于Mapper3.X我们需要把type="XMLMAPPER" --> <!-- targetPackage:包名称(自定义) targetProject:项目路径(自定义) --> <sqlMapGenerator targetPackage="com.YYcoder.mapper" targetProject="src/main/java"> <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <!-- 配置生成相应的接口类,对应与Mapper.xml中的一系列CRUD方法SQL语句 --> <!-- targetPackage:包名称(自定义) targetProject:项目路径(自定义) --> <javaClientGenerator targetPackage="com.YYcoder.mapper" targetProject="src/main/java" type="XMLMAPPER"> <property name="enableSubPackages" value="false" /> </javaClientGenerator> <!-- 数据库表名 --> <!-- 取消生成example类--> <table tableName= "address" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table> <table tableName= "admin" ></table> <table tableName= "category" ></table> <table tableName= "goods" ></table> <table tableName= "imagepath" ></table> <table tableName= "order" ></table> <table tableName= "oderitem" ></table> <table tableName= "shop" ></table> <table tableName= "shopcart" ></table> <table tableName= "user" ></table> </context></generatorConfiguration> 4.编写测试类MyGenerator.java,运行生成对应的文件123456789101112131415161718192021222324252627282930313233package com.YYcoder.Test;import org.mybatis.generator.api.MyBatisGenerator;import org.mybatis.generator.config.Configuration;import org.mybatis.generator.config.xml.ConfigurationParser;import org.mybatis.generator.internal.DefaultShellCallback;import java.io.File;import java.util.ArrayList;import java.util.List;//编写java启动类,执行逆向工程的配置文件,生成数据库中指定表的model和dao层:// (注意:启动类中创建File中的路径是从本项目中开始的,需要找到从项目开始写起,直到找到配置文件的路径即可)public class MyGenerator { public void generate() throws Exception { List<String> warnings = new ArrayList<String>(); boolean overwrite = true; File configFile = new File("./src/main/resources/generatorConfig.xml"); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(configFile); DefaultShellCallback callback = new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); } public static void main(String[] args) throws Exception { try { MyGenerator myGenerator = new MyGenerator(); myGenerator.generate(); } catch (Exception e) { e.printStackTrace(); } }} 5.运行后,相应的包会出现对应的文件,即为操作成功]]></content>
<categories>
<category>Web后端技术</category>
<category>工程技术--【逆向工程】</category>
</categories>
<tags>
<tag>工程技术</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Spring Boot(一):入门篇]]></title>
<url>%2F2019%2F05%2F16%2FWeb%E5%90%8E%E7%AB%AF%E6%8A%80%E6%9C%AF%2F%E3%80%90SpringBoot%E5%AD%A6%E4%B9%A0%E3%80%91%2Fspring-boot-%E4%B8%80-%EF%BC%9A%E5%85%A5%E9%97%A8%E7%AF%87%2F</url>
<content type="text"><![CDATA[构建微服务:Spring boot 入门篇什么是Spring Boot?Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。其实Spring Boot 不是什么新的框架,它只是默认配置了很多框架的使用方式,就像 Maven 整合了所有的 Jar 包,Spring Boot 整合了所有的框架。 使用 Spring Boot有什么好处其实就是简单、快速、方便!平时如果我们需要搭建一个 Spring Web 项目的时候需要怎么做呢? 1)配置 web.xml,加载 Spring 和 Spring mvc 2)配置数据库连接、配置 Spring 事务 3)配置加载配置文件的读取,开启注解 4)配置日志文件 ···· 配置完成之后部署 Tomcat 调试想象一下如果生产项目,只是为了实现简单的一个发送消息的功能,都需要这样折腾一遍! 但是如果使用 Spring Boot 呢? 很简单,我仅仅只需要非常少的几个配置就可以迅速方便的搭建起来一套 Web 项目或者是构建一个微服务! 快速入门 说了那么多,不如马上来动手试一试! Maven 构建项目 1、访问 http://start.spring.io/ 2、选择构建工具 Maven Project、Java、Spring Boot 版本 2.1.5 以及一些工程基本信息,可参考下图 所示: 3、点击 Generate Project 下载项目压缩包 4、解压后,使用 Idea 导入项目,File -> New -> Model from Existing Source.. -> 选择解压后的文件夹 -> OK,选择 Maven 一路 Next,OK done! 5、如果使用的是 Eclipse,Import -> Existing Maven Projects -> Next -> 选择解压后的文件夹 -> Finsh,OK done! Idea 构建项目 1、选择 File -> New —> Project… 弹出新建项目的框 2、选择 Spring Initializr,Next 也会出现上述类似的配置界面,Idea 帮我们做了集成 3、填写相关内容后,点击 Next 选择依赖的包再点击 Next,最后确定信息无误点击 Finish。 项目结构介绍 如上图所示,Spring Boot的基础结构共三个文件: src/main/java 程序开发以及主程序入口 src/main/resources 配置文件 src/test/java 测试程序 另外,spingboot建议的目录结果如下: root package结构:com.example.myproject 123456789101112131415com +- example +- myproject +- Application.java | +- domain | +- Customer.java | +- CustomerRepository.java | +- service | +- CustomerService.java | +- controller | +- CustomerController.java | 1、Application.java 建议放到跟目录下面,主要用于做一些框架配置 2、domain目录主要用于实体(Entity)与数据访问层(Repository) 3、service 层主要是业务类代码 4、controller 负责页面访问控制 采用默认配置可以省去很多配置,当然也可以根据自己的喜欢来进行更改最后,启动Application main方法,至此一个java项目搭建好了! 引入 Web 模块1、pom.xml中添加支持web的模块:1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency> pom.xml文件中默认有两个模块: spring-boot-starter:核心模块,包括自动配置支持、日志和YAML; spring-boot-starter-test:测试模块,包括JUnit、Hamcrest、Mockito。 2、编写controller内容1234567@RestControllerpublic class HelloWorldController { @RequestMapping("/hello") public String index() { return "Hello World"; }} @RestController的意思就是controller里面的方法都以json格式输出,不用再写什么jackjson配置的了! 3、启动主程序,打开浏览器访问http://localhost:8080/hello, 就可以看到效果了,是不是很简单粗暴! 如何做单元测试打开的src/test/下的测试入口,编写简单的http请求来测试;使用mockmvc进行,利用MockMvcResultHandlers.print() 打印出执行结果。1234567891011121314151617 @RunWith(SpringRunner.class) @SpringBootTest public class HelloWorldControlerTests { private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build(); } @Test public void getHello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(MockMvcResultMatchers.status().isOk()) .andDo(MockMvcResultHandlers.print()) .andReturn(); }} 开发环境的调试热启动在正常开发项目中已经很常见了吧,虽然平时开发 web 项目过程中,改动项目启重启总是报错;但Spring Boot对调试支持很好,修改之后可以实时生效,需要添加以下的配置: 1234567891011121314151617181920212223242526272829303132333435<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency></dependencies><build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> </configuration> </plugin> </plugins></build> 该模块在完整的打包环境下运行的时候会被禁用。如果你使用java -jar启动应用或者用一个特定的classloader启动,它会认为这是一个“生产环境”。 总结使用 Spring Boot 可以非常方便、快速搭建项目,使我们不用关心框架之间的兼容性,适用版本等各种问题,我们想使用任何东西,仅仅添加一个配置就可以,所以使用 Spring Boot 非常适合构建微服务。]]></content>
<categories>
<category>Web后端技术</category>
<category>【SpringBoot学习】</category>
</categories>
<tags>
<tag>框架学习</tag>
</tags>
</entry>
<entry>
<title><![CDATA[排序算法(一)--冒泡排序]]></title>
<url>%2F2019%2F05%2F16%2F%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95%2F%E3%80%90%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95%E3%80%91%2F%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95-%E4%B8%80-%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F%2F</url>
<content type="text"><![CDATA[冒泡排序(每趟排序过程中通过两两比较,找到第 i 个小(大)的元素,将其往上排。) 算法概念比较相邻的元素。如果第一个比第二个大,就交换他们两个。针对所有的元素重复以上的步骤,除了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 冒泡排序动画演示 冒泡排序冒泡排序是一种交换排序。 什么是交换排序呢? 交换排序:两两比较待排序的关键字,并交换不满足次序要求的那对数,直到整个表都满足次序要求为止。 算法思想 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。 假设有一个大小为 N 的无序序列。冒泡排序就是要每趟排序过程中通过两两比较,找到第 i 个小(大)的元素,将其往上排。 图-冒泡排序示例图 以上图为例,演示一下冒泡排序的实际流程:假设有一个无序序列 { 4. 3. 1. 2, 5 }第一趟排序:通过两两比较,找到第一小的数值 1 ,将其放在序列的第一位。第二趟排序:通过两两比较,找到第二小的数值 2 ,将其放在序列的第二位。第三趟排序:通过两两比较,找到第三小的数值 3 ,将其放在序列的第三位。至此,所有元素已经有序,排序结束。 要将以上流程转化为代码,我们需要像机器一样去思考,不然编译器可看不懂。假设要对一个大小为 N 的无序序列进行升序排序(即从小到大)。(1) 每趟排序过程中需要通过比较找到第 i 个小的元素。所以,我们需要一个外部循环,从数组首端(下标 0) 开始,一直扫描到倒数第二个元素(即下标 N - 2) ,剩下最后一个元素,必然为最大。(2) 假设是第 i 趟排序,可知,前 i-1 个元素已经有序。现在要找第 i 个元素,只需从数组末端开始,扫描到第 i 个元素,将它们两两比较即可。所以,需要一个内部循环,从数组末端开始(下标 N - 1),扫描到 (下标 i + 1)。 核心代码 算法分析 冒泡排序算法的性能 时间复杂度若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数C和记录移动次数M均达到最小值:Cmin = N - 1, Mmin = 0。所以,冒泡排序最好时间复杂度为O(N)。 若初始文件是反序的,需要进行 N -1 趟排序。每趟排序要进行 N - i 次关键字的比较(1 ≤ i ≤ N - 1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:Mmax = 3N(N-1)/2 = O(N2)冒泡排序的最坏时间复杂度为O(N2)。因此,冒泡排序的平均时间复杂度为O(N2)。总结起来,其实就是一句话:当数据越接近正序时,冒泡排序性能越好。 算法稳定性冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。 优化对冒泡排序常见的改进方法是加入标志性变量exchange,用于标志某一趟排序过程中是否有数据交换。如果进行某一趟排序时并没有进行数据交换,则说明所有数据已经有序,可立即结束排序,避免不必要的比较过程。核心代码 运行结果12345678排序前: 2 9 9 7 1 9 0 2 6 8 第 0 趟: 0 2 9 9 7 1 9 2 6 8 第 1 趟: 0 1 2 9 9 7 2 9 6 8 第 2 趟: 0 1 2 2 9 9 7 6 9 8 第 3 趟: 0 1 2 2 6 9 9 7 8 9 第 4 趟: 0 1 2 2 6 7 9 9 8 9 第 5 趟: 0 1 2 2 6 7 8 9 9 9 排序后: 0 1 2 2 6 7 8 9 9 9]]></content>
<categories>
<category>数据结构和算法</category>
<category>【排序算法】</category>
</categories>
<tags>
<tag>排序算法</tag>
</tags>
</entry>
<entry>
<title><![CDATA[排序算法(二)--选择排序]]></title>
<url>%2F2019%2F05%2F16%2F%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95%2F%E3%80%90%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95%E3%80%91%2F%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95-%E4%BA%8C-%E9%80%89%E6%8B%A9%E6%8E%92%E5%BA%8F%2F</url>
<content type="text"><![CDATA[算法概念首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。重复第二步,直到所有元素均排序完毕。 动画演示 选择排序动画演示 参考代码 排序算法总结简单选择排序是一种选择排序。 选择排序:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止。 简单排序处理流程(1)从待排序序列中,找到关键字最小的元素;(2)如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换;(3)从余下的 N - 1 个元素中,找出关键字最小的元素,重复(1)、(2)步,直到排序结束。如图所示,每趟排序中,将当前第 i 小的元素放在位置 i 上。核心代码1234567891011121314151617181920212223public void selectionSort(int[] list) { // 需要遍历获得最小值的次数 // 要注意一点,当要排序 N 个数,已经经过 N-1 次遍历后,已经是有序数列 for (int i = 0; i < list.length - 1; i++) { int temp = 0; int index = i; // 用来保存最小值得索引 // 寻找第i个小的数值 for (int j = i + 1; j < list.length; j++) { if (list[index] > list[j]) { index = j; } } // 将找到的第i个小的数值放在第i个位置上 temp = list[index]; list[index] = list[i]; list[i] = temp; System.out.format("第 %d 趟: ", i + 1); printAll(list); }} 算法分析 算法的性能 时间复杂度简单选择排序的比较次数与序列的初始排序无关。 假设待排序的序列有 N 个元素,则比较次数总是N (N - 1) / 2。而移动次数与序列的初始排序有关。当序列正序时,移动次数最少,为 0.当序列反序时,移动次数最多,为3N (N - 1) / 2。所以,综合以上,简单排序的时间复杂度为O(N2)。 空间复杂度简单选择排序需要占用 1 个临时空间,在交换数值时使用。 代码实现12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849package notes.javase.algorithm.sort;import java.util.Random; public class SelectionSort { public void selectionSort(int[] list) { // 需要遍历获得最小值的次数 // 要注意一点,当要排序 N 个数,已经经过 N-1 次遍历后,已经是有序数列 for (int i = 0; i < list.length - 1; i++) { int temp = 0; int index = i; // 用来保存最小值得索引 // 寻找第i个小的数值 for (int j = i + 1; j < list.length; j++) { if (list[index] > list[j]) { index = j; } } // 将找到的第i个小的数值放在第i个位置上 temp = list[index]; list[index] = list[i]; list[i] = temp; System.out.format("第 %d 趟: ", i + 1); printAll(list); } } // 打印完整序列 public void printAll(int[] list) { for (int value : list) { System.out.print(value + " "); } System.out.println(); } public static void main(String[] args) { // 初始化一个随机序列 final int MAX_SIZE = 10; int[] array = new int[MAX_SIZE]; Random random = new Random(); for (int i = 0; i < MAX_SIZE; i++) { array[i] = random.nextInt(MAX_SIZE); } // 调用冒泡排序方法 SelectionSort selection = new SelectionSort(); System.out.print("排序前: "); selection.printAll(array); selection.selectionSort(array); System.out.print("排序后: "); selection.printAll(array); }} 运行结果1234567891011排序前: 3 5 2 8 1 2 0 8 4 1 第 1 趟: 0 5 2 8 1 2 3 8 4 1 第 2 趟: 0 1 2 8 5 2 3 8 4 1 第 3 趟: 0 1 1 8 5 2 3 8 4 2 第 4 趟: 0 1 1 2 5 8 3 8 4 2 第 5 趟: 0 1 1 2 2 8 3 8 4 5 第 6 趟: 0 1 1 2 2 3 8 8 4 5 第 7 趟: 0 1 1 2 2 3 4 8 8 5 第 8 趟: 0 1 1 2 2 3 4 5 8 8 第 9 趟: 0 1 1 2 2 3 4 5 8 8 排序后: 0 1 1 2 2 3 4 5 8 8]]></content>
<categories>
<category>数据结构和算法</category>
<category>【排序算法】</category>
</categories>
<tags>
<tag>排序算法</tag>
</tags>
</entry>
<entry>
<title><![CDATA[排序算法(三)--插入排序]]></title>
<url>%2F2019%2F05%2F16%2F%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95%2F%E3%80%90%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95%E3%80%91%2F%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95%EF%BC%88%E4%B8%89%EF%BC%89-%E6%8F%92%E5%85%A5%E6%8E%92%E5%BA%8F%2F</url>
<content type="text"><![CDATA[算法概念将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。) 动画演示插入排序动画演示 参考代码 算法总结直接插入排序是一种最简单的插入排序。 插入排序:每一趟将一个待排序的记录,按照其关键字的大小插入到有序队列的合适位置里,知道全部插入完成。 在讲解直接插入排序之前,先让我们脑补一下我们打牌的过程。先拿一张5在手里,再摸到一张4,比5小,插到5前面,摸到一张6,嗯,比5大,插到5后面,摸到一张8,比6大,插到6后面,。。。最后一看,我靠,凑到全是同花顺,这下牛逼大了。以上的过程,其实就是典型的直接插入排序,每次将一个新数据插入到有序队列中的合适位置里。 算法步骤假设有一组无序序列 R0, R1, … , RN-1。(1) 我们先将这个序列中下标为 0 的元素视为元素个数为 1 的有序序列。(2) 然后,我们要依次把 R1, R2, … , RN-1 插入到这个有序序列中。所以,我们需要一个外部循环,从下标 1 扫描到 N-1 。(3) 接下来描述插入过程。假设这是要将 Ri 插入到前面有序的序列中。由前面所述,我们可知,插入Ri时,前 i-1 个数肯定已经是有序了。所以我们需要将Ri 和R0 ~ Ri-1 进行比较,确定要插入的合适位置。这就需要一个内部循环,我们一般是从后往前比较,即从下标 i-1 开始向 0 进行扫描。 核心代码 算法分析 算法性能 时间复杂度1.当数据正序时,执行效率最好,每次插入都不用移动前面的元素,时间复杂度为O(N)。2.当数据反序时,执行效率最差,每次插入都要前面的元素后移,时间复杂度为O(N2)。3.所以,数据越接近正序,直接插入排序的算法性能越好。 空间复杂度由直接插入排序算法可知,我们在排序过程中,需要一个临时变量存储要插入的值,所以空间复杂度为 1 。 算法稳定性直接插入排序的过程中,不需要改变相等数值元素的位置,所以它是稳定的算法。 代码实现 运行结果]]></content>
<categories>
<category>数据结构和算法</category>
<category>【排序算法】</category>
</categories>
<tags>
<tag>排序算法</tag>
</tags>
</entry>
<entry>
<title><![CDATA[十大排序(四)--希尔排序]]></title>
<url>%2F2019%2F05%2F16%2F%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95%2F%E3%80%90%E5%8D%81%E5%A4%A7%E6%8E%92%E5%BA%8F%E3%80%91%2F%E5%8D%81%E5%A4%A7%E6%8E%92%E5%BA%8F-%E5%9B%9B-%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F%2F</url>
<content type="text"><![CDATA[算法概念希尔(Shell)排序又称为缩小增量排序,它是一种插入排序。它是直接插入排序算法的一种威力加强版。 算法思想把记录按步长 gap 分组,对每组记录采用直接插入排序方法进行排序。随着步长逐渐减小,所分成的组包含的记录越来越多,当步长的值减小到 1 时,整个数据合成为一组,构成一组有序记录,则完成排序。我们来通过演示图,更深入的理解一下这个过程。 在上面这幅图中:初始时,有一个大小为 10 的无序序列。 在第一趟排序中,我们不妨设 gap1 = N / 2 = 5,即相隔距离为 5 的元素组成一组,可以分为 5 组。接下来,按照直接插入排序的方法对每个组进行排序。 在第二趟排序中,我们把上次的 gap 缩小一半,即 gap2 = gap1 / 2 = 2 (取整数)。这样每相隔距离为 2 的元素组成一组,可以分为 2 组。按照直接插入排序的方法对每个组进行排序。 在第三趟排序中,再次把 gap 缩小一半,即gap3 = gap2 / 2 = 1。 这样相隔距离为 1 的元素组成一组,即只有一组。按照直接插入排序的方法对每个组进行排序。此时,排序已经结束。 需要注意一下的是,图中有两个相等数值的元素 5 和 5 。我们可以清楚的看到,在排序过程中,两个元素位置交换了。所以,希尔排序是不稳定的算法。 核心代码 算法分析 算法性能 时间复杂度步长的选择是希尔排序的重要部分。只要最终步长为1任何步长序列都可以工作。 算法最开始以一定的步长进行排序。然后会继续以一定步长进行排序,最终算法以步长为1进行排序。当步长为1时,算法变为插入排序,这就保证了数据一定会被排序。 Donald Shell 最初建议步长选择为N/2并且对步长取半直到步长达到1。虽然这样取可以比O(N2)类的算法(插入排序)更好,但这样仍然有减少平均时间和最差时间的余地。可能希尔排序最重要的地方在于当用较小步长排序后,以前用的较大步长仍然是有序的。比如,如果一个数列以步长5进行了排序然后再以步长3进行排序,那么该数列不仅是以步长3有序,而且是以步长5有序。如果不是这样,那么算法在迭代过程中会打乱以前的顺序,那就不会以如此短的时间完成排序了。已知的最好步长序列是由Sedgewick提出的(1, 5, 19, 41, 109,…),该序列的项来自这两个算式。这项研究也表明“比较在希尔排序中是最主要的操作,而不是交换。”用这样步长序列的希尔排序比插入排序和堆排序都要快,甚至在小数组中比快速排序还快,但是在涉及大量数据时希尔排序还是比快速排序慢。 算法稳定性由上文的希尔排序算法演示图即可知,希尔排序中相等数据可能会交换位置,所以希尔排序是不稳定的算法。 直接插入排序和希尔排序的比较直接插入排序是稳定的;而希尔排序是不稳定的。直接插入排序更适合于原始记录基本有序的集合。希尔排序的比较次数和移动次数都要比直接插入排序少,当N越大时,效果越明显。在希尔排序中,增量序列gap的取法必须满足:最后一个步长必须是 1。直接插入排序也适用于链式存储结构;希尔排序不适用于链式结构。 代码实现范例代码中的初始序列和本文图示中的序列完全一致。 运行结果]]></content>
<categories>
<category>数据结构和算法</category>
<category>【十大排序】</category>
</categories>
<tags>
<tag>排序算法</tag>
</tags>
</entry>
<entry>
<title><![CDATA[排序算法(五)--归并排序]]></title>
<url>%2F2019%2F05%2F16%2F%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95%2F%E3%80%90%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95%E3%80%91%2F%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95-%E4%BA%94-%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F%2F</url>
<content type="text"><![CDATA[算法概念归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序的基本思想将待排序序列R[0…n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并,得到n/2个长度为2的有序表;将这些有序序列再次归并,得到n/4个长度为4的有序序列;如此反复进行下去,最后得到一个长度为n的有序序列。综上可知:归并排序其实要做两件事:(1)“分解”——将序列每次折半划分。(2)“合并”——将划分后的序列段两两合并后排序。我们先来考虑第二步,如何合并?在每次合并过程中,都是对两个有序的序列段进行合并,然后排序。这两个有序序列段分别为 R[low, mid] 和 R[mid+1, high]。先将他们合并到一个局部的暂存数组R2中,带合并完成后再将R2复制回R中。为了方便描述,我们称 R[low, mid] 第一段,R[mid+1, high] 为第二段。每次从两个段中取出一个记录进行关键字的比较,将较小者放入R2中。最后将各段中余下的部分直接复制到R2中。经过这样的过程,R2已经是一个有序的序列,再将其复制回R中,一次合并排序就完成了。 合并核心代码 掌握了合并的方法,接下来,让我们来了解 如何分解。 在某趟归并中,设各子表的长度为gap,则归并前R[0…n-1]中共有n/gap个有序的子表:R[0…gap-1], R[gap…2gap-1], … , R[(n/gap)gap … n-1]。调用Merge将相邻的子表归并时,必须对表的特殊情况进行特殊处理。若子表个数为奇数,则最后一个子表无须和其他子表归并(即本趟处理轮空):若子表个数为偶数,则要注意到最后一对子表中后一个子表区间的上限为n-1。 分解核心代码 算法分析 归并排序算法的性能 时间复杂度归并排序的形式就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的可以得出它的时间复杂度是O(n*log2n)。 空间复杂度由前面的算法说明可知,算法处理过程中,需要一个大小为n的临时存储空间用以保存合并序列。 算法稳定性在归并排序中,相等的元素的顺序不会改变,所以它是稳定的算法。 归并排序和堆排序、快速排序的比较若从空间复杂度来考虑:首选堆排序,其次是快速排序,最后是归并排序。若从稳定性来考虑,应选取归并排序,因为堆排序和快速排序都是不稳定的。若从平均情况下的排序速度考虑,应该选择快速排序。 完整代码 运行结果123456排序前 : 9 1 5 3 4 2 6 8 7 gap = 1: 1 9 3 5 2 4 6 8 7 gap = 2: 1 3 5 9 2 4 6 8 7 gap = 4: 1 2 3 4 5 6 8 9 7 gap = 8: 1 2 3 4 5 6 7 8 9 排序后: 1 2 3 4 5 6 7 8 9]]></content>
<categories>
<category>数据结构和算法</category>
<category>【排序算法】</category>
</categories>
<tags>
<tag>排序算法</tag>
</tags>
</entry>
<entry>
<title><![CDATA[排序算法(六)--快速排序]]></title>
<url>%2F2019%2F05%2F16%2F%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95%2F%E3%80%90%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95%E3%80%91%2F%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95-%E5%85%AD-%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F%2F</url>
<content type="text"><![CDATA[算法概念快速排序是一种交换排序,找准一个基值,定义两个指针分别进行移动,与基值进行相比交换,反复进行直到最后形成一个有序的数组。 基本思想通过一趟排序将要排序的数据分割成独立的两部分:分割点左边都是比它小的数,右边都是比它大的数。然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。详细的图解往往比大堆的文字更有说明力,所以直接上图: 上图中,演示了快速排序的处理过程:初始状态为一组无序的数组:2、4、5、1、3。经过以上操作步骤后,完成了第一次的排序,得到新的数组:1、2、5、4、3。新的数组中,以2为分割点,左边都是比2小的数,右边都是比2大的数。2左边的数组只有一个元素1,所以显然不用再排序,位置也被确定。(注:这种情况时,left指针和right指针显然是重合的。因此在代码中,我们可以通过设置判定条件left必须小于right,如果不满足,则不用排序了)。而对于2右边的数组5、4、3,设置left指向5,right指向3,开始继续重复图中的一、二、三、四步骤,对新的数组进行排序。 核心代码 算法分析 快速排序算法的性能 时间复杂度当数据有序时,以第一个关键字为基准分为两个子序列,前一个子序列为空,此时执行效率最差。而当数据随机分布时,以第一个关键字为基准分为两个子序列,两个子序列的元素个数接近相等,此时执行效率最好。所以,数据越随机分布时,快速排序性能越好;数据越接近有序,快速排序性能越差。 空间复杂度快速排序在每次分割的过程中,需要 1 个空间存储基准值。而快速排序的大概需要 Nlog2N次的分割处理,所以占用空间也是 Nlog2N 个。 算法稳定性在快速排序中,相等元素可能会因为分区而交换顺序,所以它是不稳定的算法。 完整参考代码 运行结果12345678数组排序前: 1 3 4 5 2 6 9 7 8 0 base = 1: 0 1 4 5 2 6 9 7 8 3 base = 4: 3 2 4 6 9 7 8 5 base = 3: 2 3 base = 6: 5 6 7 8 9 base = 7: 7 8 9 base = 8: 8 9 数组排序后: 0 1 2 3 4 5 6 7 8 9]]></content>
<categories>
<category>数据结构和算法</category>
<category>【排序算法】</category>
</categories>
<tags>
<tag>排序算法</tag>
</tags>
</entry>
<entry>
<title><![CDATA[MySQL基础笔记(2)-- SQL语言]]></title>
<url>%2F2019%2F05%2F14%2FJavaWeb%2F%E3%80%90MySQL%E6%95%B0%E6%8D%AE%E5%BA%93%E3%80%91%2Fmysql%E5%9F%BA%E7%A1%80%E7%AC%94%E8%AE%B0%EF%BC%882%EF%BC%89-sql%E8%AF%AD%E8%A8%80%2F</url>
<content type="text"><![CDATA[什么是SQL查询语言?SQL是Structured Quevy Language(结构化查询语言)的缩写。 SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言。在使用它时,只需要 发出“做什么”的命令,“怎么做”是不用使用者考虑的。 SQL数据类型1.常用的数据类型double:浮点型,例如double(5,2)表示最多5位,其中必须有2位小数,即最大值为999.99; char:固定长度字符串类型; char(10) 'abc' varchar:可变长度字符串类型;varchar(10) 'abc' text:字符串类型; blob:二进制类型; date:日期类型,格式为:yyyy-MM-dd; time:时间类型,格式为:hh:mm:ss datetime:日期时间类型 yyyy-MM-dd hh:mm:ss 在mysql中,字符串类型和日期类型都要用单引号括起来。 如’sql_study’、’2020-01-01’等 MySQL支持的数据类型大致可以分为三类1.数值类型 2.字符串类型 3.日期和时间类型 sql功能分类1.DDL: 数据定义语言DDL是用来定义数据库对象:创建库,表,列等。 创建数据库 create database 数据库名 character set utf8; 修改数据库 alter database 数据库名 charactor set gbk; 查看表的字段信息 DESC 表名; 查看表的创建细节 SHOW CREATE TABLE 表名; 修改表的字符集为gbk ALTER TABLE 表名 CHARACTER SET 字符集名称; 创建表 create table 表名(列名1 列的类型[约束],列名2 列的类型[约束]....); 修改表名 RENAME TABLE 原始表名 TO 要修改的表名; 修改一个表的字段类型 ALTER TABLE 表名 MODIFY 字段名 数据类型 修改表的列名 ALTER TABLE 表名 CHANGE 原始列名 新列名 数据类型; 删除表 DROP TABLE 表名; 添加一列 ALTER TABLE 表名 ADD 列名 数据类型; 删除一列 ALTER TABLE 表名 DROP 字段名; 2.DML:数据操作语言DML用来操作数据库表中的记录,即就是对数据库的数据进行增删改查的操作 ①查询操作 查询表中的所有数据 SELECT * FROM 表名; 查询表中的指定数据 SELECT * FROM 表名 where 条件; ②插入操作 单个数据插入 INSERT INTO 表名(列名1,列名2 ...)VALUE (列值1,列值2...); 批量数据插入 INSERT INTO 表名(列名1,列名2 ...)VALUES (列值1,列值2...),(列值1,列值2...); ③更新操作 更新记录 UPDATE 表名 SET 列名1=列值1,列名2=列值2 .... WHERE 列名=值; ④删除操作 删除记录 DELETE FROM 表名 【WHERE 列名=值】; (DELETE 删除表中的数据,表结构还在;删除后的数据可以找回) 删除所有记录 TRUNCATE TABLE 表名; (删除是把表直接DROP掉,然后再创建一个同样的新表。删除的数据不能找回) 3.DQL:数据查询语言DQL用来查询数据。数据库执行DQL语句不会对数据进行改变,而是让数据库发送结果集给客户端。 结果集:通过查询语句查询出来的数据以表的形式展示我们称这个表为虚拟结果集,并存放在内存中。查询返回 的结果集是一张虚拟表。 DQL包含模糊查询、条件查询、字段控制查询、排序、以及聚合函数的应用 4.DCL:数据控制语言DCL用来定义访问权限和安全级别。即对数据库事务(trasaction)的控制,包括事务的提交(commit),事务的回滚(rollback),以及权限的管理等。]]></content>
<categories>
<category>JavaWeb</category>
<category>【MySQL数据库】</category>
</categories>
<tags>
<tag>MySQL</tag>
</tags>
</entry>
<entry>
<title><![CDATA[MySQL基础笔记(1)-- 数据库的介绍]]></title>
<url>%2F2019%2F05%2F13%2FJavaWeb%2F%E3%80%90MySQL%E6%95%B0%E6%8D%AE%E5%BA%93%E3%80%91%2Fmysql%E5%9F%BA%E7%A1%80%E7%AC%94%E8%AE%B0%EF%BC%881%EF%BC%89-%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E4%BB%8B%E7%BB%8D%2F</url>
<content type="text"><![CDATA[什么是数据库?数据库是是按照数据结构来组织、存储和管理数据的仓库。我们一般说的数据库,就是指的DBMS: 数据库服务器(是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库,简称DBMS).常见的数据库有Oracle、MySQL、SQL Server等等. Oracle: 运行稳定,可移植性高,功能齐全,性能超群!适用于大型企业领域。MySQL:开源,体积小,速度快。适用于于中小型企业领域。SQL Server: 全面,效率高,界面友好,操作容易,但是不跨平台。适用于于中小型企业领域。 数据库系统的专业术语表 具有固定的列数,和任意的行数 数据库 数据库是一些关联表的集合 列 一个数据项 Field 字段 行 一条记录(row) 主键 主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。 外键 外键用于关联两个表 索引 使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。 类似于书籍的目录。 MySQL数据库1.MySql介绍 MySQL是一个关系型数据库管理系统,属于Oracle公司。MySQL是一种关联数据库管理系统,关联数据库将数据保 存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。Mysql是开源的,而且支持 大型的数据库。可以处理拥有上千万条记录的大型数据库。 MySQL使用标准的SQL数据语言形式。 Mysql可以允许于多个系统上,并且支持多种语言。这些编程语言包括C、C++、Python、Java等。 2.MySql安装 (下载地址 https://dev.mysql.com/downloads/mysql/)3.MySql的存储引擎① 什么是存储引擎 MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机 制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术,你能够获得额外的速度或 者功能,从而改善你的应用的整体功能。(不同的存储引擎性能是不一样的) ②什么是事务 是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 4.存储引擎分类MYISAM :它不支持事务,也不支持外键,尤其是访问速度快,对事务完整性没有要求或者以SELECT、INSERT为主的应 用基本都可以使用这个引擎来创建表。每个MyISAM在磁盘上存储成3个文件,其中文件名和表名都相同,但 是扩展名分别为:.frm(存储表定义)、MYD(MYData,存储数据)、MYI(MYIndex,存储索引) INNODB:InnoDB存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全。但是对比MyISAM的存储引擎,InnoDB写的 处理效率差一些并且会占用更多的磁盘空间以保留数据和索引。 MEMORY:memory使用存在内存中的内容来创建表。每个MEMORY表实际对应一个磁盘文件,格式是.frm。 MEMORY类型的表访问非常快,因为它到数据是放在内存中的,并且默认使用HASH索引,但是一旦服务器关闭, 表中的数据就会丢失,但表还会继续存在。 常用数据库命令1.Mysql数据库的分类 (1)系统数据库 information_schema 存储数据库对象信息如用户表信息,列信息,根除,字符,分区里面的内容我们不能动. performance_schema 存储数据库服务器性能参数信息 mysql 存储数据库用户权限信息 sys 通过这个库可以快速的了解系统的元数据信息(这个库是通过视图的形式把information_schema 和 performance_schema结合起来,查询出更加令人容易理解的数据 (2)用户数据库 用户自己创建的数据库,一个项目用一个数据库 2.Mysql数据库命令]]></content>
<categories>
<category>JavaWeb</category>
<category>【MySQL数据库】</category>
</categories>
<tags>
<tag>MySQL</tag>
</tags>
</entry>
<entry>
<title><![CDATA[SSM三大框架之---SpringMVC]]></title>
<url>%2F2019%2F05%2F12%2FWeb%E5%90%8E%E7%AB%AF%E6%8A%80%E6%9C%AF%2FSSM%E6%A1%86%E6%9E%B6-%E3%80%90SpringMVC%E5%AD%A6%E4%B9%A0%E3%80%91%2Fssm%E4%B8%89%E5%A4%A7%E6%A1%86%E6%9E%B6%E4%B9%8B-springmvc%2F</url>
<content type="text"><![CDATA[表现层框架SpringMVC1.SpringMVC程序开发的基本步骤:123456789101112131415161718192021221.准备好SpringMVC开发的jar包(8个) spring-aop.jar spring-beans.jar spring-context.jar spring-core.jar spring-expression.jar commons-logging.jar spring-web.jar 在Web应用开发过程中,用到Spring框架时所需的核心类库 spring-webmvc.jar Spring MVC框架相关的所有类。如国际化、标签、Theme、FreeMarker等相关类2.在web.xml中配置前置控制器DispatcherServlet,用于拦截与<url-pattern>相匹配的请求 3.开发前端请求页面(index.jsp) 4.开发请求处理类(controller):含注解@Controller、@RequestMapping()等5.在src目录下创建SpringMVC的配置文件:springmvc.xml <!-- 配置需要扫描的包 --> <context:component-scan base-package="com.YYcoder.controller"> </context:component-scan> <!-- 配置视图解析器:把请求处理类的返回值,加工成最终的视图路径--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/views/"></property><!--前缀--> <property name="suffix" value=".jsp"></property><!--后缀--> </bean>6.开发前端结果显示页面:result.jsp 2.SpringMVC的学习内容(主要是学会如何使用注解来实现操作) ①常见注解的使用(可以参考springMVC的文档学习) @RequestMapping 用来给方法绑定一个请求映射 @PathVariable 获取动态参数 @RequestParam 获取请求参数 @RequestHeader 获取请求中的“头信息” @CookieValue 可以给处理方法入参绑定某个Cookie值 ②处理模型数据:用户从视图页面(v)发起一个请求到控制器(c),控制器调用Service/Dao等处理数据, 并从数据库中返回数据(M)。之后控制器拿到数据后加以处理,并返回到视图页面。 实现方法: (1)ModelAndView:含Model和View两部分,数据将被放入request作用域 (2)ModelMap、Map及Model:不含view部分,可以方法的参数操作数据放入request作用域。 (3)@SessionAttribute:把数据放到session作用域 (4)@ModelAttribute:会在请求处理类中的每一个方法执行前都执行一次(谨用) ③视图、视图解析器(ViewResolver),以及对静态资源的处理 ④类型转换:将前端传来的数据类型转为请求处理方法参数中的所对应的类型 ⑤数据格式化、数据校验:让前端传入的数据按照一定格式、要求,否则报错。 ⑥文件上传、拦截器的使用。在springmvc.xml文件中配置: <mvc:interceptors> <!-- 配置自定义的拦截器 --> <bean class="org.lanqiao.interceptor.FirstInterceptor"></bean> </mvc:interceptors> ⑦异常处理:使用@ExceptionHandler注解用来捕获指定类型的异常。 ⑧SSM整合:Spring + springmvc + Mybatis Spring - Mybatis SqlSessionFactory - > SqlSession -> StduentMapper ->CRUD 整合: 将SqlSessionFactory在spring中配置 Spring - SpringMvc:spring springmvc各自配置一遍 步骤: 1.jar包 2.Student 类 --Student表 3.(省略)--MyBatis配置SqlMapConfig.xml(数据源、 mapper.xml) 在spring配置文件中 applicationContext.xml 4.通过mapper.xml将 类、表建立映射关系 5.web配置spring springmvc 6.spring 整合mybatis 扫描器 7.spring整合springmvc(视图解析器 标准配置) ui层:前端(jsp)--->通过注解调用 后端:SpringMvc(或Servlet) (controller控制器依赖于Service,即给controller注入service) Service层:StudentService.java StduentServiceImpl.java(依赖dao层,即给service注入mapper) <!-- 配置DAO层:为StudentDaoImpl注入SqlSessionFactory对象 --> <bean id="studentService" class="org.lanqiao.service.impl.StudentServiceImpl"> <property name="studentDao" ref="studentMapper"></property> </bean> <bean id="studentController" class="org.lanqiao.controller.stduentController"> <property name="studentService" ref="studentService"></property> </bean> dao层:studentMapper.java() StudentMapper.xml --->操作DB数据库 控制器 testController.java 业务逻辑层接口 testService.java 业务逻辑层实现类 testServiceImpl.java Web.xml中配置使用Spring和SpringMVC SpringMVC.xml配置扫描包、视图解析器和控制器Controller applicationContext.xml:配置数据库连接池、sqlSessionFactory、dao、service 编写test测试:jsp页面测试]]></content>
<categories>
<category>Web后端技术</category>
<category>SSM框架--【SpringMVC学习】</category>
</categories>
<tags>
<tag>框架学习</tag>
</tags>
</entry>
<entry>
<title><![CDATA[SSM三大框架之---Spring]]></title>
<url>%2F2019%2F05%2F12%2FWeb%E5%90%8E%E7%AB%AF%E6%8A%80%E6%9C%AF%2FSSM%E6%A1%86%E6%9E%B6-%E3%80%90Spring%E5%AD%A6%E4%B9%A0%E3%80%91%2Fssm%E4%B8%89%E5%A4%A7%E6%A1%86%E6%9E%B6%E4%B9%8B-spring%2F</url>
<content type="text"><![CDATA[业务层框架Spring1.Spring程序开发的基本步骤:123456789101112131415161718192021222324251.准备好Spring开发的jar包,至少需要: spring-aop.jar 使用Spring的AOP特性时所需的jar类库 spring-beans.jar 包含访问配置文件、创建和管理bean 以及进行IoC/DI操作相关的所有类 spring-context.jar 为Spring核心提供了大量扩展。例如,可以找到使用Spring ApplicationContext 特性时所需的全部类,JDNI所需的全部类,以及校验Validation方面等相关类. spring-core.jar Spring框架的核心类库,Spring各个组件要都要使用到这个包里的类 spring-expression.jar Spring表达式语言需要的类库 可以下载第三方提供的日志jar commons-logging.jar,打印日志 2.开发工具:Eclipse+插件Spring Tool Suite,或者直接下载STS工具3.创建实体类、配置文件(applicationContext.xml)、编写测试类Test <!-- 配置文件 applicationContext.xml,通过<bean>标签实现对象的赋值 --> <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="唯一标识符" class="包名+类名"> <!-- 配置属性: value 值 -> name 字段 --> <property name="属性" value="属性值"></property> <property name="属性名" ref="引用对象的id值"></property> </bean> </beans> 2.Spring的特点(获取对象不需要new,直接从IOC容器拿。前提是要在springIOC中存放对象并赋值)123456//1.创建Spring的IOC容器对象ApplicationContext context = new ClassPathXmlApplicationContext("applicatoinContext.xml");//2.从IOC容器中获取Bean实例(id为"student"的Student对象)//相当于 Student stu = new Student();Student stu =(Student)context.getBean("student");//继续操作 3.spring的学习内容12345678910111213141516171819202122232425262728293031323334353637383940414243444546 IOC(控制反转):将创建对象、属性值的方式进行了翻转,从new、setXxx()翻转为 从SpringIOC 容器getBean()获取。 DI(依赖注入):将属性值注入给属性,将属性注入给bean,将bean注入给IOC容器。 IOC容器赋值:基本类型 用 value=" "赋值;对象类型:ref =" 需要引用的对象的id值 ",实现对象与对象之间的依赖关系。 依赖注入的赋值方式: 1.setter注入((底层通过反射实现) 默认使用setter方法()给属性赋值 <property>标签 2.构造器注入:通过构造器注入 <constructor-arg>标签,其内部的属性赋值顺序需要和构造器参数的顺序一致; 如果不一致,则需要通过type、index或name指定顺序。 3.p命名空间注入:①引入命名空间:xmlns:p="http://www.springframework.org/schema/p" ②<bean>标签里面添加:简单类型(8大类型+String)(p:属性名="属性值") 引用类型(p:属性名-ref="引用对象的id") ③ 注入各种集合数据类型(List、Set、Map、properties) 都有各自对应的标签使用 List或Array 外层用<list>;内层用<value>或<ref> Set 外层用<set>;内层用<value>或<ref> Map 外层用<map>;中间层用<entry>;内层中键用<key><value>…</value></key>, 值用<value>…</value>或<ref>…</ref> Properties 外层用<props>;内层中键写在<prop key=”..”>..</prop>的key值中, 值写在<prop>..</prop>中间。Properties中的键和值通常都是字符串类型。 自动装配: 自动装配 (只适用于ref类型) Course类中有一个ref属性propertyName(属性名),并且ioc容器中也有一个bean为的id也ropertyName autowire="byName":自动寻找其他bean的id值 = 该Course的属性名 autowire="byType":寻找其他bean的类型(class) = 该Course类的ref属性类型(只能有一个满足要求,否则报错) autowire="constructor":寻找其他bean的类型(class) = 该Course类的构造方法参数(本质和byType一样) <bean id="Course" class="包名+类名" autowire="byName或者byType或constructor"> <property name="..." value="..."></property> <!-- <property name="..." ref="..."></property> --> </bean> 注:<beans xmlns="http://www.springframework.org/schema/beans" ... default-autowire="byName"> 可以一次性将该ioc容器中的所有bean统一设置成自动装配 注解定义bean:实体类添加注解,Spring在启动时,会根据base-package在改包中扫描所有类,查找这些类是否有注解。 如果有,则将该类加入spring ioc 容器。application.xml下添加: <context:component-scan base-package="实体类所在包名"></context:component-scan> 常见注解(@Component)分为: dao层注解(@Repository)、service层注解(@Service)、控制器注解(@Controller) AOP(面向切面编程):①前置通知 覆盖before()方法 目标方法执行前发生。 ②后置通知 覆盖afterReturning()方法 目标方法执行后发生 ③异常通知 无需覆盖方法 目标方法发生异常时执行 ④最终通知 目标方法执行完毕后,插入的通知(不论是正常返回还是异常退出)。 ④环绕通知 覆盖invoke()方法 拦截对目标方法调用,即调用目标方法的整个过程(功能最强大) Spring整合Mybatis:将Mybatis操作Dao层的权力交给Spring,Spring与其他什么框架整合的时候,权力全部 交由Spring掌控,Spring是老大。]]></content>
<categories>
<category>Web后端技术</category>
<category>SSM框架--【Spring学习】</category>
</categories>
<tags>
<tag>框架学习</tag>
</tags>
</entry>
<entry>
<title><![CDATA[SSM三大框架之---MyBatis]]></title>
<url>%2F2019%2F05%2F12%2FWeb%E5%90%8E%E7%AB%AF%E6%8A%80%E6%9C%AF%2FSSM%E6%A1%86%E6%9E%B6-%E3%80%90MyBatis%E5%AD%A6%E4%B9%A0%E3%80%91%2Fssm%E4%B8%89%E5%A4%A7%E6%A1%86%E6%9E%B6%E4%B9%8B-mybatis%2F</url>
<content type="text"><![CDATA[持久层框架Mybatis1.MyBatis的基本步骤: 12341.mybatis.jar、mysql.jar(数据库连接包);2.conf.xml(数据库配置信息、映射文件)3.表-类:相对应的实体类(属性) 映射关系文件mapper.xml,mapper.java(包含方法的接口)4.编写测试类TestDemo 2.MyBatis的调用实现过程:123456789String resource = "conf.xml";// 加载mybatis 的配置文件Reader reader = Resources.getResourceAsReader(resource);// 创建sqlSession 的工厂(由XML配置文件(conf.xml)创建SqlSessionFactory)SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);// 通过SqlSessionFactory创建能够执行SQL映射文件中sql语句的sqlSession对象SqlSession session = sessionFactory.openSession(); //SqlSession对象包含了执行SQL所需要的所有方法,可以直接运行映射的SQL语句,完成对数据的增删改查等操作。 seesion.方法(); 3.MyBatis的学习内容1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374属性文件(db.properties) 全局参数:<settings></settings>里面的子标签设置 别名定义:不需要通过全类名的形式(即“包名+类名”),直接用包名访问 1.单个别名 <typeAliases> <typeAlias type="实体类的对象类型" alias="别名"/> </typeAliases> 2.批量别名(包名下所有实体类都自动定义了别名) <typeAliases> <package name="包名"/> </typeAliases> 类型转换器:java类型与jdbc类型之间的映射(类型对应不上),如javaType="java.lang.Boolean" jdbcType="INTEGER",这时需自定义类型处理器,通过实现TypeHandler接口(或继承 BaseTypeHandler抽象类)取值符号: 1.#{参数},可以防止SQL注入,并且会为传入String类型的参数值自动加上引号(参数名任意), 但如果查询语句中传入一个int类型的值,则“#{参数}”不会为其加引号。 2.${value},来获取输入的参数值.这种方式不能防止SQL注意,有很大的安全隐患。 而且不会为字符串类型的值加上引号(需手动"),主要用于动态排序(order by). 输入参数(parameterType):1.简单类型(8钟基本类型+String),输入参数名可任意 2.实体类的对象,要确保${}或#{}中的参数名必须是实体类的属性名。 3.嵌套对象,A对象包含B对象的属性,可以#{}或${}来获取传入的A对象的嵌套属性. 参数一般为A.B对象属性名。 4.HashMap:通过${}或#{}获取key对应的value值。输出参数:1.简单类型,resultType=" 简单类型 " 2.HashMap。resultType="HashMap" 3.resultMap.(用于处理字段名与属性名不一致) <select>元素中用resultMap的属性值匹配<resultMap> 元素的id值;然后在<resultMap>元素中用type指定相应<select>元素的返回值;并通过<result>子元素 的column指定字段名、property指定与字段名相对应的属性名,从而将字段名和属性名一一对应起来。 <result>元素用来指定普通字段,<id>元素用来指定主键字段。 注:亦可取通过别名形式字段名 "属性名(字段名的别名)")处理字段名与属性名不一致的问题 动态SQL:MyBatis提供了<if>、<where>、<foreach>等标签来实现SQL语句的动态拼接。 关联查询:1.一对一 ① 业务扩展类(包含所要查询的表的所有属性) ② 使用resultMap实现一对一查询。表与表的外键在实体类使用成员变量表示在mapper.xml通过 <association>将属性与字段绑定起来 javaType="类型" 2.一对多(多对一,多对多) 将查询的结果放在一个集合中<collection>标签进行字段与属性绑定 oftype="集合中的类型" 日志输出:配置过程(导入log4j.jar) ① conf.xml文件配置 <configuration> <properties resource="db.properties" /> <settings> <setting name="logImpl" value="LOG4J"/> </settings> </configuration> ② 编写log4j.properties log4j.rootLogger=DEBUG, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n 延迟加载:根据需要延迟信息的加载,如一对多情况下,只想查看一的那部分,多的那部分延迟加载。配置加载方式: <settings> <!-- 将延迟加载设置为:true (可省,因为默认值就是true)--> <setting name="lazyLoadingEnabled" value="true"/> <!-- 将立即加载设置为:false --> <setting name="aggressiveLazyLoading" value="false"/> </settings>缓存:一级缓存:同一个SqlSession对象共享。 第一次执行完查询时,向数据库发送语句,并将数据库的查询结果放入SQLSESSION内存(作为缓存),以后如果 再次执行该相同的查询SQL语句时,就会直接从内存中读取查询结果。 二级缓存:多个SqlSession对象共享的,范围是同一个namespace下SQL映射文件生成的动态代理mapper对象 *注:如果执行了增删改所需的commit()方法,那么SqlSession对象的一级缓存就会被清理(即将缓存中的数据 全部写入数据库,缓存变空)*逆向工程:在MyBatis的开发过程中,数据库表、实体类、SQL映射文件以及动态代理接口四者之间有着非常密切的关系。 只要根据一个,其余三个都能自动生成(依靠下载mybatis-generator-core-1.4.2-bundle.zip)。]]></content>
<categories>
<category>Web后端技术</category>
<category>SSM框架--【MyBatis学习】</category>
</categories>
<tags>
<tag>框架学习</tag>
</tags>
</entry>
<entry>
<title><![CDATA[滑动窗口的最大值]]></title>
<url>%2F2019%2F04%2F23%2F%E5%88%B7%E9%A2%98%2Fnewcoder%2F%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E7%9A%84%E6%9C%80%E5%A4%A7%E5%80%BC%2F</url>
<content type="text"><![CDATA[题目描述 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。 题解 建立两个指针pLow(初始指向下标为0的位置),pHigh(指向size-1的地方)。以 pHigh < num.length作为循环的条件,依次在list中add滑动窗口的最大值,然后使pLow++,pHigh++,直到循环推出。 代码123456789101112131415161718192021222324import java.util.ArrayList;public class WindowMove { public ArrayList<Integer> maxInWindows(int[] num, int size) { ArrayList<Integer> list = new ArrayList<Integer>(); if (num == null || size < 0) return null; if (size == 0) { return list; } int pLow = 0; int pHigh = pLow + size - 1; while (pHigh < num.length) { int max = 0; for (int i = pLow; i <= pHigh; i++) { if (max < num[i]) max = num[i]; } list.add(max); pLow++; pHigh++; } return list; }}]]></content>
<categories>
<category>刷题</category>
<category>newcoder</category>
</categories>
<tags>
<tag>nowcoder</tag>
</tags>
</entry>
<entry>
<title><![CDATA[确定字符有无重复]]></title>
<url>%2F2019%2F04%2F23%2F%E5%88%B7%E9%A2%98%2F%E7%A1%AE%E5%AE%9A%E5%AD%97%E7%AC%A6%E6%9C%89%E6%97%A0%E9%87%8D%E5%A4%8D%2F</url>
<content type="text"><![CDATA[题目描述 请实现一个算法,确定一个字符串的所有字符是否全都不同。给定一个string iniString,请返回一个bool值,True代表所有字符全都不同,False代表存在相同的字符。 代码12345678910111213141516171819202122import java.util.*;public class Different { public boolean checkDifferent(String iniString) { LinkedHashMap<Character, Integer> map = new LinkedHashMap<Character, Integer>(); char[] ch = iniString.toCharArray(); for (int i = 0; i < ch.length; i++) { if (map.containsKey(ch[i])) { int time = map.get(ch[i]); map.put(ch[i], ++time); } else map.put(ch[i], 1); } for (int i = 0; i < ch.length; i++) { if (map.get(ch[i]) > 1) return false; } return true; }}]]></content>
<categories>
<category>刷题</category>
</categories>
<tags>
<tag>nowcoder</tag>
</tags>
</entry>
</search>