Django之web本质
Django之web本质
Web的本质,是基于socket玩的。
在我们上网的过程中,一个访问请求是如何工作的。
Web的框架:
网络的连接都是基于Socket
在连接中有TCP/UDP 和HTTP协议
HTTP协议是:无状态,短连接。(HTTP协议的访问状态是发送请求连接一次,返回请求结果数据一次,就断开连接)
无状态体现在同样的请求者第二次发请求来,服务端不认识它。
TCP:不断开,安全,不丢包,慢
UDP:易丢包,快
Web的工作流程:
浏览器端(Socket客户端)
2、域名或DNS正反解析出的IP,在浏览器中输入。
在socket端创建Socket对象
Socket.socket()
在创建连接
Socket.connet(("IP",端口))
在发送连接请求
socket.send("我想请求数据") 5、接收响应的数据
6、连接断开,完成一个HTTP请求
网站服务端(Socket服务端)
1、监听自己网站的IP和域名,while 循环监听
while True:
等待用户连接
3、接收用户的连接请求("我想请求数据")
4、响应用户的连接,给用户返回响应的数据("好")
断开连接,等待下一个用户的连接请求
socket的服务端:
web的最本质最基本简化的流程。
import socket Socket = socket.socket()
# 创建Socket对象 Socket.bind(("127.0.0.1",8080))
# 绑定IP和端口 Socket.listen(5)
# 监听等待5个连接 while True:
conn, addr = Socket.accept()
# 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据 data = conn.recv(8096)
# 获取数据 print(data)
# 打印一下data的获取数据的结果 conn.send(b'HTTP/1.1 200 OK \r\n\r\n')
# 响应头 conn.send(b'')
# 响应的返回数据,响应体 conn.close()
# 断开连接
HTTP协议:发送的数据和响应的数据是有相互的规则的,规则遵循HTTP协议。
发送(Request):
GET请求:
GET请求头:
数据在请求头的url中。在GET / /HTTP1.1 的第一个/后,也就是请求体(请求体Request Bodys) GET / HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36
HTTPS: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Cookie: csrftoken=hNmu2JOtntGMN0hSRSPmMQk2newEb3o8zb6pXW5Cc3m54IaA5VlTkUvqWsFezpni 请求体部分
GET请求体:数据在url中。
GET的请求体在GET / HTTP/1.1中的第一个 "/" 后。
例如:
GET /index?p=123 HTTP/1.1
其中,index是url,这没错,but,p=123就是请求体。
POST请求:
POST请求头:
POST /index HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36
HTTPS: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Cookie: csrftoken=hNmu2JOtntGMN0hSRSPmMQk2newEb3o8zb6pXW5Cc3m54IaA5VlTkUvqWsFezpni 请求体部分
POST请求体:
POST /index HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36
HTTPS: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Cookie: csrftoken=hNmu2JOtntGMN0hSRSPmMQk2newEb3o8zb6pXW5Cc3m54IaA5VlTkUvqWsFezpni p=123 #POST请求体内容
响应(Response):
响应头:
在响应体中,要注意一个Status Code的状态码,应为200 OK 响应头是在Response Headers中。 响应头的数据:
Cache-Control:public, max-age=15
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/html; charset=utf-8
Date:Wed, 14 Jun 2017 01:21:17 GMT
Expires:Wed, 14 Jun 2017 01:21:33 GMT
Last-Modified:Wed, 14 Jun 2017 01:21:03 GMT
Transfer-Encoding:chunked
Vary:Accept-Encoding
X-Frame-Options:SAMEORIGIN
X-UA-Compatible:IE=10
响应体:就是看到的前端页面,页面效果是浏览器解析的而已的啦。
优化socket服务端流程,丰富功能:MK2
分化url,不同的url,显示不同的内容。
import socket Socket = socket.socket()
# 创建Socket对象
Socket.bind(("127.0.0.1",8080))
# 绑定IP和端口
Socket.listen(5)
# 监听的次数
while True:
#监听循环
conn, addr = Socket.accept()
# 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据
data = conn.recv(8096)
# 获取数据
print(data)
#打印拿到的请求数据
data = str(data,encoding="utf-8")
#将data的数据类型,由byte类型转换成str类型。并编码为utf-8。
Headers,Bodys = data.split("\r\n\r\n")
#将data数据用split以"\r\n\r\n"分割成请求头和请求体
temp_list = Headers.split("\r\n")
#将请求头以“\r\n”分割,并且可以单独处理 [0] 的GET第一行,因为第一条的写法不同
method,url,protocal = temp_list[0].split(" ")
#将temp_list的 [0] 的内容分给请求方式,url和协议,以空格分开。url是请求的url
conn.send(b'HTTP/1.1 200 OK \r\n\r\n')
# 响应头
if url == "/XXX":
conn.send(b"asfafafas")
elif url == "/BBB":
conn.send(b"qqqqqq")
else:
conn.send(b"404 not found")
conn.close()
在获取的用户数据后,转换成数据类型,比如字符串,操作如下:
data拿到的一般都是字节byte类型的数据
data = str(data,encoding = "utf-8")
即可将byte的数据类型,直接转换成字符串str的数据类型。
在拿取请求头是,是根据\r\n 来分割开请求头和请求体的。
headers,bodys = data.split("\r\n\r\n")
#这样可以将请求头和请求体分来。 #在请求头中在进行分割:
headers.split("\r\n")
对请求头再进一步的分割,可以将headers放在列表里,进行操作。这个的url是请求的url
temp_list = Headers.split("\r\n")
#将Headers放进列表 #在对请求头的第一行数据进行单独的操作,因为第一行数据不同。
#GET / /HTTP1.1\n
#定义GET为method,/后的请求体为url,是请求的url,/HTTP是协议protocal
method,url,protocal = temp_list[0].split(" ")
#根据空格分割。
MK3,将url抽离出,可单独操作每一个url。
# Socket服务端
import socket def index(request):
return b'index' def func2(request):
return b'func2' # 定义一个列表,里面存有url和url对应的函数名
Routers = [
("/index",index), #url 为XXX时,执行func1函数
("/SSS",func2), #url 为SSS时,执行func2函数
] def run():
"""
Socket服务端响应
:return:
"""
Socket = socket.socket()
# 创建Socket对象
Socket.bind(("127.0.0.1",8080))
# 绑定IP和端口
Socket.listen(5)
# 监听的次数
while True:
#监听循环
conn, addr = Socket.accept()
# 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据
data = conn.recv(8096)
# 获取数据
print(data)
#打印拿到的请求数据
data = str(data,encoding="utf-8")
#将data的数据类型,由byte类型转换成str类型。并编码为utf-8。
Headers,Bodys = data.split("\r\n\r\n")
#将data数据用split以"\r\n\r\n"分割成请求头和请求体
temp_list = Headers.split("\r\n")
#将请求头以“\r\n”分割,并且可以单独处理 [0] 的GET第一行,因为第一条的写法不同
method,url,protocal = temp_list[0].split(" ")
#将temp_list的 [0] 的内容分给请求方式,url和协议,以空格分开。url是请求的url
conn.send(b'HTTP/1.1 200 OK \r\n\r\n')
# 响应头
func_name = None
#定义一个func_name,用于赋值item的func函数
for item in Routers:
#循环遍历Routers列表里的url。
if item[0] == url:
#取出url进行判断
func_name = item[1]
#如果匹配到func指定的函数
break
if func_name:
#如果func_name=True,存在,就拿func_name 的值
response = func_name(data)
else:
response = b"404 Not Found"
conn.send(response)
#发送Response的值给作为响应体
conn.close() if __name__ == "__main__":
run()
结果:
--->--->
MK4 优化函数的功能,丰富页面的内容:静态网站
index页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<h1>Login</h1>
<form>
<p><input type="text" placeholder="Username"></p>
<p><input type="password" placeholder="Password"></p>
</form>
</body>
</html>
func2页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>article</title>
</head>
<body>
<table border='1'>
<thead>
<tr>
<th>ID</th>
<th>Username</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<th>0001</th>
<th>George</th>
<th>George@G.com</th>
</tr>
</tbody>
</table>
</body>
</html>
socket端代码:
# Socket服务端
import socket def index(request):
"""
处理用户请求,并返回响应数据
:param request: 用户请求的所有信息
:return:
"""
f = open("index.html","rb")
data = f.read()
f.close()
return data def func2(request):
"""
处理用户请求,并返回响应数据
:param request: 用户请求的所有信息
:return:
"""
f = open("article.html","rb")
data = f.read()
f.close()
return data # 定义一个列表,里面存有url和url对应的函数名
Routers = [
("/index",index), #url 为XXX时,执行func1函数
("/SSS",func2), #url 为SSS时,执行func2函数
] def run():
"""
Socket服务端响应
:return:
"""
Socket = socket.socket()
# 创建Socket对象
Socket.bind(("127.0.0.1",8080))
# 绑定IP和端口
Socket.listen(5)
# 监听的次数
while True:
#监听循环
conn, addr = Socket.accept()
# 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据
data = conn.recv(8096)
# 获取数据
print(data)
#打印拿到的请求数据
data = str(data,encoding="utf-8")
#将data的数据类型,由byte类型转换成str类型。并编码为utf-8。
Headers,Bodys = data.split("\r\n\r\n")
#将data数据用split以"\r\n\r\n"分割成请求头和请求体
temp_list = Headers.split("\r\n")
#将请求头以“\r\n”分割,并且可以单独处理 [0] 的GET第一行,因为第一条的写法不同
method,url,protocal = temp_list[0].split(" ")
#将temp_list的 [0] 的内容分给请求方式,url和协议,以空格分开。url是请求的url
conn.send(b'HTTP/1.1 200 OK \r\n\r\n')
# 响应头
func_name = None
#定义一个func_name,用于赋值item的func函数
for item in Routers:
#循环遍历Routers列表里的url。
if item[0] == url:
#取出url进行判断
func_name = item[1]
#如果匹配到func指定的函数
break
if func_name:
#如果func_name=True,存在,就拿func_name 的值
response = func_name(data)
else:
response = b"404 Not Found"
conn.send(response)
#发送Response的值给作为响应体
conn.close() if __name__ == "__main__":
run()
结果:
---》-->
MK5 静态变动态。简单动态。
以func2函数演示,获取系统时间,以实现动态效果。
socket端,重点在func2函数:
# Socket服务端
import socket def index(request):
"""
处理用户请求,并返回响应数据
:param request: 用户请求的所有信息
:return:
"""
f = open("index.html","rb")
data = f.read()
f.close()
return data def func2(request):
"""
处理用户请求,并返回响应数据
:param request: 用户请求的所有信息
:return:
"""
f = open("article.html","r")
data = f.read()
f.close()
import time
#导入时间模块
ctime = time.time()
#获取当期时间
data = data.replace("@@sw@@",str(ctime))
#将当期时间与前端的标签位进行替换
return bytes(data,encoding="utf-8") # 定义一个列表,里面存有url和url对应的函数名
Routers = [
("/index",index), #url 为XXX时,执行func1函数
("/SSS",func2), #url 为SSS时,执行func2函数
] def run():
"""
Socket服务端响应
:return:
"""
Socket = socket.socket()
# 创建Socket对象
Socket.bind(("127.0.0.1",8080))
# 绑定IP和端口
Socket.listen(5)
# 监听的次数
while True:
#监听循环
conn, addr = Socket.accept()
# 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据
data = conn.recv(8096)
# 获取数据
print(data)
#打印拿到的请求数据
data = str(data,encoding="utf-8")
#将data的数据类型,由byte类型转换成str类型。并编码为utf-8。
Headers,Bodys = data.split("\r\n\r\n")
#将data数据用split以"\r\n\r\n"分割成请求头和请求体
temp_list = Headers.split("\r\n")
#将请求头以“\r\n”分割,并且可以单独处理 [0] 的GET第一行,因为第一条的写法不同
method,url,protocal = temp_list[0].split(" ")
#将temp_list的 [0] 的内容分给请求方式,url和协议,以空格分开。url是请求的url
conn.send(b'HTTP/1.1 200 OK \r\n\r\n')
# 响应头
func_name = None
#定义一个func_name,用于赋值item的func函数
for item in Routers:
#循环遍历Routers列表里的url。
if item[0] == url:
#取出url进行判断
func_name = item[1]
#如果匹配到func指定的函数
break
if func_name:
#如果func_name=True,存在,就拿func_name 的值
response = func_name(data)
else:
response = b"404 Not Found"
conn.send(response)
#发送Response的值给作为响应体
conn.close() if __name__ == "__main__":
run()
func2的页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>article</title>
</head>
<body>
<table border="">
<thead>
<tr>
<th>ID</th>
<th>Username</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<th>0001</th>
<th>@@sw@@</th>
<th>George@G.com</th>
</tr>
</tbody>
</table>
</body>
</html>
结果:
MK6,动态获取数据改为数据库获取。
重点在func3函数,要链接数据库。
socket端:
# Socket服务端
import socket def index(request):
"""
处理用户请求,并返回响应数据
:param request: 用户请求的所有信息
:return:
"""
f = open("index.html","rb")
data = f.read()
f.close()
return data def func2(request):
"""
处理用户请求,并返回响应数据
:param request: 用户请求的所有信息
:return:
"""
f = open("article.html","r")
data = f.read()
f.close()
import time
#导入时间模块
ctime = time.time()
#获取当期时间
data = data.replace("@@sw@@",str(ctime))
#将当期时间与前端的标签位进行替换
return bytes(data,encoding="utf-8") def func3(request):
"""
处理用户请求,并返回响应数据
:param request: 用户请求的所有信息
:return:
"""
import pymysql
conn = pymysql.connect(host = '127.0.0.1',port=3306,user="root",password="密码",db="数据库名")
#创建连接
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
#创建游标
effect_row = cursor.execute("select id,name,password from user")
#执行SQL语句,并返回结果
userlist = cursor.fetchall()
#拿到的所有数据
cursor.close()
#关闭游标
conn.close()
#关闭连接
print(userlist)
#打印user_list字典
"""
将user_list拼接成如下的字符串,将字典的每一个值对应发给每一个标签
[
{id,name,password}
{id,...}
{id,...}
] <tr>
<td>%s</td> #id
<td>%s</td> #name
<td>%s</td> #password
</tr>
"""
content_list = []
for row in userlist:
#每一个row都是一行数据
tp = '<tr><td>%s</td><td>%s</td><td>%s</td></tr>' %(row['id'],row['name'],row['password'])
#字符串拼接
content_list.append(tp)
content = "".join(content_list)
f = open("user_list.html", "r",encoding='utf-8')
template = f.read()
f.close()
#模块的渲染,
data = template.replace('@@XXXXX@@',content)
return bytes(data, encoding="utf-8") # 定义一个列表,里面存有url和url对应的函数名
Routers = [
("/index",index), #url 为XXX时,执行func1函数
("/SSS",func2), #url 为SSS时,执行func2函数
("/hhh",func3), #url 为hhh时,执行func3函数
] def run():
"""
Socket服务端响应
:return:
"""
Socket = socket.socket()
# 创建Socket对象
Socket.bind(("127.0.0.1",8080))
# 绑定IP和端口
Socket.listen(5)
# 监听的次数
while True:
#监听循环
conn, addr = Socket.accept()
# 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据
data = conn.recv(8096)
# 获取数据
print(data)
#打印拿到的请求数据
data = str(data,encoding="utf-8")
#将data的数据类型,由byte类型转换成str类型。并编码为utf-8。
Headers,Bodys = data.split("\r\n\r\n")
#将data数据用split以"\r\n\r\n"分割成请求头和请求体
temp_list = Headers.split("\r\n")
#将请求头以“\r\n”分割,并且可以单独处理 [0] 的GET第一行,因为第一条的写法不同
method,url,protocal = temp_list[0].split(" ")
#将temp_list的 [0] 的内容分给请求方式,url和协议,以空格分开。url是请求的url
conn.send(b'HTTP/1.1 200 OK \r\n\r\n')
# 响应头
func_name = None
#定义一个func_name,用于赋值item的func函数
for item in Routers:
#循环遍历Routers列表里的url。
if item[0] == url:
#取出url进行判断
func_name = item[1]
#如果匹配到func指定的函数
break
if func_name:
#如果func_name=True,存在,就拿func_name 的值
response = func_name(data)
else:
response = b"404 Not Found"
conn.send(response)
#发送Response的值给作为响应体
conn.close() if __name__ == "__main__":
run()
use_list.html 函数3的页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>user_list</title>
</head>
<body>
<table border="">
<thead>
<tr>
<th>ID</th>
<th>Username</th>
<th>Email</th>
</tr>
</thead>
<tbody>
@@XXXXX@@
</tbody>
</table>
</body>
</html>
结果: 更改数据库name栏数据,图中username栏的数据会跟随变化。
MK7 优化函数func3中处理的繁琐字符串 :做模板渲染的 jinja2 模块。
重点func4函数:
func4函数的页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>func4</title>
</head>
<body>
<table border="">
<thead>
<tr>
<th>ID</th>
<th>用户名</th>
<th>邮箱</th>
</tr>
</thead>
<tbody>
{% for row in xxxxx %}
<tr>
<td>{{row.id}}</td>
<td>{{row.name}}</td>
<td>{{row.password}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{user}}
</body>
</html>
socket端:
# Socket服务端
import socket def index(request):
"""
处理用户请求,并返回响应数据
:param request: 用户请求的所有信息
:return:
"""
f = open("index.html","rb")
data = f.read()
f.close()
return data def func2(request):
"""
处理用户请求,并返回响应数据
:param request: 用户请求的所有信息
:return:
"""
f = open("article.html","r")
data = f.read()
f.close()
import time
#导入时间模块
ctime = time.time()
#获取当期时间
data = data.replace("@@sw@@",str(ctime))
#将当期时间与前端的标签位进行替换
return bytes(data,encoding="utf-8") def func3(request):
"""
处理用户请求,并返回响应数据
:param request: 用户请求的所有信息
:return:
"""
import pymysql
conn = pymysql.connect(host = '127.0.0.1',port=3306,user="root",password="密码",db="数据库名")
#创建连接
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
#创建游标
effect_row = cursor.execute("select id,name,password from user")
#执行SQL语句,并返回结果
userlist = cursor.fetchall()
#拿到的所有数据
cursor.close()
#关闭游标
conn.close()
#关闭连接
print(userlist)
#打印user_list字典
"""
将user_list拼接成如下的字符串,将字典的每一个值对应发给每一个标签
[
{id,name,password}
{id,...}
{id,...}
] <tr>
<td>%s</td> #id
<td>%s</td> #name
<td>%s</td> #password
</tr>
"""
content_list = []
for row in userlist:
#每一个row都是一行数据
tp = '<tr><td>%s</td><td>%s</td><td>%s</td></tr>' %(row['id'],row['name'],row['password'])
#字符串拼接
content_list.append(tp)
content = "".join(content_list)
f = open("user_list.html", "r",encoding='utf-8')
template = f.read()
f.close()
#模块的渲染,
data = template.replace('@@XXXXX@@',content)
return bytes(data, encoding="utf-8") def func4(request):
"""
处理用户请求,并返回响应数据
:param request: 用户请求的所有信息
:return:
"""
import pymysql
conn = pymysql.connect(host='127.0.0.1', port=3306, user="root", password="redhat", db="GeorgeTest")
# 创建连接
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 创建游标
effect_row = cursor.execute("select id,name,password from user")
# 执行SQL语句,并返回结果
userlist = cursor.fetchall()
# 拿到的所有数据
cursor.close()
# 关闭游标
conn.close()
# 关闭连接
f = open('func4.html','r',encoding='utf-8')
data = f.read()
f.close() # 基于第三方工具实现的模板渲染
from jinja2 import Template
template = Template(data)
data = template.render(xxxxx=userlist,name='fadfasdfa')
return data.encode('utf-8') # 定义一个列表,里面存有url和url对应的函数名
Routers = [
("/index",index), #url 为XXX时,执行func1函数
("/SSS",func2), #url 为SSS时,执行func2函数
("/hhh",func3), #url 为hhh时,执行func3函数
("/func4",func4), #url 为func4时,执行func4函数
] def run():
"""
Socket服务端响应
:return:
"""
Socket = socket.socket()
# 创建Socket对象
Socket.bind(("127.0.0.1",8080))
# 绑定IP和端口
Socket.listen(5)
# 监听的次数
while True:
#监听循环
conn, addr = Socket.accept()
# 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据
data = conn.recv(8096)
# 获取数据
print(data)
#打印拿到的请求数据
data = str(data,encoding="utf-8")
#将data的数据类型,由byte类型转换成str类型。并编码为utf-8。
Headers,Bodys = data.split("\r\n\r\n")
#将data数据用split以"\r\n\r\n"分割成请求头和请求体
temp_list = Headers.split("\r\n")
#将请求头以“\r\n”分割,并且可以单独处理 [0] 的GET第一行,因为第一条的写法不同
method,url,protocal = temp_list[0].split(" ")
#将temp_list的 [0] 的内容分给请求方式,url和协议,以空格分开。url是请求的url
conn.send(b'HTTP/1.1 200 OK \r\n\r\n')
# 响应头
func_name = None
#定义一个func_name,用于赋值item的func函数
for item in Routers:
#循环遍历Routers列表里的url。
if item[0] == url:
#取出url进行判断
func_name = item[1]
#如果匹配到func指定的函数
break
if func_name:
#如果func_name=True,存在,就拿func_name 的值
response = func_name(data)
else:
response = b"404 Not Found"
conn.send(response)
#发送Response的值给作为响应体
conn.close() if __name__ == "__main__":
run()
结果:
------ END ------
最新文章
- Skyfree的毕业论文 《系统封装与部署的深入研究》
- log4j - 配置文件
- trap在shell中捕捉信号
- oracle 查看隐含参数脚本
- PHP 判断客户端请求是 Android 还是 IOS
- iOS学习之自动布局
- 【转】Android 源码编译make的错误处理--不错
- [置顶] 顿悟JAVA,自己实现Object的Clone的约束关系(上)
- nginx命令启动及选项
- Solr在Linux中的安装
- windbg 如何再内核模式调试用户空间的程序
- How to set up github to work with Visual Studio 2013
- 恶意软件正在利用SSLserver窃取用户个人信息!
- Spring Bean 的加载顺序
- MySQL库和表的管理
- python socket编程函数介绍
- 51nod 1183 编辑距离
- HDU 5887 Herbs Gathering(搜索求01背包)
- CF1083B The Fair Nut and String
- 行为事件(ActionChains)源码详解
热门文章
- 前端开发常用cmd命令
- Redis的高级特性哨兵
- autolayout UIImageView 根据 UILabel的宽度变换位置
- Spring 2.5
- loj125 除数函数求和 2
- DP+埃氏筛法 Codeforces Round #304 (Div. 2) D. Soldier and Number Game
- adb shell报错:error: insufficient permissions for device的解决办法
- JSP九大内置对象的作用和用法总结【转】
- springmvc、springboot静态资源访问配置
- this的试题