面向对象&网络编程
1 接口与归一化设计
1.1 归一化概念:
归一化的好处:
1.归一化让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了,这极大降低了使用者的使用难度。
2.归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合
继承的两种用途
一:继承基类的方法,并且做出自己改变或者扩展(代码重用):实践中,继承的这种用途意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。
二:声明某个子类兼容于某基类,定义一个接口类(模仿java的Interface),接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能

class Interface:
'''
定义接口Interface类来模仿接口的概念,
python中压根就没有interface关键字来定义一个接口。
'''
def read(self): # 定接口函数read
pass def write(self): # 定义接口函数write
pass class Txt(Interface): # 文本,具体实现read和write
def read(self):
print('文本数据的读取方法') def write(self):
print('文本数据的读取方法') class Sata(Interface): #磁盘,具体实现read和write
def read(self):
print('硬盘数据的读取方法') def write(self):
print('硬盘数据的读取方法') class Process(Interface):
def read(self):
print('进程数据的读取方法') def write(self):
print('进程数据的读取方法') t = Txt()
s = Sata()
p = Process() t.read() # 运行结果:文本数据的读取方法
s.read() # 运行结果:硬盘数据的读取方法
p.read() # 运行结果:进程数据的读取方法

1.2 抽象类
了解知识点
与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化
借助abc模块,进行模拟抽象类

import abc
class Interface(metaclass=abc.ABCMeta):
'''
定义接口Interface类来模仿接口的概念,
python中压根就没有interface关键字来定义一个接口。
'''
@abc.abstractmethod
def read(self): # 定接口函数read
pass
@abc.abstractmethod
def write(self): # 定义接口函数write
pass class Txt(Interface): # 文本,具体实现read和write
def read(self):
pass def write(self):
pass t = Txt()

1.3 多态
面向对象的多态、多态性
多态:指的是同一种事物的多种形态
动物有多种形态:人、狗、猪

# 多态:同一种事物的多种形态
class Animal: # 同一类事物:动物
def talk(self):
pass class People(Animal): # 动物的形态之一:人
def talk(self):
print('say hello') class Dog(Animal): # 动物的形态之二:狗
def talk(self):
print('say wangwang') p=People()
d=Dog()
p.talk()
d.talk()

1.4 多态性
多态性:可以在不考虑实例类型的前提下使用实例

# 多态:同一种事物的多种形态
class Animal: # 同一类事物:动物
def talk(self):
pass class People(Animal): # 动物的形态之一:人
def talk(self):
print('say hello') class Dog(Animal): # 动物的形态之二:狗
def talk(self):
print('say wangwang') # 多态性:可以在不考虑实例类型的前提下使用实例
p=People()
d=Dog() def Talk(animal):
animal.talk() Talk(p)
Talk(d)

1.5 多态性的好处
多态性的好处:
1.增加了程序的灵活性
2.增加了程序可扩展性
1.6 鸭子类型
Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’
python程序员通常根据这种行为来编写程序。例如,如果想编写现有对象的自定义版本,可以继承该对象
也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度。
利用标准库中定义的各种‘与文件类似’的对象,尽管这些对象的工作方式像文件,但他们没有继承内置文件对象的方法

# 二者都像鸭子,二者看起来都像文件,因而就可以当文件一样去用
class TxtFile:
def read(self):
pass def write(self):
pass class DiskFile:
def read(self):
pass
def write(self):
pass

2 封装
2.1 隐藏
在python中用双下划线开头的方式将属性隐藏起来

class Foo:
__N = 1111 # _Foo__N
def __init__(self,name):
self.__Name=name # self._Foo__Name=name def __f1(self): # _Foo__f1
print('f1')
def f2(self):
self.__f1() # self._Foo__f1() f = Foo('egon')
# print(f.__N) # 把数据类型隐藏起来了 # 这种隐藏需要注意的问题:
# 1:这种隐藏只是一种语法上变形操作,并不会将属性真正隐藏起来
print(Foo.__dict__)
print(f.__dict__) # 运行结果:{'_Foo__Name': 'egon'}
print(f._Foo__Name) # 运行结果:egon
print(f._Foo__N) # 运行结果:1111 # 2:这种语法级别的变形,是在类定义阶段发生的,并且只在类定义阶段发生
Foo.__x = 123123
print(Foo.__dict__) # 运行结果:...'__doc__': None, '__x': 123123}
print(Foo.__x) # 运行结果:123123
f.__x = 123123123
print(f.__dict__) # 运行结果:{'_Foo__Name': 'egon', '__x': 123123123}
print(f.__x) # 运行结果:123123123 # 3:在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,
# 而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时, # 子类是无法覆盖的。
class Foo:
def __f1(self): # _Foo__f1
print('Foo.f1') def f2(self):
self.__f1() # self._Foo_f1 class Bar(Foo):
def __f1(self): # _Bar__f1
print('Bar.f1') b = Bar()
b.f2() # 运行结果:Foo.f1

2.2 封装数据属性

# 封装不是单纯意义的隐藏
# 1:封装数据属性:将属性隐藏起来,然后对外提供访问属性的接口,
# 关键是我们在接口内定制一些控制逻辑从而严格控制使用对数据属性的使用
class People:
def __init__(self,name,age):
if not isinstance(name,str):
raise TypeError('%s must be str' %name)
if not isinstance(age,int):
raise TypeError('%s must be int' %age)
self.__Name=name
self.__Age=age
def tell_info(self):
print('<名字:%s 年龄:%s>' %(self.__Name,self.__Age)) def set_info(self,x,y):
if not isinstance(x,str):
raise TypeError('%s must be str' %x)
if not isinstance(y,int):
raise TypeError('%s must be int' %y)
self.__Name=x
self.__Age=y p=People('egon',18)
p.tell_info() # 运行结果:<名字:egon 年龄:18> p.set_info('Egon',19)
p.tell_info() # 运行结果:<名字:egon 年龄:19>

2.3 封装函数属性
封装函数属性的目的:隔离复杂度

# 2:封装函数属性:为了隔离复杂度
# 取款是功能,而这个功能有很多功能组成:插卡、密码认证、输入金额、打印账单、取钱
# 对使用者来说,只需要知道取款这个功能即可,其余功能我们都可以隐藏起来,很明显这么做
# 隔离了复杂度,同时也提升了安全性 class ATM:
def __card(self):
print('插卡')
def __auth(self):
print('用户认证')
def __input(self):
print('输入取款金额')
def __print_bill(self):
print('打印账单')
def __take_money(self):
print('取款') def withdraw(self):
self.__card()
self.__auth()
self.__input()
self.__print_bill()
self.__take_money() a = ATM()
a.withdraw()
# 运行结果:
# 插卡
# 用户认证
# 输入取款金额
# 打印账单
# 取款

2.4 静态属性

class Foo:
@property
def f1(self):
print('Foo.f1') f = Foo()
f.f1 # 运行结果:Foo.f1

示例:计算BMI指数

'''
例:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,
如果我们将其做成一个属性,更便于理解)
成人的BMI数值:
过轻:低于18.5
正常:18.5-23.9
过重:24-27
肥胖:28-32
非常肥胖, 高于32
体质指数(BMI)=体重(kg)÷身高^2(m)
EX:70kg÷(1.75×1.75)=22.86
'''
class People:
def __init__(self,name,weight,height):
self.name=name
self.weight=weight
self.height=height
@property
def bmi(self):
return self.weight / (self.height**2) p=People('jack',75,1.80)
p.height=1.86
print(p.bmi)

3 面向对象高级
3.1 反射
通过字符串,反射到真实的属性上,找到真实的属性

class Foo:
x=1
def __init__(self,name):
self.name = name def f1(self):
print('from f1') print(Foo.x) # Foo.__dict__['x'] f = Foo('egon')
print(f.__dict__) print(f.name)
print(f.__dict__['name']) # hasattr
print(hasattr(f,'name')) # f.name
print(hasattr(f,'f1')) # f.f1
print(hasattr(f,'x')) # f.x # setattr
setattr(f,'age',18) # f.age=18 # getattr
print(getattr(f,'name')) # f.name
print(getattr(f,'abc',None)) # f.abc
print(getattr(f,'name',None)) # f.abc func = getattr(f,'f1') # f.f1
func() # delattr
delattr(f,'name') # del f.name
print(f.__dict__)

3.2 item系列
Item系类,主要包括:__getitem__、__setitem__、 __delitem__,通过这几个item,可以像操作字典一样,操作对象的属性。

class Foo:
def __getitem__(self, item):
print('=====>get')
return self.__dict__[item] def __setitem__(self, key, value):
self.__dict__[key]=value
# setattr(self,key,value) def __delitem__(self, key):
self.__dict__.pop(key) f = Foo()
f['name'] = "jack" # 设置
print(f["name"]) # 取出属性
del f["name"] # 删除
print(f.__dict__)

3.3 __str__
通过__str__,打印对象信息

class People:
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex def __str__(self): # 在对象被打印时触发执行
return '<name:%s age:%s sex:%s>' %(self.name,self.age,self.sex) p=People('alex',38,'male')
print(p) # 运行结果:<name:alex age:38 sex:male>

3.4 析构方法
用法:清理一些资源,清理一些python解析器不能清理的资源,例如:清理操作系统的资源,打开文件,向操作系统发起调用,关闭文件句柄资源

class Foo:
def __init__(self, name):
self.name = name def __del__(self): # 在对象资源被释放时触发
print('-----del------') f = Foo("mary")
del f
print('对象被释放')

4 异常

# 逻辑错误
# TypeError
for i in 3:
pass # NameError
aaaaa # ValueError
int('asdfsadf') # IndexError
l=[1,2]
l[1000] #KeyError
d = {'a':1}
d['b'] # AttributeError
class Foo:pass
Foo.x

4.1 异常处理
如果错误发生的条件可预知的,我们需要用if进行处理,在错误发生之前进行预防
如果错误发生的条件时不可预知的,则需要用到try…except,在错误发生之后进行处理

#基本语法为
try:
# 被检测的代码块
except 异常类型:
# try中一旦检测到异常,就执行这个位置的逻辑
# 示例
try:
f=open('a.txt')
g=(line.strip() for line in f)
print(next(g))
print(next(g))
except StopIteration:
f.close()

4.2 多分支异常

try:
aaaa
print('====>1')
l = []
l[3]
print('====>2')
d = {}
d['x']
print('====>3')
except NameError as e:
print(e)
except IndexError as e:
print(e)
except KeyError as e:
print(e)

4.3 万能异常

try:
# aaaa
print('====>1')
l = []
l[3]
print('====>2')
except Exception as e:
print(e)

4.4 基本结构

try:
aaaa
print('====>1')
l=[]
l[3]
print('====>2')
d={}
d['x']
print('====>3')
except NameError as e:
print(e)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except Exception as e:
print(e)
else:
print('在没有错误的时候执行')
finally:
print('无论有无错误,都会执行')

4.5 自定义异常

class EgonException(BaseException):
def __init__(self, msg):
self.msg=msg
def __str__(self):
return '<%s>' %self.msg raise EgonException('jack 的异常')

5 Socket编程
IP + 端口,标识唯一一个软件、应用
tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端
5.1 简单套接字
5.1.1 服务端

import socket # 买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 插卡
phone.bind(("127.0.0.1", 8080)) # 开机
phone.listen(5) # 等待电话
print("server start...")
conn,client_addr = phone.accept() # tcp链接,client_addr
print("链接", conn)
print(client_addr) # 基于建立的链接,收发消息
client_data = conn.recv(1024)
print("客户端的消息", client_data)
conn.send(client_data.upper()) # 挂电话链接
conn.close() # 关机
phone.close()

5.1.2 客户端

import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080)) phone.send("hello".encode("utf-8"))
server_data = phone.recv(1024)
print("服务端回应的消息", server_data)
phone.close()

5.2 加上通信循环
5.2.1 服务端

import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...")
conn,client_addr = phone.accept() while True: # 通讯循环
client_data = conn.recv(1024)
print("客户端的消息", client_data)
conn.send(client_data.upper()) conn.close()
phone.close()

5.2.2 客户端

import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080)) while True:
msg = input(">>").strip()
if not msg:continue
phone.send(msg.encode("utf-8"))
server_data = phone.recv(1024)
print("server back:", server_data.decode("utf-8")) phone.close()

5.3 加上链接循环
5.3.1 服务端

import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...") while True: # 链接循环
conn,client_addr = phone.accept()
while True: # 通讯循环
try:
client_data = conn.recv(1024)
if not client_data:break # 针对linux系统
conn.send(client_data.upper())
except Exception: # 针对windows
break
conn.close() phone.close()

5.3.2 客户端

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080)) while True:
msg=input('>>: ').strip()
if not msg:continue
phone.send(msg.encode('utf-8'))
server_data = phone.recv(1024)
print(server_data.decode('utf-8')) phone.close()

5.4 模拟ssh远程执行命令
5.4.1 服务端

import socket
import subprocess phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...") while True: # 链接循环
conn,client_addr = phone.accept()
while True: # 通讯循环
try:
cmd = conn.recv(1024)
if not cmd:break # 针对linux系统 # 执行命令,拿到结果
res = subprocess.Popen(cmd.decode("utf-8"),
shell = True,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
stdout = res.stdout.read()
stderr = res.stderr.read()
conn.send(stdout+stderr)
except Exception: # 针对windows
break
conn.close() phone.close()

5.4.2 客户端

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080)) while True:
cmd = input('>>').strip()
if not cmd:continue
# 发命令
phone.send(cmd.encode('utf-8')) # 收命令的执行结果
cmd_res = phone.recv(1024) # 打印结果
print(cmd_res.decode('gbk')) phone.close()

5.5 粘包现象
Tcp出现粘包现象,udp不会出现粘包;主要是tcp基于流式的,像水流一样,没有开头,没有结尾,源源不断,会发生粘包;udp,是数据报的,不会出现粘包。
5.5.1 服务端

from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind(("127.0.0.1", 8080))
s.listen(5) conn,addr = s.accept() # 收发消息
data1 = conn.recv(1024)
print("data1:", data1) data2 = conn.recv(1024)
print("data2:", data2) conn.close()
s.close()

5.5.2 客户端

from socket import *
c = socket(AF_INET, SOCK_STREAM)
c.connect(("127.0.0.1", 8080)) c.send("hello".encode("utf-8"))
c.send("world".encode("utf-8"))
c.close()

5.6 ssh远程执行命令+定制报头
5.6.1 服务端

import socket
import struct
import subprocess
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...")
while True: # 链接循环
conn,client_addr = phone.accept()
print(conn, client_addr) while True: # 通讯循环
try:
cmd = conn.recv(1024)
if not cmd:break # 执行命令,拿到结果
res = subprocess.Popen(cmd.decode("utf-8"),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = res.stdout.read()
stderr = res.stderr.read() # 制作报头
header = struct.pack("i", len(stdout)+len(stderr)) # 先发报头(固定长度)
conn.send(header)
# 再发真实数据
conn.send(stdout)
conn.send(stderr)
except Exception: # 针对windows
break
conn.close() phone.close()

5.6.2 客户端

import socket
import struct phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080)) while True:
cmd = input(">>").strip()
if not cmd:continue
# 发命令
phone.send(cmd.encode("utf-8")) # 先收报头
header = phone.recv(4)
total_size = struct.unpack("i", header)[0] # 再收命令的执行结果
recv_size = 0
data = b""
while recv_size < total_size:
recv_data = phone.recv(1024)
recv_size += len(recv_data)
data += recv_data # 打印结果
print(data.decode("gbk")) phone.close()

5.7 定制报头的正确方式
5.7.1 服务端

import socket
import struct
import subprocess
import json
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...")
while True: # 链接循环
conn,client_addr = phone.accept()
print(conn, client_addr) while True: # 通讯循环
try:
cmd = conn.recv(1024)
if not cmd:break # 执行命令,拿到结果
res = subprocess.Popen(cmd.decode("utf-8"),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = res.stdout.read()
stderr = res.stderr.read() # 制作报头
header_dic = {"total_size":len(stdout)+len(stderr), "md5":None}
header_json = json.dumps(header_dic)
header_bytes = header_json.encode("utf-8") # 1.先发报头的长度(固定4个bytes)
conn.send(struct.pack("i", len(header_bytes))) # 2.再发报头
conn.send(header_bytes) # 3.最后发真实数据
conn.send(stdout)
conn.send(stderr)
except Exception: # 针对windows
break
conn.close() phone.close()

5.7.2 客户端

import socket
import struct
import json phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080)) while True:
cmd = input(">>").strip()
if not cmd:continue
# 发命令
phone.send(cmd.encode("utf-8")) # 先收报头的长度
struct_res = phone.recv(4)
header_size = struct.unpack("i", struct_res)[0] # 再收报头
header_bytes = phone.recv(header_size)
print(header_bytes)
head_json = header_bytes.decode("utf-8")
head_dic = json.loads(head_json) total_size = head_dic["total_size"] # 再收命令的执行结果
recv_size = 0
data = b""
while recv_size < total_size:
recv_data = phone.recv(1024)
recv_size += len(recv_data)
data += recv_data # 打印结果
print(data.decode("gbk")) phone.close()

5.8 服务端实现并发
5.8.1 服务端

import socketserver class MyTcphandler(socketserver.BaseRequestHandler):
def handle(self):
while True: # 通信循环
print(self.request)
data = self.request.recv(1024)
self.request.send(data.upper()) if __name__ == '__main__':
# 取代链接循环
server = socketserver.ThreadingTCPServer(("127.0.0.1",8080), MyTcphandler)
server.serve_forever()

5.8.2 客户端

import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080)) while True:
msg = input(">>").strip()
if not msg:continue
phone.send(msg.encode("utf-8"))
server_data = phone.recv(1024)
print(server_data.decode("utf-8"))
phone.close()

面向对象&网络编程的更多相关文章
- Java面向对象 网络编程 下
Java面向对象 网络编程 下 知识概要: (1)Tcp 练习 (2)客户端向服务端上传一个图片. (3) 请求登陆 (4)url 需求:上传图片. 客户端: ...
- Java面向对象 网络编程 上
Java面向对象 网络编程 上 知识概要: (1)网络模型 (2)网络通讯要素 (3)UDP TCP 概念 (4)Socket (5)UDP TCP 传输 ...
- 第三模块:面向对象&网络编程基础 第2章 网络编程
01-计算机基础 02-什么是网络 03-五层协议详解 04-传输层详解 05-什么是Socket 06-基于socket实现简单套接字通信 07-在简单套接字基础上加上通信循环 08-客户端与服务端 ...
- 第三模块:面向对象&网络编程基础 第1章 面向对象
我的失败与梦想(一) 我的失败与梦想之为何创办路飞学城 01-编程范式 02-面向过程编程 03-面向对象编程介绍 04-定义类与实例化出对象 05-如何使用类 06-如何使用对象 07-属性查找与绑 ...
- 第三模块 面向对象& 网络编程基础 实战考核
1.简述构造方法和析构方法. 构造方法(__init__):主要作用是实例化时给实例一些初始化参数,或执行一些其它的初始化工作,总之因为这个__init__只要一实例化, 就会自动执行,不管你在这个方 ...
- 第三模块:面向对象&网络编程基础 第3章 选课系统作业讲解
01-选课系统作业讲解1 02--选课系统作业讲解2 03-选课系统作业讲解3 04--选课系统作业讲解4 01-选课系统作业讲解1 02--选课系统作业讲解2 03-选课系统作业讲解3 04--选课 ...
- 第三模块:面向对象&网络编程基础 第4章 FTP项目作业讲解
01-FTP项目需求 02-FTP项目框架搭建 03-FTP项目用户认证 04--FTP项目制定标准定长消息头 05-FTP项目下载功能开发 06-FTP项目下载功能开发2 07-FTP项目ls文件列 ...
- 有哪些适合学生参与的 C++,网络编程方面的开源项目?
有哪些适合学生参与的 C++,网络编程方面的开源项目? Tinyhttpd是一个超轻量型Http Server,使用C语言开发,全部代码只有502行(包括注释),附带一个简单的Client,可以通 ...
- C++网络编程方面的开源项目
Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力. ...
随机推荐
- Python3学习笔记18-访问限制
在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑. 但是,从Student类的定义来看,外部代码还是可以自由地修改一个实例的name ...
- WebsphereMQ搭建集群
#https://www.ibm.com/developerworks/cn/websphere/library/techarticles/1202_gaoly_mq/1202_gaoly_mq.ht ...
- Unity 发送游戏画面到 Winform
一.首先看一下Unity界面: 设了2个摄像机,位置重叠,旋转相同,父子关系,在父摄像机上加上脚本A.cs,并将子摄像机复制给A脚本中的变量Cam: Cam用于为RenderTexture提供画面,P ...
- CentOS6.5环境使用keepalived实现nginx服务的高可用性及配置详解
keepalived基础概念 Keepalived是一个基于VRRP协议来实现的WEB服务高可用方案,可以利用其来避免单点故障.一个WEB服务至少会有2台服务器运行Keepalived,一台为主 ...
- bootgrid 刷新保持当前排序
1. 前言 主要是利用了HTHNL5的localStorage技术和用ajax传输一个数组到后台并进行判断.这篇文章是解决一个小需求而来的,主要是用来记录. 2. 代码 JavaScript: var ...
- Ubuntu下安装Golang并测试HelloWorld
Intel Core i5-8250U,Ubuntu 18.04(安装在虚拟机Oracle VirtualBox 5.2.12上),Go 1.11, 安装步骤如下: -进入Go文档官网: https: ...
- javascript 什么类型没有toString()?
JS里面任何对象都有toString()方法么?不是! null和undefined就没有!虽然null用typeof看的时候,是object类型的. 另外number对象调用toString()会报 ...
- 使用JDBC连接数据库报“找不到驱动程序”错误解决
1.jre安装不成功: 2.jre中没有数据库驱动(D:\jre\lib\ext 中查看)
- LeetCode(6):Z字形转换
Medium! 题目描述: 将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数:(下面这样的形状) P A H N A P L S I I G Y I R 之后按 ...
- hdu1255扫描线计算覆盖两次面积
总体来说也是个模板题,但是要开两个线段树来保存被覆盖一次,两次的面积 #include<iostream> #include<cstring> #include<cstd ...