Python面向对象总结及类与正则表达式
Python3 面向对象
一丶面向对象技术简介
- 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
- 方法:类中定义的函数。
- 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
- 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
- 局部变量:定义在方法中的变量,只作用于当前实例的类。
- 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
- 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
- 实例化:创建一个类的实例,类的具体对象。
- 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
和其它编程语言相比,Python 在尽可能不增加新的语法和语义的情况下加入了类机制。
Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。
对象可以包含任意数量和类型的数据。
1.类中带下划线开头的变量特点
类中的方法,其实就是类中的函数,可以分为:实例方法,类方法,静态方法。方法和字段一样,也是属于类的属性,所以也具有运行中修改的特效, 但一般不推荐这样做。
我在类的基本语法中,介绍了构造器方法:__init__ 、__new__;解构器方法:__del__;
注意,这里虽然是以两个下划线(__)开头,但同时以两个下划线(__)结尾,这里表明其是一个‘魔法方法’,关于类中的魔法方法,将起一篇进行说明。
但是,如果单纯只以两个下划线开始,则依然是私有化的意思,看代码示例:
class Test(object): def __scolia__(self): # 一个类似魔术方法,并不是私有化
return 'scolia' def __good(self): # 私有方法
return 'good' a = Test()
print a.__scolia__() # 魔法方法可以在直接访问
print a.__good() # 私有方法不能直接访问
aaarticlea/png;base64,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" alt="" />
同样的,和字段私有化一样,我们也可能同特殊手段进行强制访问:
print a._Test__good() # 强制访问
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOcAAAAYCAIAAACOUn27AAAAzklEQVR4nO3a2wmEMBBG4SlrKppy0k2qSTH6sBrZjUQXEvSH870o4uXlMAbRloeYmZk99XRIoxvooVrooVrooVroGVttSW5mkYfeFPgxfNbmoFpMRrXQQ7XQc1ZtDjtEXvb1qnkq+zntkc9V7k61mKyttg7LulOSeyrH9uII1WKyk1m7jdFjkLYd39kBZunM2uqfWZuDL1+Y7WJduwV4f10bEXyxxWT9WcvrHm/UW9d+z1LgLfgPAXqoFnqoFnqoFnqoFnqoFnqoFnqoFnpW200MUgjCPoIAAAAASUVORK5CYII=" alt="" />
当然,私有方法也可以在类的内部访问,和私有字段一样。
所以说,属性的私有化都是对访问入口进行混淆,同样的,也不建议强制访问私有属性。
也许这里的‘魔法方法’看起来并不‘魔法’,详情将以后解释。
实例方法:
在 __init__ 构造器中,提起过其是一个实例方法,实例方法的特点就是:
1.方法的第一个参数必须是 self,当然这是约定俗成的写法,你可以将 self 换成 abc 之类的,但是为了别的程序员能看得懂,还是统一用 self 吧。这里的 self 代表实例本身,也就是说如果我实例化时使用的是: a = Test() ,那么 self 就代表 a 这个实例,我们可以在很多构造器中看到类似 self.scolia = 'good' 的写法,其实这个写法和在类外面 a.scolia = 'good' 效果一样,是为了添加属性,只不过 __init__ 方法是实例化时自动调用的函数,所以适合进行初始属性的创建。
2.实例方法在调用的时候,self 是自动传递的,所以不需要我们再处理。
3.实例方法一般要有实例才能调用,当然也有特殊的调用方法。
代码示例:
class Test(object): def __init__(self, a, b): # 构造器在实例创建时进行属性的初始化
self.a = int(a)
self.b = int(b) def abc(self, c): # 实例方法
print self.a + self.b + int(c) # 因为self是自动传递的,所以我们可以在实例方法中调用实例的属性 a = Test(123, 321) # 我们只要为 a 和 b 传参就行了
a.abc(666) # 同样的,只要为 c 传参
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQwAAAAjCAIAAADuY6OTAAAEG0lEQVR4nO2by5HjIBCGOyxC2ERMGHIEy02n3Qy4mrui0EUZOAn2AIhXY7DG8o6n/q+2XLa2oRuafhjXkO1zV2IiuhJdSa5tmVlt8bORYQhdpRlQ4lkl6SfEHdsiaMp1JTaLZeMsPMohC09kxDuZsDTeO9LYTc1jAw8aFtzR2rTHm3lXl6XnsRGZr0JdiU3NQt2ttdauUjQNSsSsF3br3xbx8FRtakn+98ARTLbJaPLDVxVsNmG6ysJRvmzhiQx6x2N0SBn7Kk5bTtTlsxiXK9+0mbkHnx7VD5I0ASfKquVti8icNBgkxTwHdi0dUg7Pdqe08MD8xyw8j/uod7xwndpPWk6qy1qjSWrJ1Kv3bOYxLXFUP0jGFRiZZotVZi2Q/yiNy/dXIn3zb9y/6DOlZqJrzPq+m3Knwc1TyTjBqpqpXCC10MiJSEs5hXneYWEGM2pWmx9uGJmaZ9yfpnYuSGKHnFcArz3sifEP26NKXW7b70okprrZxCxI/1Ez0SzEREJfxOR3bFcXDa52tZTh7Mk9eGuswrede7uej3plkFijk+629l/sB4yqvRX3IhxZ9zwky1gHahm/zvJEmqU8W6WFkzT5zGdamLMXgV2pO0Zpk13LFIwHSZ7amSCpp6q1r5ImYvuFR7r8PEaGAEh3jPTNrtJnB/fa6gvYXR2p88w8jVXwMz/Xbtnt/rBdedT52P0cG815q2XuyJvUAREjH+8XM895FnJ7NeU1yj1MiwYrk3If9U6e2tvHIq1atfbWEcxrHaOrqDaZ9pv/mL4WRj62ucrFZe0dCKRYOg4FSfbVsHcNkvQzzRxDrMVmbRwvNk9nMpua9zPd68sLC4uZz7KQIznf/nCHShLbklqmZMw7RWrP115ddZTritqZE8mNynVtyyXkLyPdhGFmo+nFQVLbY9serGbOvj/HUf0gSS4ZB76/+n4mDKmbBKPzlB8k5RpTjlyzdpPp3VOZv79iwrtybTdroROYhZiouKR+vYX7OcjZb673mcWyhebbMDIsA94pU7u1dRfOXiWn2pM2PdmfahRfRrJva8aGzC21pInEb6KrlHp/dcU8/wmB29VSprGK1IP8KvbvSPoipuQ3Az9qJEieomgYSrgW6M3sFrZKzX+38LXUZeRn6HofLw+SFsnd0ffAX4Nkled7WQi+CW8LEgA+FQQJAB0QJAB0QJAA0AFBAkAHBAkAHRAkAHRAkADQAUECQIfRIDGy/CW692RTgoiIxCv+ZhaA/8dAkBhJRERJAAw82ZQIf78iESbgoxmsJEZSUTceP9mU2EMDUQI+m5OCpPUegM8DQQJAB7RbAHQ4KUjwxR38HMZvt5Lbq5EnuAIGPwX8mAhABwQJAB0QJAB0QJAA0AFBAkAHBAkAHRAkAHRAkADQ4R9cnxGS++phswAAAABJRU5ErkJggg==" alt="" />
这里,将引入一个绑定 (binding) 的概念,其主要和方法的调用有关。
首先,我们知道方法是类的属性,而不是实例的属性,在上篇博文类的属性和实例的属性中我们也讨论过这个问题。
其次,方法只有在其所属的类拥有实例时,才能被调用。当一个类存在实例后,方法才被认为是绑定到这个实例。没有实例的时候,方法是未绑定的。
最后,任何一个方法定义的第一个参数都是变量 self ,它表示调用此方法的实例对象。
很明显这里的绑定针对的是实例方法。因为如果没有实例的话,self 就无法传递,这将导致参数的不足,当然就无法调用了。
但是,我们可以自己传递 self 来调用未绑定的方法。调用未绑定的方法通常是在我们继承了一个父类后, 我们覆盖了父类中的某个方法,但是为了实现代码重用,我们又想在子类中调用父类的方法。单纯的复制父类中的代码明显不是一个好选择, 除了浪费系统资源之外,还有可能在复制的时候出错,而且以后修改父类的代码之后,还要修改相应子类中的代码,实在太低效,这个时候就是调用未绑定方法的场景。
代码示例:
class abc(object):
def __init__(self, a):
self.a = -int(a) class Test(abc):
def __init__(self, a, b):
abc.__init__(self, a) # 调用父类的构造器,并手动传递 self
self.b = b def fangfa(self):
print self.a + self.b # 属性 a 由父类的构造器创建,b 由子类构造器创建 a = Test(123, 321) # 我们只创建了子类的实例,而没有创建父类的实例
a.fangfa()
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAAvCAIAAADrS1Z3AAADGElEQVR4nO2awZW0IAyAUxYl/I1MynA64Obt74Dr5G4VXujAJtiDgIDoMDru+vLyvT3MuFEjnwnoLjiBNfDXCQjXIoKZc0KwHZQa7NkERoQOwNDZ49S4f4bXsyV40qoDeAI8AcftmF4n40cYdoEnfjAeIx4YPjso6PJzJTl7r2WGRzmU4YW02PHUBVvdKz0555wbcbsIkjDng+eBsIPaHRGrh+S3B4Zv0o+QFZlQXqMOOVM43CrDVk5neCGNdmbqgtMbP7nU1XWWPbBRcHGcA8OX7lLunrk52KXPZ3gdU6sd55yb6oLbr4ewS7rxPF3Ftum/Is119gQwL/9h/vGVh2C07gGeS7X5DjxfiZ8Fyxh/hWUX0XlAmiFhB2AQu3Cc38gwo7JXr20+zWcxaz6528icFezIJNPA+txLDyEdK2ldH10Y7nl7uEmX+lvHOFftwDSU41Jm2CHlR74yw5xYfPGkk1aG0hmnElPQLnjSqnvfop2ddlvcXrd00QGZvNCrDfCjD46wW9cK4friqxkuG6/LsDZWXd4b5o1psVZjUqZWO2RADQ2LrHfrtKQH1qcBrYrHjBBG48bQVOsji7G6jz7ezUNFhsWRr8qwRuLGiwkVrOIu65iSNjuTVh3S+8ekhrWG74Fhl3VjIZOXWojEcblhcYyzYFimFXNVGvP/33Kbp2fcz3AO6JUK8+6FGZpXNZn4dBePrAZbPGpnMVUa7JCZh+Urb7KKJlNSa5u/TMxwq8T/PMPv4svXXfyqMlmj3gP/Kiar+Htl+HXkXTRzRDBzRDBzRDBzRDBzRDBzRDBzRDBzRDBz9gQTJm94rFYwEzYSAhSbhNuxIdjLS/5go8IXQkByjhCUf/9MKIpvy04Fe5PVzy9ntQqCHaH6xr+2CRfQKHipYKtVqNfYo6V870uj4MWmejy86zBFp7Us3I1mweXmrQYu3ItP5+C4oEpWVskKTLgb+6voZYKNT0mLyeXBSTr0fZEXHcwRwcwRwcwRwcwRwcwRwcwRwcwRwcwRwcwRwcwRwcwRwcwRwcwRwcwRwcwRwcz5Aaz3crFa6JyJAAAAAElFTkSuQmCC" alt="" />
本来我们没有创建父类的示例,是无法调用父类的实例方法的,但是我们手动传递了实例方法需要的 self 参数,就可以实现调用了。
这里的顺序是,我们创建了 Test 的实例,其 self 是自动传递的,故 Test 的构造方法 __init__(self, a, b) 中 self 就代表实例 a,而我们又调用了父类的 abc.__init__(self, a) 这里的 self 就是子类的实例 a ,参数 a 就是我们传的 123,而父类中 self.a = -int(a) ;最后我们可在子类的方法中调用 self.a 这个属性。
2.Python面向对象的三大特性
一、继承
面向对象中的继承就是继承的类直接拥有被继承类的属性而不需要在自己的类体中重新再写一遍,其中被继承的类叫做父类、基类,继承的类叫做派生类、子类。在python3中如果不指定继承哪个类,默认就会继承Object类,而继承了Object类的类就叫做新式类,而在python2中如果不指定继承哪个类也不会默认去继承Object类,而没有继承Object类的类就叫做经典类。经典类和新式类的不同就在于对方法的搜索顺序不同,经典类是深度优先即先找自己类内,如果没有就找左边第一个父类,没找到继续从这个父类的父类中找依次类推直到找到最上一级的父类也没找到再找左边第二个父类,然后再重复之前的过程,直到所有父类找一遍没找到就报错;而新式类是广度优先,当下一个类可以通过其他类找到时就先不去找它,而是找继承关系中与它的子类同级的其他类,依次类推直到最后找到object类没有找到指定方法就报错。新式类搜索顺序图示如下,还可以通过类名.mro()查看新式类继承中的属性搜索顺序
二、单继承与多继承
在其他语言中只支持单继承即class 类名(父类名),而python支持多继承,用逗号将多个父类隔开即class 类名(父类名1,父类名2,。。。。)
三、继承与抽象
抽象就是把一类事物的共有特性提取出来,继承则是把父类的属性拿过来并且还拥有自己的属性。抽象是包含的范围越来越大,共性越来越少,继承则是包含的返回越来越小,共性越来越多。我们定义父类的过程就是抽象,定义子类的过程就是继承。
四、父类方法重写
我们把子类有而父类没有的方法叫做子类的派生方法,而父类有子类也有的方法叫做对父类方法的重写,因为按照类方法的搜索顺序一个方法如果在子类中有就不会再从父类中找了,结果就是父类中的方法无法调用了,如果既想执行父类中的方法同时在子类中又能定义新功能,就需要先把父类中的这个方法单独继承过来,在python中只能使用父类名.方法名(self,父类的其他参数)的方式,在python3中可以使用super函数来实现,比如super().父类方法名(除self外的其他参数),其实在super函数中还需要传入子类名和子类对象(在类中用self),但是我们使用时不需要特意去传,除非在类外单独调用父类的方法。注意在继承父类方法时父类的参数除了需要在父类的方法中传递还需要在子类重写的方法中传递
class Animal:
def __init__(self,name,life_value,aggr):
self.name=name
self.life_value=life_value
self.aggr=aggr
def eat(self):
self.life_value+=10 class Person(Animal):
def __init__(self,money,name,life_value,aggr):
super().__init__(name,life_value,aggr)
self.money=money
def attack(self,obj):
obj.life_value-=self.aggr
五、接口类
接口类是用于规范子类的方法名定义用的,继承接口类的子类可以不存在任何逻辑上的关系但是都需要实现某些共同的方法,为了让这些子类的方法名能够统一以便之后调用这些方法时不需要关注具体的对象就用接口类规范了这些方法的名字,子类一旦继承了接口类就必须实现接口类中定义的方法,否则在子类实例化的时候就会报错,而接口类本身则不需要实现去实现这些方法。
1 from abc import ABCMeta,abstractmethod
2 class Payment(metaclass=ABCMeta):
3 @abstractmethod
4 def pay(self,money):pass
5
6 class Wechatpay(Payment):
7 def pay(self,money): #子类中必须定义接口类中有的方法,否则实例化会报错
8 pass
9
10 w1=Wechatpay()
六、抽象类
抽象类的作用和接口类一样,只是继承它的子类一般存在一些逻辑上的关系,且抽象类中的方法可以去实现,子类在重写时用super函数调用抽象类的方法即可,同时在用抽象类时使用单继承,使用接口类时使用多继承
七、多态
多态就是不同的对象可以调用相同的方法然后得到不同的结果,有点类似接口类的感觉,在python中处处体现着多态,比如不管你是列表还是字符串还是数字都可以使用+和*。
八、封装
封装就是把类中的属性和方法定义为私有的,方法就是在属性名或方法名前加双下划线,而一旦这样定义了属性或方法名后,python会自动将其转换为_类名__属性名(方法名)的格式,在类的内部调用还是用双下划线加属性名或方法名,在类的外部调用就要用_类名__属性名(方法名)。父类的私有属性和方法,子类无法对其进行修改。
九、类的装饰器
property属性装饰器:将类内的方法的调用方式和属性一样,这个装饰器还有和其配套的setter、deleter。
class Demo:
@property
def p(self):
print('property func')
@p.setter
def p(self,num):
print('property_setter')
@p.deleter
def p(self):
print('在删除')
d=Demo()
d.p
d.p=10
del d.p
--------------------------------------------------------------------------------------
property func
property_setter
在删除
staticmethod静态方法装饰器:将类内的方法变成普通的函数,或者把类外的函数放到类内当作方法调用
class A:
@staticmethod
def sum(): #这个方法跟普通函数没有区别
print('staticmethod')
A.sum() #用类名调用
--------------------------------------------------------------------------------------
staticmethod
classmethod类方法装饰器:该方法用于操作类属性,无法操作对象属性
class A:
role='male'
@classmethod
def sum(cls): #用于操作类属性
print(cls.role)
A.sum() #用类名调用
--------------------------------------------------------------------------------------
male
十、isinstance和type的区别以及issubclass
isinstance和type都可以用于判断对象和指定类间的关系,但是isinstance的判断没有type准确,它无法正确判断子类的对象和其父类的关系
class A:
pass
class B(A):
pass b=B()
print(isinstance(b,B))
print(isinstance(b,A))
print(type(b) is B)
print(type(b) is A)
--------------------------------------------------------------------------------------
True
True
True
False
issubclass用于判断给定的两个类,前者是否是后者的子类
十一、反射
hasattr(对象或类名,‘属性或方法名’) 判断指定的对象或类中是否存在指定的属性或方法,有返回True
getattr(对象或类名,'属性或方法名') 获取对象或类的指定属性值或方法的内存地址
setattr(对象或类名,‘新属性名’,新属性值) 给对象或类添加新的属性或方法
delattr(对象或类名,‘新属性名’) 删除之前添加的属性
十二、类的内置方法
__doc__ :输出类的描述信息
__module__ :表示当前操作的对象在那个模块
__class__ : 表示当前操作的对象的类是什么
__dict__ :查看类或对象中的所有成员 类调用打印类的所有属性,不包括实例属性。实例调用打印所有实例属性
__str__ 格式化输出%s输出该方法的值
__repr__ 格式化输出%r输出该方法的值,并且%s在没有__str__方法时也是输出该方法的值
__del__ del 执行该方法
__getitem__ 用对象加[]方式取值
class A:
def __init__(self):
self.names=['egon','alex','eva'] #可以是其他序列
def __getitem__(self, item):
print(self.names[item]) a=A()
a[1]
----------------------------------------------------------
alex
__setitem__ 添加值
__delitem__ 删除值
__new__ 用于创建没有属性的对象,调用object的__new__即可不需要自己实现。可以利用该方法实现单例模式
__call__ 对象加括号执行该方法
__len__ len()执行该方法
__eq__ ==运算输出该方法的值
__hash__ hash执行该方法
二丶代码实现(三维向量类)
class Vecter3:
def __init__(self, x=0, y=0, z=0):
self.X = x
self.Y = y
self.Z = z
def __add__(self, n):
r = Vecter3()
r.X = self.X + n.X
r.Y = self.Y + n.Y
r.Z = self.Z + n.Z
return r
def __sub__(self, n):
r = Vecter3()
r.X = self.X - n.X
r.Y = self.Y - n.Y
r.Z = self.Z - n.Z
return r
def __mul__(self, n):
r = Vecter3()
r.X = self.X * n
r.Y = self.Y * n
r.Z = self.Z * n
return r
def __truediv__(self, n):
r = Vecter3()
r.X = self.X / n
r.Y = self.Y / n
r.Z = self.Z / n
return r
def __floordiv__(self, n):
r = Vecter3()
r.X = self.X // n
r.Y = self.Y // n
r.Z = self.Z // n
return r
def show(self):
print((self.X,self.Y,self.Z)) v1 = Vecter3(1,2,3) v2 = Vecter3(4,5,6) v3 = v1+v2 v3.show() v4 = v1-v2 v4.show() v5 = v1*3 v5.show() v6 = v1/2 v6.show()
此类可实现三维向量的加减乘除
运行后为
三丶代码实现(程序类)
这个程序运用类与正则表达式匹配来写,可以删除重复的英文并输出,这里输入 This is my name
import re
class Good:
def __init__(self,n):
self.n = n
def love(self):
s1 = re.split(r' ',self.n)
s2 = sorted(set(s1),key=s1.index)
print(s2)
b = Good('This is is my name')#此处可自行输入字符串
b.love()
接下来我们看运行结果
Python面向对象总结及类与正则表达式的更多相关文章
- Python面向对象之接口类(抽象类)
Python面向对象之接口类(抽象类):就是制定一个规范. 比如定义了一个接口类(抽象类)(他们是不可以进行实例化的,这就是他为什么是制定一个规范的原因). 他的定义是需要abc模块,要变的就是他的方 ...
- Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法
Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3 ...
- Python面向对象编程、类
一.面向对象编程 面向对象--Object Oriented Programming,简称oop,是一种程序设计思想.在说面向对象之前,先说一下什么是编程范式,编程范式你按照什么方式来去编程,去实现一 ...
- Python面向对象 --- 新旧式类、私有方法、类属性和类方法、静态方法
一.Python面向对象中的新旧式类 1)新式类(推荐使用):在定义类时,类后边括号里要继承基类(object).在python3.x中若没有指定父类,会默认使用的是object作为基类:在pytho ...
- Python面向对象-概念、类、实例
OOP——Object Oriented Programming,面向对象编程,是一种程序设计思想.该思想将对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 区别于面向过程的程序设计即把计 ...
- Python面向对象1:类与对象
Python的面向对象- 面向对象编程 - 基础 - 公有私有 - 继承 - 组合,Mixin- 魔法函数 - 魔法函数概述 - 构造类魔法函数 - 运算类魔法函数 # 1. 面向对象概述(Objec ...
- python面向对象 : 抽象类(接口类),多态,封装(私有制封装)
一. 抽象类(接口类) 与java一样, python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类, 它的特殊之处在于只能被继承, 不能被实例化. 从设计角度去看, 如果类是从现实对 ...
- python面向对象的多态-类相关内置函数-类内置魔法函数-迭代器协议-上下文管理-04
多态 一种事物具备不同的形态 例如:水 --> 固态.液态.气态 多态:# 多个不同对象可以相应同一个对象,产生不同的结果 首先强调,多态不是一种特殊的语法,而是一种状态,特性(多个不同对象可以 ...
- 『无为则无心』Python面向对象 — 46、类和对象
目录 1.理解类和对象 2.类 3.对象 4.Python中的对象 5.类和对象的定义 (1)定义类 (2)创建对象 (3)练习 6.拓展:isinstance() 函数 1.理解类和对象 (1)类和 ...
随机推荐
- C++中接口与实现分离的技术 ZZ
最简单清晰的例子:http://www.cnblogs.com/maoye/archive/2010/03/19/1690183.html 接口与实现分离 为什么这样设计? 主要原因是保持接口的稳定, ...
- python之路——进程
操作系统背景知识 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统的其 ...
- Exchange 2007 前端 IIS 内存占用过高
已经碰见了好几次,在Exchange2007的场景中,前端角色所在服务器的w3wp.exe进程总是占用大量内存,以至于触发反压组件,停止了正常的邮件流投递,造成业务中断. 终于下决心查一下到底问题问题 ...
- Exchange Server 2007 多名称证书配置
Exchange Server 2007上配置多名称证书,有两种方式,一种是通过Exchange Management Shell利用命令行工具进行创建:另一种是通过证书管理器控制台进行创建.本文将介 ...
- 内置的HTTP服务器【Modern PHP】
目录 启动服务器 配置服务器 路由器脚本 判断是否为内置的服务器 PHP5.4.0起,PHP内置了Web服务器.对本地开发是个极好的工具,便捷,无需安装WAMP.XAMP或大新那个web服务器,就能在 ...
- [转] Spark-Sql On YARN自动调整Executor数配置
在所有的NodeManager中,修改yarn-site.xml,为yarn.nodemanager.aux-services添加spark_shuffle值,并设置yarn.nodemanager. ...
- 【LeetCode每天一题】Remove Duplicates from Sorted Array II(移除有序数组中重复的两次以上的数字)
Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twic ...
- POJ3690 Constellations
嘟嘟嘟 哈希 刚开始我一直在想二维哈希,但发现如果还是按行列枚举的话会破坏子矩阵的性质.也就是说,这个哈希只能维护一维的子区间的哈希值. 所以我就开了个二维数组\(has_{i, j}\)表示原矩阵\ ...
- 【Vue】vue.js常用指令
http://www.cnblogs.com/rik28/p/6024425.html Vue.js的指令是以v-开头的,它们作用于HTML元素,指令提供了一些特殊的特性,将指令绑定在元素上时,指令会 ...
- Java之关于JSTL引入问题
错误信息:Can not find the tag library descriptor for “http://java.sun.com/jstl/core”JSTL taglib需要jstl.ja ...