taoCMS-基于php+sqlite最小巧的CMS http://www.taocms.org/ taoCMS是基于php+sqlite/mysql的国内最小(100Kb左右)的功能完善的CMS管理系统 2022-05-21 taoCMS-基于php+sqlite最小巧的CMS 1244 Windows开机自动登录账户

如何在Windows设了账户密码的情况下开机自动登录账户,有以下两种方法。

通过Windows设置自动登录

按“Win+R”组合键打开“运行”框内输入“netplwiz”。

 打开以下窗口,将“要使用本计算机,用户必须输入用户密码和密码”的复选框取消勾选,点击“确定”。

 在弹出的对话框中输入需要自动登录的用户名和密码。

 

完成以上操作即可实现开机自动登录账户。如果这台电脑是域成员计算机,将不能通过这种方法设置,“要使用本计算机,用户必须输入用户密码和密码”前的复选框不可修改。域成员计算机可以通过第二种方法设置。

 

通过Autologon工具设置自动登录账户

 微软官网提供了一个工具Autologon,用于设置自动登录。

网址:https://docs.microsoft.com/zh-cn/sysinternals/downloads/autologon

下载地址:https://download.sysinternals.com/files/AutoLogon.zip

网页截图:

使用方法:

输入用户名、域名或本地计算机名和账户密码,点击Enable即可使能自动登录,点击Disable即可取消自动登录。


]]>
taoCMS-基于php+sqlite最小巧的CMS 2022-02-21 10:02:08
1243 Python高级教程

关键字is 和 == 的区别

a = 'hello world'
b = 'hello world'
a == b  #返回True 
a is b  #返回False 
注意:is 判断是否是一个ID, == 判断内容是否一致。

深拷贝和浅拷贝

import copy
a = [1,2,3,4,5]
b = a   #浅拷贝,a,b同时指向一个id,当其中一个修改时,另外一个也会被修改。
c = copy.deepcopy(a) #深拷贝,c单独开辟一个id,用来存储和a一样的内容。
d =a[:] #这样也是深拷贝。
e = copy.copy(a) #当拷贝内容是可变类型时,那么就会进行深拷贝,如果是不可变类型时,那么就会进行浅拷贝。
注意:深拷贝指的是复制内容,单独开辟一个内存,浅拷贝指的是两个变量同时指向一个内存ID。


私有化和Property

class Test(object):
	def __init__(self):
		self.__num = 100
	@getNum.setter #等同步于 porperty(setNum,getNum)
	def setNum(self,num): #将self.__num的属性封装。
		self.__num = num
	@porperty #等于getNum = porperty(getNum) 默认的是getter方法。
	def getNum(self) #获取__num的值。
		return self.__num
	num = porperty(getNum,setNum) #使用关键字porperty将getNum和setNum方法打包使用,并将引用赋予属性num。
t = Test()
print(t.__num) #将会出错,表示输出私有属性,外部无法使用。
t.__num = 200  #这里将会理解为添加属性 __num = 200,而不是重新赋值私有属性。
print(t.__num) #这里输出的200是定义的属性__num,而不是self.__num。 
t.setNum(200) #通过set方法将私有属性重新赋值。
t.getNum() #通过get方法获取__num的值。
print(_Test__num) #私有属性其实是系统再私有属性前加上了一个_Test,就是一个下划线加类名。

t.num = 300 #调用类属性num,并重新赋值,porperty会自动检测set方法和get方法,并将引用赋值给set方法。
print(t.num) #输出类属性,并会自己检测使用get方法进行输出。


注意: num 前后没有下划线的是公有方法,_num 前边有一个下划线的为私有方法或属性,子类无法继承, 前边有两个下划线的 一般是为了避免于子类属性或者方法名冲突,无法在外部直接访问。前后都有双下划线的为系统方法或属性。后边单个下划线的可以避免与系统关键词冲突。

列表生成式

range(1,100,5) #第一个参数表示开始位,第二个参数表示结束位(不含),第三个参数表示步长,就是每5个数返回一次。
a = [i for i in range(1,10)] #列表生成式表示返回i的值,并且返回9次,每次返回的是i的值。
a = [2 for i in range(1,10)] #这里表示返回2,并且返回9次,但是每次的值都是2。
a = [i for i in range10 if i%2==0] #表示在生成式内部加入if判断,当i除以2的余数等于0的时候将数值返回。
a = [(i,j) for i in range(5) for j in range(5)] #表示将i和j的值以元组为元素的形式返回,当i循环一次的时候j循环5次,以此类推。
生成器
a = (i for i in range(1,10)) #将列表生成试外部的中括号改为小括号,就能将生成式转化为生成器。
next(a),a.__next__() #生成器的取值方式只能使用next的方法。
def num():
	a,b = 0,1
	for i in range(10):
		yield b  #生成关键字yield,有yield的关键字的代码块就是yield的生成器。当运行到yield时代码就会停止,并返回运行结果,当在次运行时依旧是到yield停止,并返回结果。 切记:生成器只能使用next方法。
		a,b = b,a+b
		temp = yield b  #这里并不是变量的定义,当运行到yield时就会停止,所以当运行到等号右边的时候就会停止运行,当在次使用next的时候,将会把一个None赋值给temp,因为b的值已经在上轮循环中输出。这里可以使用num().send()方法将一个新的值赋值给temp。
a = num()  #将生成器赋值给变量a。
for n in a:  #生成器可以使用for循环使用,并且不会出错。
	print(n) 


注意:生成器占用内存小,在使用的时候取值,降低CPU和内存空间,提高效率。并且一般都使用for循环进行取值。

迭代器

for i in '',[],(),{},{:}
#可以for循环的对象是可迭代对象。
a = (x for i in range(100))
#列表生成式,把中括号改为小括号就可以变为一个列表生成器,是可迭代对象。
from collections import Iterable #如果想验证是否是可迭代对象,可以使用isinstance()判断是否是可迭代对象。
isinstance('abc',Ierable) #判断语法
a = [1,2,3,4,5]
b = iter(a)  #使用iter()方法可以将可迭代对象转换为可迭代对象。


注意:生成器是可迭代对象,迭代器不一定是生成器。并且迭代器无法回取,只能向前取值。
注意:一个对象具有 iter 方法的才能称为可迭代对象,使用yield生成的迭代器函数,也有iter方法。凡是没有iter方法的对象不是可迭代对象,凡是没有__next__()方法的不是是生成器。(这里的方法都是魔法方法,是内置方法,可以使用dir()查看)

闭包

def num(num): #定义函数
	def num_in(nim_in): #定义函数
		return num + num_in #返回两个参数的和。
	return num_in #返回内部函数的引用。(变量名)

a = num(100) #将参数为100的函数num接收,并赋值给a,只不过这个返回值是一个函数的引用。等于 a = num_in,注意这里接收的不光是函数本身,还有已经传递的参数。
b = a(100) #调用函数a,即num_in,并传递一个参数100,返回值给b。


注意:当一个函数定义在另一个函数内,且使用到了外部函数的参数。整个代码块称为闭包。当外部参数确定时,内部函数参数可以反复调用。

装饰器

装饰没有参数的函数

def function(func): #定义了一个闭包
	def func_in(): #闭包内的函数
		print('这里是需要装饰的内容,就是需要添加的内容')
		func() #调用实参函数。
	return func_in
	
def test(): 	#需要被装饰修改的函数。
	print('无参函数的测试')
	
test = function(test) 	#装饰器的原理就是将原有的函数名重新定义为以原函数为参数的闭包。
test() 这里再次掉用test()的时候,其实是将会调用闭包内的函数func_in()。所以将会起到装饰修改的作用,最后会再次调用原函数test()。

@function 	#装饰器的python写法,等价于test = function(test),并且无需调用当代码运行道这里,Python会自动运行。
def test():
	print('无参函数的测试')
test() 	#这里再次调用函数时,将会产生修改后的效果。

装饰带有参数的函数

def function(func): #定义了一个闭包
	def func_in(*args,**kwargs): 	#闭包内的函数,因为装饰器运行的实则是闭包内的函数,所以这里将需要有形参用来接收原函数的参数。
		print('这里是需要装饰的内容,就是需要添加的内容')
		func(*args,**kwargs) 	#调用实参函数,并传入一致的实参。
	return func_in
	
@function	 #装饰器的python写法,等价于test = function(test) .
def test():
	print('无参函数的测试')
	
test(5,6) 	#这里再次掉用test()的时候,其实是将会调用闭包内的函数func_in()。所以将会起到装饰修改的作用,最后会再次调用原函数test()。
装饰带有返回值的函数
def function(func): #定义了一个闭包
	def func_in(*args,**kwargs): #闭包内的函数,因为装饰器运行的实则是闭包内的函数,所以这里将需要有形参用来接收原函数的参数。
		print('这里是需要装饰的内容,就是需要添加的内容')
		num = func(*args,**kwargs) #调用实参函数,并传入一致的实参,并且用变量来接收原函数的返回值,
		return num #将接受到的返回值再次返回到新的test()函数中。
	return func_in
@function
def test(a,b): #定义一个函数
	return a+b #返回实参的和

通用装饰器

def function(func): #定义了一个闭包
	def func_in(*args,**kwargs): 	#闭包内的函数,因为装饰器运行的实则是闭包内的函数,所以这里将需要有形参用来接收原函数的参数。
		print('这里是需要装饰的内容,就是需要添加的内容')
		num = func(*args,**kwargs) 	#调用实参函数,并传入一致的实参,并且用变量来接收原函数的返回值,
		return num 	#将接受到的返回值再次返回到新的test()函数中。
	return func_in


def func(*args,**kwags):
	def function(func): #定义了一个闭包
		def func_in(*args,**kwargs): #闭包内的函数,因为装饰器运行的实则是闭包内的函数,所以这里将需要有形参用来接收原函数的参数。
			print('这里是需要装饰的内容,就是需要添加的内容')
			num = func(*args,**kwargs) #调用实参函数,并传入一致的实参,并且用变量来接收原函数的返回值,
			return num #将接受到的返回值再次返回到新的test()函数中。
		return func_in
	return function

@func(50)  #这里会先运行函数func,并切传入参数,之后会再次运行闭包函数进行装饰, @func(50)>>@function,然后将由@function继续进行装饰修改。
def test(a,b):
	print('这是一个函数')
	return a+b


类装饰器

class Test(object): #定义一个类
	def __init__(self,func):
		self.__func = func
	def __call__(self):  #定义call方法,当直接调用类的时候,运行这里。
		print('这里是装饰的功能')
		self.__func()	
t = Test() #实例化对象
t() #调用类,将会调用call方法。

@Test  #类装饰器等于test = Test(test),将函数test当作参数传入类中的init方法,并将函数名赋值给私有属性__func,当函数test被调用的时候,其实是运行Test类中的call方法.
def test():
	print('被装饰的函数')
test() #这里调用的不在是函数test,而是实例对象test的call方法,会先进行装饰,然后再调用私有属性__func(),__func 其实就是被装饰的函数test。
动态语言添加属性和方法
class Person(): #创建一个类
	def __init__(self,name): #定义初始化信息。
		self.name = name 
li = Person('李')  #实例化Person('李'),给变量li
li.age = 20  #再程序没有停止下,将实例属性age传入。动态语言的特点。
Person.age = None  #这里使用类名来创建一个属性age给类,默认值是None。Python支持的动态属性添加。
def eat(self): #定义一个方法,不过这个方法再类之外。
	print('%s正在吃东西。。'%self.name) 
import types  #动态添加方法需要使用tpyes模块。
li.eat = types.MethodType(eat,li) #使用types.MethodType,将函数名和实例对象传入,进行方法绑定。并且将结果返回给li.eat变量。实则是使用一个和li.eat方法一样的变量名用来调用。
li.eat() #调用外部方法eat()方法。

@staticmethod  #定义静态方法。
def test():  #定义静态方法,静态方法可以不用self参数。
	print('这是一个静态方法。')
Person.test = test  #使用类名.方法名 = test的形式来方便记忆和使用,Person.test其实只是一个变量名,没有特殊的含义。
Person.test()  #调用test方法。

@classmethod  #类方法
def test(cls): 
	print('这是一个类方法。')
Person.test = test #定义一个类属性等于方法名。
Person.test() #调用方法。

class test(object): #定义一个类。
	__slots__ = ('name','age') #使用slots来将属性固定,不能进行动态添加修改。


元类

创建带有类属性的类

Test = type('Test',(object,),{'num':0}  #元类是只使用type创建的类,使用type会有3个参数,第一个是类名,第二个小括号内是父类名,需要使用元组。第三个字典中是类属性,使用type能够快速的动态创建一个类。
class Test(object):  #创建一个类,等价于上边
	num = 0
创建带有方法的类
def eat(self):  #定义一个函数,self作为第一个参数。
	print ('%s正在吃饭。。'%self.name)
Person = type('Person',(object,), {'eat':eat,'name':None}  #使用type创建一个类,但是有两个属性,一个是eat,一个是name,但是eat的值是函数eat的引用。
p = Person()  #实例化
p.name = 'Tom'  #类属性赋值
p.eat()  #调用eat()方法。
内建属性
__init__ #构造初始化函数,__new__之后运行
__new__ #创建实例所需的属性
__class__ #实例所在的类,实例.__class__
__str__ #实例的字符串表示,可读性高
__repr__ #实例的字符串表示,准确性高
__del__ #删除实例引用
__dict__ #实力自定义属性,vars(实例.__dict__)
__doc__ #类文档,help(类或者实例)
__bases__ #当前类的所有父类
__getattribute__ #属性访问拦截器。


内建方法

range(start,stop,[,step]) #生成器
map(function, iterable, ...) # map() 会根据提供的函数对指定序列做映射。
filter(function, iterable) #filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
reduce(function, iterable[, initializer]) #reduce() 函数会对参数序列中元素进行累积。
sorted(iterable[, cmp[, key[, reverse]]]) #sorted() 函数对所有可迭代的对象进行排序操作。sort 与 sorted 区别:
sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。
list 的 sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。
PDB调试
1.python -m pdb xxx.py  #在命令行输入以上命令,进入pdb调试模式。XXX.py表示需要打开的文件。
2.import pdb
pdb.run('func(*args)') #第二种方式,当程序在运行中调试。
3.pdb.set_trace() #第三种方法,当程序运行到这行代码时,就会自动运行。
l(list) # 显示全部代码
n(next) # 向下执行一行代码
c(contiune) # 执行余下的代码
b(break) 10 # 设置断点,b 10表示将断点设置到第10行。clear 1,删除第一个断点
p(print) a,b #打印变量的值
a(args) #打印全部的形参数据
s(step) #进入到一个函数
r(return) #快速执行到函数的最后一行


进程和线程

进程

import	os
pid = os.fork() #这里将会创建一个子进程,返回值会是子进程PID值。
print('父子进程都会输出。') #这里没有判断语句,将会运行两次,一次是父进程,一次是子进程。
if pid > 0: #判断,父进程的返回值会大于0。
	print('子进程的PID是%d,父进程的PID是%d'%(os.getpid(),os.getppid())) #getpid的获取当前进程的pid,如果子进程getpid的时候,会得到子进程的值,再子进程使用getppid的时候能够获取到父进程的pid。
else: #子进程的返回值则会永远是0
	print('父进程的PID是%d'%os.getpid()) #当父进程使用getpid的时候获得的是父进程的pid。


**注意:**进程值PID是不能重复的,类似于端口。系统会为每个进程会分配不同的PID进行区分不同的软件进程。并且父子进程会独立运行,互不干扰。而且父子进程的调用需要系统来调度,没有固定性。

import os
pid = os.fork() #创建子进程,接收pid的返回值。
if pid > 0: #判断是子进程还是父进程。
	print('父进程') #当pid的返回值是0的时候,会运行父进程
else:
	print('子进程') #否则就是子进程
pid =os.fork() #让之前的父子进程再次创建各自的子进程
if pid > 0: #判断父子进程
	print('父进程的子进程') #这里会运行2次父进程
else:
	print('子进程的子进程') #这里也会运行两次子进程


windons中的fork()-Process

from multiprocessing import Process #导入模块类,这是一个类
import time
def test(): #定义一个函数
    while True:
        print('-1-')
        time.sleep(1)
p = Process(target=test) #创建一个实例,就是一个新进程,并且执行的代码就是test()函数
p.start() #调用start方法让子进程开始运行。
p.join(10) #join表示延时时间,也就是等待子进程的时间,当10秒过了以后,则会运行主进程。
while True: #这里是主进程。
    print('-2-')
    time.sleep(1)


注意:Process需要自己创建进程,以及调用开始进程,fork则是全自动运行。后期最好以Process为主,可实现跨平台运行。还有最主要的一点是Process的主进程会等待子进程。

Process实例

from multiprocessing import Process
import time

class Process_class(Process): #创建一个Process的子类。
    def run(self): #重写run方法,当调用start方法时,则会默认调用run方法,所以不用再填写target参数。
        while True:
            print('--1--')
            time.sleep(1)
p = Process_class() #实例化一个子进程。
p.start() #运行子进程
p.join(5) #这里将会等待子进程单独运行5秒。
while True: #主进程,当join等待结束收,则会父子进程一起运行。但是如果当父进程运行完,子进程还没有结束,那么父进程会继续等子进程。
    print('--main--')
    time.sleep(1) 


进程池Pool

from multiprocessing import Pool #导入Pool模块类
import os,time
def work(num): #创建一个进程的工作函数。
    for i in range(2): #表示每次工作需要执行2次。
        print('进程的pid是%d,进程值是%d'%(os.getpid(),num)) #输出两次
        time.sleep(1)

p = Pool(2) #实例化对象,参数2表示创建2个子进程,就是说每次只能执行2个进程。

for i in range(6): 
    print('--%d--'%i)
    p.apply_async(work,(i,)) #向实例对象添加6次任务,就是6个进程,但是实例对象的进程池只有2个,需要每次执行2个进程,当2个进程执行完以后则会再次执行下面2个。

p.close() #关闭进程池,不再接收进程任务。
p.join() #当子进程工作结束后,则会运行主进程。

Queue队列

Process的Queue用法

from multiprocessing import Process,Queue  #导入Process和Queue
import os,time,random

def write(q):  #定义函数,接收Queue的实例参数
    for v in range(10):
        print('Put %s to Queue'%v)
        q.put(v)  #添加数据到Queue
        time.sleep(1)
def read(q): #定义函数,接收Queue的实例参数
    while True:
        if not q.empty(): #判断,如果Queue不为空则进行数据取出。
            v = q.get(True) #取出Queue中的数据,并返回保存。
            print('Get %s from Queue'%v)
            time.sleep(1)
        else: #如果Queue内没有数据则退出。
            break

if __name__ == '__main__':
    q = Queue() #实例化Queue括号内可选填,输入数字表示有多少个存储单位。以堵塞方式运行。必须等里边有空余位置时,才能放入数据,或者只能等里边有数据时才能取出数据,取不出数据,或者存不进数据的时候则会一直在等待状态。
    pw = Process(target=write,args=(q,)) #实例化子进程pw,用来执行write函数,注意这里的函数不带括号,只是传递引用,参数需要使用args参数以元组的方式进行接收。
    pr = Process(target=read,args=(q,)) #实例化子进程pr,用来执行read函数,注意这里的函数不带括号,只是传递引用,参数需要使用args参数以元组的方式进行接收。
    pw.start() #开始执行pw。
    pr.start() #开始执行pr。
    pw.join() #等待pw结束
    pr.join() #等待pr结束
    print('Over')  #主进程结束
Pool的Queue用法
from multiprocessing import Manager,Pool #这里注意导入的是Manager和Pool
import os,time,random

def write(q):
    for v in range(10):
        print('Put %s to Queue'%v)
        q.put(v)
        time.sleep(1)
def read(q):
    while True:
        if not q.empty():
            v = q.get(True)
            print('Get %s from Queue'%v)
            time.sleep(1)
        else:
            break

if __name__ == '__main__':
    q = Manager().Queue() #这里实例化的时候是使用Manager的Queue
    p = Pool()
    p.apply_async(write,(q,)) #将任务加入Pool的进程池,注意这里的参数于Process不同。
    p.apply_async(read,(q,)) #将任务加入Pool的进程池,注意这里的参数于Process不同。
    p.close() #关闭进程池,不再接收进程。
    p.join() #子进程完毕,运行以下的主进程。
    print('Over')
线程
from threading import Thread #导入Thread线程类。
import time

num = 0 #定义全局变量

def work(): #定义函数内容
    global num 
    for i in range(1000000):
        num += 1
    print('work的num是%d'%num)

def works(): #定义函数
    global num
    for i in range(1000000):
        num += 1
    print('works的num是%d'%num)

t = Thread(target=work) #创建第一个线程内置的self.name属性为Thread-1,并指向work
tt = Thread(target=works) #创建第二个线程内置的self.name属性为Thread-2,并指向works
t.start() #开始执行
tt.start() #开始执行
time.sleep(1) #主线程休息一秒
print('最后的num值是%d'%num) #输出最后的结果。


注意:线程中的变量数据是可以共享的,进程与线程的区别在于,父子进程是两个单独的个体,子进程类似于直接拷贝的一份父进程的代码独立运行,相当于两个文件。线程则是再主进程的内部分裂运行。举例子来说一个工厂需要做100万件衣服,但是工期太紧,自己做太慢,老板现在有两个选择,一个是雇佣另外一个同样规模的工厂一起来做,两个工厂一起做——进程,另外一个选择就是在自己的工厂内大批量的招募工人用来赶工——线程。总得来说线程的消耗成本会比进程低很多。

互斥锁

from threading import Thread,Lock #导入互斥锁Lock

num = 0

def work():
    global num
    l.acquire() #这里表示调用互斥锁上锁方法,如果work函数先运行l.acquire的话,那么后边的程序就不能再修改和使用变量num。直到将其解锁后才能使用。
    for i in range(1000000):
        num += 1
    print('work的num是%d'%num)
    l.release() #这里表示调用互斥锁解锁方法。

def works():
    global num
    l.acquire() #这里表示调用互斥锁上锁方法。
    for i in range(1000000):
        num += 1
    print('works的num是%d'%num)
    l.release() #这里表示调用互斥锁解锁方法。


l = Lock() #实例化互斥锁,互斥锁是为了保护子线程不争抢数据而使用的一个类。
t = Thread(target=work)
tt = Thread(target=works)
t.start()
tt.start()
print('最后的num值是%d'%num) #输出最后的结果,如果实验过的可能会发现这个结果并不是2000000,为什么呢?
这里需要明白,主线程和子线程是同时进行的,因为创建子进程在前,最后输出再后,所以当最后线程输出的时候,子线程还在运行,也就是说当子线程的加法运算加到95222的时候你的
主进程刚好运行到最后的输出语句,所以就把95222拿过来进行输出。你也可以试试将最后的输出语句放到实例化的前边,看看结果是不是0,因为子线程还没有开始工作,所以并没有进行加法运算。
注意:因为线程的数据是共享数据,不用Queue就能实现,所以也会存在一些弊端,因为线程是在进程间独立运行的,所以共享数据会有一定的延时性和不准确性,举例家里有10个馒头,2个孩子,第一个孩子拿走一个会记得还剩下9个,第二个孩子去拿的时候会记得还剩下8个,但是当第一个孩子再去拿的时候会发现只剩下7个了,但是之前明明还剩下9个,这样就会出现问题。互斥锁的作用就是再厨房装上一把锁,当第一个孩子饿的时候就进去吃馒头,将门反锁,这样第二个孩子就吃不到再门口等着,当第一个吃饱的时候第二个再进去,也把门锁上。这样一个一个的来避免冲突。

同步、异步

import threading
import time

class MyThread(threading.Thread):
    def run(self):
        global num 
        time.sleep(1)

        if mutex.acquire(1):  
            num = num+1
            msg = self.name+' set num to '+str(num)
            print msg
            mutex.release()
num = 0
mutex = threading.Lock()
def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == '__main__':
    test()
结果
Thread-3 set num to 1
Thread-4 set num to 2
Thread-5 set num to 3
Thread-2 set num to 4
Thread-1 set num to 5


注意:这里就是一个简单的同步,使用互斥锁来实现,因为每个线程在创建运行的时候都是各自做各自的,如果没有互斥锁来约束步调,那么结果是1,2,3,4,5的概率是未知数,但是加上了互斥锁以后,就会对线程的运行顺序进行排队,达到预期的结果。而异步则是各个线程独立运行,谁先做完就休息,不用等待。

threadlocal

import threading  #导入模块

l = threading.local() #实例化local,注意这个local和Lock互斥锁的名称不同。

def work(name): #创建函数
    l.name = name #将参数name传递给local实例对象的name属性。注意:这里的l.name是创建的对象属性。
    works() #调用work函数

def works(): #创建函数
    name = l.name
    print('hello,%s,线程的name是%s'%(name,threading.current_thread().name))

t1 = threading.Thread(target=work,args=('小李',)) #实例化线程对象,并调用work,参数name是小李。
t2 = threading.Thread(target=work,args=('小王',))#实例化线程对象,并调用work,参数name是小王。
t1.start()
t2.start()
t1.join()
t2.join()


注意:threadlocal是比较方便的共享数据处理办法,他的内部类似于一个字典,Thread.name作为Key,对应的属性作为Value,当Thread-1储存和取值的时候,对应的是它的值,从而避免多个线程对共有数据造成错误和丢失。

网络编程

Tcp/Ip协议

早期的计算机网络,都是由各厂商自己规定一套协议,IBM、Apple和Microsoft都有各自的网络协议,互不兼容为了把全世界的所有不同类型的计算机都连接起来,就必须规定一套全球通用的协议,为了实现互联网这个目标,互联网协议簇(Internet ProtocolSuite)就是通用协议标准。

因为互联网协议包含了上百种协议标准,但是最重要的两个协议是TCP和IP协议,所以,大家把互联网的协议简称TCP/IP协议

这里写图片描述

这里写图片描述

这里写图片描述

端口

知名端口

知名端口是众所周知的端口号,范围从0到1023
例如:
80端口分配给HTTP服务
21端口分配给FTP服务
一般情况下,如果一个程序需要使用知名端口的需要有root权限

动态端口

动态端口的范围是从1024到65535
之所以称为动态端口,是因为它一般不固定分配某种服务,而是动态分配。
动态分配是指当一个系统进程或应用程序进程需要网络通信时,它向主机申请一个端口,主机从可用的端口号中分配一个供它使用。当这个进程关闭时,同时也就释放了所占用的端口号。

小结
端口有什么作用?在两台计算机通信时,只发 IP 地址是不够的,因为同一台计算机上跑着多个网络程序。一个 IP 包来了之后,到底是交给浏览器还是 QQ,就需要端口号来区分。每个网络程序都向操作系统申请唯一的端口号,这样,两个进程在两台计算机之间建立网络连接就需要各自的 IP 地址和各自的端口号。

Socket-套接字

udp-套接字

from socket import *  #导入socket
from threading import *  #导入threading

udp = socket(AF_INET,SOCK_DGRAM) #创建套接字,基于UDP传输协议。相对于TCP比较快。AF_INET表示使用IPV4进行链接。如果使用IPV6则把参数修改为AF_INET6

udp.bind(('',8080)) #绑定任意ip,和8080端口,如果不进行绑定,那么每创建一个套解字就会使用一个动态端口。

sendip = input('输入接收方的IP:')
sendport = int(input('输入接收方的端口:'))

def sendinfo(): #定义发送函数
    while True:
        senddata = input('请输入发送的内容:')
        udp.sendto(senddata.encode('utf-8'),(sendip,sendport)) #调用套解字的sendto方法,第一个参数为编码后的数据,第二个参数为接收方的IP和端口。

def receiveinfo(): #定义接收函数
    while True:
        recvdata = udp.recvfrom(1024) #调用recvfrom方法进行数据接收,并且以元祖的方式返回,第一个参数是数据,第二个参数为IP和端口。与发送格式一致。
        print(recvdata[1],recvdata[0].decode('utf-8')) #将接收到的数据进行打印,并将数据进行解码。

def main():
    ts = Thread(target=sendinfo) #创建一个线程运行发送函数。
    tr = Thread(target=receiveinfo) #创建一个线程运行接收函数。

    ts.start()
    tr.start()

    ts.join()
    tr.join()

if __name__ == '__main__':
    main()
注意:socket套接字是用来再网络间通信的模块。

tcp-套接字

tcp-套接字 服务器

from socket import * #导入套接字

tcp = socket(AF_INET,SOCK_STREAM) #创建tcp套接字

tcp.bind(('',8800)) #绑定ip,和端口,客户端需要连接这个ip和端口进行服务器连接。

tcp.listen(5) #tcp监听,参数为可连接的数量。

newsocket,addr = tcp.accept() #接收客户端的连接,并返回一个新的socket和客户端地址。阻塞程序等待客户端的接入。

while 1: # 表示while True,只要条件类型不是空类型、0和None的False类型则就表示while True。
    socketDate = newsocket.recv(1024) #接收客户端的数据。
    if len(socketDate)>0: #如果接收数据的长度大于0,则打印出接收到的信息,如果接收的数据长度为0,则表示客户端使用close方法关闭了套接字。
            print(socketDate.decode('utf-8'))  #将接收数据解码为utf-8输出
    else: #如果客户端关闭了套接字,则跳出循环
            break

    sendDate = input('请输入要回复的内容:') #输入需要回复的数据
    newsocket.send(sendDate.encode('utf-8')) #使用send将数据编码为utf-8回复
	
newsocket.close() #关闭与客户端通信的套接字。
tcp.close() #关闭服务器的套接字,关闭后将不会再接收客户端的连接。


注意:在linux系统中listen的参数可以忽略,因为系统会自动按照内核进行最大连接数的操作,即使填写参数也没有效果,但是windons和mac中则会有效。以上是单线程案例。

tcp-套接字 客户端

from socket import * #导入模块

csocket = socket(AF_INET,SOCK_STREAM) #创建套接字

serverIp = input('请输入服务器的IP:') 

csocket.connect((serverIp,8800)) #连接服务器

while 1:
    sendData = input('请输入需要发送打内容:') #输入发送的内容
    csocket.send(sendData.encode('utf-8')) #编码发送

    recvData = csocket.recv(1024)
    print('recvData:%s'%recvData.decode('utf-8')) #解码输出

csocket.close() #关闭套接字
注意:正常的编程工作中,会优先使用tcp套接字。

交换机、路由器

交换机

转发过滤:当⼀个数据帧的⽬的地址在MAC地址表中有映射时,它被转发到连接⽬的节点的端⼝⽽不是所有端⼝(如该数据帧为⼴播帧则转发⾄所有端⼝)

学习功能:以太⽹交换机了解每⼀端⼝相连设备的MAC地址,并将地址同相应的端⼝映射起来存放在交换机缓存中的MAC地址表中

交换机能够完成多个电脑的链接每个数据包的发送都是以⼴播的形式进⾏的,容易堵塞⽹络如果PC不知⽬标IP所对应的的MAC,那么可以看出,pc会先发送arp⼴播,得到对⽅的MAC然后,在进⾏数据的传送当switch第⼀次收到arp⼴播数据,会把arp⼴播数据包转发给所有端⼝(除来源端⼝);如果以后还有pc询问此IP的MAC,那么只是向⽬标的端⼝进⾏转发数据。

路由器

路由器(Router)⼜称⽹关设备(Gateway)是⽤于连接多个逻辑上分开的⽹络所谓逻辑⽹络是代表⼀个单独的⽹络或者⼀个⼦⽹。当数据从⼀个⼦⽹传输到另⼀个⼦⽹时,可通过路由器的路由功能来完成具有判断⽹络地址和选择IP路径的功能

不在同⼀⽹段的pc,需要设置默认⽹关才能把数据传送过去 通常情况下,都会把路由器默认⽹关当路由器收到⼀个其它⽹段的数据包时,会根据“路由表”来决定,把此数据包发送到哪个端⼝;路由表的设定有静态和动态⽅法每经过⼀次路由器,那么TTL值就会减1

网段、ARP、DNS、MAC地址

网段

网段(network segment)一般指一个计算机网络中使用同一物理层设备(传输介质,中继器,集线器等)能够直接通讯的那一部分。例如,从192.168.0.1到192.168.255.255这之间就是一个网段。

A类IP段  0.0.0.0 到127.255.255.255 A类的默认子网掩码 255.0.0.0     一个子网最多可以容纳1677万多台电脑
B类IP段  128.0.0.0 到191.255.255.255 B类的默认子网掩码 255.255.0.0    一个子网最多可以容纳6万台电脑
C类IP段  192.0.0.0 到223.255.255.255 C类的默认子网掩码 255.255.255.0   一个子网最多可以容纳254台电脑

局域网保留地址:
A类:10.0.0.0/8 10.0.0.0-10.255.255.255
B类:172.16.0.0/12 172.16.0.0-172.31.255.255
C类:192.168.0.0/16 192.168.0.0~192.168.255.255

注意:C类地址必须前三位一致的才算是一个局域网,可以不使用路由器进行通信,例如192.168.1.1-192.168.1.254 是一个局域网,B类地址则必须前两位一致才算是一个局域网。以此类推。即子网掩码有几位相同的则需要有几位一致的。

ARP

地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址;收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。地址解析协议是建立在网络中各个主机互相信任的基础上的,网络上的主机可以自主发送ARP应答消息,其他主机收到应答报文时不会检测该报文的真实性就会将其记入本机ARP缓存;由此攻击者就可以向某一主机发送伪ARP应答报文,使其发送的信息无法到达预期的主机或到达错误的主机,这就构成了一个ARP欺骗。ARP命令可用于查询本机ARP缓存中IP地址和MAC地址的对应关系、添加或删除静态对应关系等。相关协议有RARP、代理ARP。NDP用于在IPv6中代替地址解析协议。

工作过程
主机A的IP地址为192.168.1.1,MAC地址为0A-11-22-33-44-01;
主机B的IP地址为192.168.1.2,MAC地址为0A-11-22-33-44-02;
当主机A要与主机B通信时,地址解析协议可以将主机B的IP地址(192.168.1.2)解析成主机B的MAC地址,以下为工作流程:
第1步:根据主机A上的路由表内容,IP确定用于访问主机B的转发IP地址是192.168.1.2。然后A主机在自己的本地ARP缓存中检查主机B的匹配MAC地址。
第2步:如果主机A在ARP缓存中没有找到映射,它将询问192.168.1.2的硬件地址,从而将ARP请求帧广播到本地网络上的所有主机。源主机A的IP地址和MAC地址都包括在ARP请求中。本地网络上的每台主机都接收到ARP请求并且检查是否与自己的IP地址匹配。如果主机发现请求的IP地址与自己的IP地址不匹配,它将丢弃ARP请求。
第3步:主机B确定ARP请求中的IP地址与自己的IP地址匹配,则将主机A的IP地址和MAC地址映射添加到本地ARP缓存中。
第4步:主机B将包含其MAC地址的ARP回复消息直接发送回主机A。
第5步:当主机A收到从主机B发来的ARP回复消息时,会用主机B的IP和MAC地址映射更新ARP缓存。本机缓存是有生存期的,生存期结束后,将再次重复上面的过程。主机B的MAC地址一旦确定,主机A就能向主机B发送IP通信了。

DNS

DNS服务器是(Domain Name System或者Domain Name Service)域名系统或者域名服务,域名系统为Internet上的主机分配域名地址和IP地址。用户使用域名地址,该系统就会自动把域名地址转为IP地址。域名服务是运行域名系统的Internet工具。执行域名服务的服务器称之为DNS服务器,通过DNS服务器来应答域名服务的查询。

MAC地址

MAC(Media Access Control或者Medium Access Control)地址,意译为媒体访问控制,或称为物理地址、硬件地址,用来定义网络设备的位置。在OSI模型中,第三层网络层负责 IP地址,第二层数据链路层则负责 MAC地址。因此一个主机会有一个MAC地址,而每个网络位置会有一个专属于它的IP地址。

MAC(Medium/Media Access Control)地址,用来表示互联网上每一个站点的标识符,采用十六进制数表示,共六个字节(48位)。其中,前三个字节是由IEEE的注册管理机构RA负责给不同厂家分配的代码(高位24位),也称为"编制上唯一的标识符"(Organizationally Unique Identifier),后三个字节(低位24位)由各厂家自行指派给生产的适配器接口,称为扩展标识符(唯一性)。一个地址块可以生成2个不同的地址。MAC地址实际上就是适配器地址或适配器标识符EUI-48[1]

注意:在真正的信息传输中,发送者的ip和接收方的ip和数据包内容是不变的,期间会通过各个路由器的mac地址进行传输。简单可以理解为,在网上买了一件衣服,包裹的发送方是商家(可以理解为发送者的IP),包裹的接收方是自己(理解为接收者的IP),期间的各个快递中转站就可以理解为各个路由器的mac地址,最后由数据将会传递到自己手中。

TCP3次握手、4次挥手和10种状态

TCP3次握手

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接.
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认; SYN:同步序列编号(Synchronize Sequence Numbers)
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手.
完成三次握手,客户端与服务器开始传送数据

这里写图片描述

关闭连接(四次挥手)

第一次挥手:客户端发送FIN+ACK包(序号为seq=a,确认序号ack=b)给服务端,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1状态。
第二次挥手:服务端收到FIN+ACK包后,发送ACK包给客户端进行确认,服务端进入CLOSE_WAIT状态。客户端收到ACK包后进入FIN_WAIT_2状态。到这里,关闭一个单向通道。
第三次挥手:服务端发送FIN+ACK包给客户端,服务端进入LAST_ACK状态。
第四次挥手:客户端收到FIN+ACK包后,发送ACK包给服务端进行确认,客户端进入TIME_WAIT状态,在等待30秒(可修改)后进入CLOSED状态。服务端收到ACK包后进入CLOSED状态,关闭另一个单向通道。

这里写图片描述

TCP十种状态

这里写图片描述

CLOSED:表示关闭状态(初始状态)。
LISTEN:该状态表示服务器端的某个SOCKET处于监听状态,可以接受连接。
SYN_SENT:这个状态与SYN_RCVD遥相呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,随即进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。
SYN_RCVD: 该状态表示接收到SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂。此种状态时,当收到客户端的ACK报文后,会进入到ESTABLISHED状态。
ESTABLISHED:表示连接已经建立。
FIN_WAIT_1: FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。区别是: FIN_WAIT_1状态是当socket在ESTABLISHED状态时,想主动关闭连接,向对方发送了FIN报文,此时该socket进入到FIN_WAIT_1状态。 FIN_WAIT_2状态是当对方回应ACK后,该socket进入到FIN_WAIT_2状态,正常情况下,对方应马上回应ACK报文,所以FIN_WAIT_1状态一般较难见到,而FIN_WAIT_2状态可用netstat看到。
FIN_WAIT_2:主动关闭链接的一方,发出FIN收到ACK以后进入该状态。称之为半连接或半关闭状态。该状态下的socket只能接收数据,不能发。
TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,等2MSL后即可回到CLOSED可用状态。如果FIN_WAIT_1状态下,收到对方同时带 FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。
CLOSE_WAIT: 此种状态表示在等待关闭。当对方关闭一个SOCKET后发送FIN报文给自己,系统会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,察看是否还有数据发送给对方,如果没有可以 close这个SOCKET,发送FIN报文给对方,即关闭连接。所以在CLOSE_WAIT状态下,需要关闭连接。
LAST_ACK: 该状态是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,即可以进入到CLOSED可用状态。

tcp第十一种状态:
CLOSING:这种状态较特殊,属于一种较罕见的状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。

TCP的2MSL

这里写图片描述

2MSL即两倍的MSL,TCP的TIME_WAIT状态也称为2MSL等待状态,
当TCP的⼀端发起主动关闭,在发出最后⼀个ACK包后,即第3次握 ⼿完成后发送了第四次握⼿的ACK包后就进⼊了TIME_WAIT状态,必须在此状态上停留两倍的MSL时间,等待2MSL时间主要⽬的是怕最后⼀个 ACK包对⽅没收到,那么对⽅在超时后将重发第三次握⼿的FIN包,主动关闭端接到重发的FIN包后可以再发⼀个ACK应答包。

在TIME_WAIT状态 时两端的端⼝不能使⽤,要等到2MSL时间结束才可继续使⽤。当连接处于2MSL等待阶段时任何迟到的报⽂段都将被丢弃。不过在实际应⽤中可以通过设置 SO_REUSEADDR选项达到不必等待2MSL时间结束再使⽤此端⼝。

TCP⻓连接和短连接

短链接

这里写图片描述

⻓连接

这里写图片描述

常见的网络攻击

DDOS攻击

这里写图片描述

注意:简单的理解DDOS攻击就是使用TCP的三次握手协议,编写代码使用多线程或者多进程方式恶意的不发送第三次握手导致服务器listen队列爆满,使正常的客户无法正常连接。

DNS攻击

DNS欺骗就是攻击者冒充域名服务器的一种欺骗行为。 原理:如果可以冒充域名服务器,然后把查询的IP地址设为攻击者的IP地址,这样的话,用户上网就只能看到攻击者的主页,而不是用户想要取得的网站的主页了,这就是DNS欺骗的基本原理。DNS欺骗其实并不是真的"黑掉"了对方的网站,而是冒名顶替、招摇撞骗罢了。

ARP攻击

ARP攻击就是通过伪造IP地址和MAC地址实现ARP欺骗,能够在网络中产生大量的ARP通信量使网络阻塞,攻击者只要持续不断的发出伪造的ARP响应包就能更改目标主机ARP缓存中的IP-MAC条目,造成网络中断或中间人攻击。
ARP攻击主要是存在于局域网网络中,局域网中若有一台计算机感染ARP木马,则感染该ARP木马的系统将会试图通过“ARP欺骗”手段截获所在网络内其它计算机的通信信息,并因此造成网内其它计算机的通信故障。
攻击者向电脑A发送一个伪造的ARP响应,告诉电脑A:电脑B的IP地址192.168.0.2对应的MAC地址是00-aa-00-62-c6-03,电脑A信以为真,将这个对应关系写入自己的ARP缓存表中,以后发送数据时,将本应该发往电脑B的数据发送给了攻击者。同样的,攻击者向电脑B也发送一个伪造的ARP响应,告诉电脑B:电脑A的IP地址192.168.0.1对应的MAC地址是00-aa-00-62-c6-03,电脑B也会将数据发送给攻击者。
至此攻击者就控制了电脑A和电脑B之间的流量,他可以选择被动地监测流量,获取密码和其他涉密信息,也可以伪造数据,改变电脑A和电脑B之间的通信内容。

]]>
taoCMS-基于php+sqlite最小巧的CMS 2022-02-18 01:02:40
1242 EAP服务-心理服务的主要内容 当前很多人对于心理健康服务是缺乏认知的,有朋友就曾问我有啥问题不能自己解决还找咨询师,浪费钱啊!在发达国家,每个家庭会有2名医生:家庭医生和心理医生,如果你看欧美剧,稍微注意下就能看到,看心理医生是常见的事情。生活工作中我们面临一些困扰,当自己或身边人无法帮助自己走出来的时候,寻求专业帮助是明智的选择。

那么,具体到企业心理服务都包含哪些内容呢?

一、心理咨询

这是基础服务,使用的频度最高。员工经常会遇到婚恋情感、家庭关系、亲子教育等各种生活困扰,在工作中也会因工作压力、同事关系、岗位调整等带来的不适。这些因素都会影响员工的工作表现,但是,很少有人愿意对同事主动讲这些,因为怕影响对自己的看法,这个时候心理咨询师就可以很好地帮助到他们。

二、心理培训

如果说心理咨询是等到出了问题后的补救,那么心理培训就是未雨绸缪。帮助员工掌握一些处理问题的技能,比如压力情绪管理、人际关系处理、亲子教育、精神疾病识别等等。通过培训也可以让一些有困扰的员工找到新的求助渠道,转化为心理咨询。

三、心理测评

员工的心理健康状态如何?有哪些需要干预的?这时候,心理测评的作用就呈现了。提供服务者需要准备足够丰富的心理量表,这些量表既能帮助员工自我筛查,又能帮助心理咨询师获取更多信息,提升咨询效率。但是心理测评有个难点,主观性强,员工往往不愿按照真实的情况填写信息。如果做大面积的筛查,效果往往无法尽如人意,目前行业中也没有更好的解决方法。我个人的建议是提供工具给员工让他们有需要的时候自我筛查,或者当进行某些心理培训的时候可以设置对应的环节,让参与者做完题后能获得及时的反馈和解读。此外,心理测评还应起到危机响应系统的作用。

四、危机干预

这是企业最不愿意用到的服务,但又必须做好准备。企业规模越大,发生人员自杀的概率越高,出现这种情况时,必须及时安抚员工家人和身边的同事,这需要专业团队来处理。一位资深心理医生告诉我说:“至少30%的人曾经在某些时刻想过自杀”。这也直接说明了企业运营过程中不仅仅有财务、法务风险,还有人员的生命风险,万一处理不好可能会对公司造成致命打击。

五、心理科普

这项服务和前面的培训有一定重合,为什么把ta单独拿出来说呢?因为科普的形式可以有很多:文章、内部广告、各种会议、小册子等。如果此部分做好了是有助于前面每个项目开展的。

六、心理类活动

结合公司大事件、各种节假日筹备一些心理类的活动也是其中一个模块,比如情人节、儿童节可以开展亲密关系、亲子关系主题的活动,这样有助于拉近EAP团队和员工之间的距离,在需要的时候愿意寻求帮助。

如果一个企业拥有以上六项服务,那它的EAP服务框架算是搭建完备了。

如果更高阶,EAP服务还需要具备以下内容:

1、新人适应力项目:帮助员工更快地适应新的工作环境,这里需要注意的是把握好价值观引导的问题,如果引导性太强会影响员工对EAP服务的信任。

2、重点人员随访服务:对于一些相对“较重”的人员,服务团队有责任持续追踪随访,直到他们恢复到平常。

3、员工婚恋服务:很多年轻男女因各种原因,惧怕交往、同时又渴望关系,缺少关系滋养的他们需要有合适的机会寻找到另一半。

4、促沟通、提升凝聚力服务:企业是协作单元,用心理学的方式促进企业中员工间的沟通,提升凝聚力,可以提升企业的运营效率。

5、即时倾诉服务:员工有时候希望第一时间获取帮助,这时候如果EAP咨询师能及时出现,对他们来说是极大的宽慰。不过,此项服务需要有相对规模化的团队才能实施。

6、精神疾病治疗服务:当前各种精神疾病高发,如果EAP能提供治疗类的服务,对于企业员工来说将是极大的福音。

7、全方位咨询服务(健康、法律、财务、保险):这些都是员工在日常中需要的问题,通过跨领域合作方式引入更多的资源给到员工,将极大地提升员工的幸福感。

另外,EAP的服务一定要充分利用新技术,比如互联网工具,让服务更高效、便捷。

希望此文能帮助您的企业建立自己的员工心理健康服务体系。

]]>
taoCMS-基于php+sqlite最小巧的CMS 2021-12-15 21:12:29
1241 HR三支柱(COE、BP、SSC)是什么 有道是,好男不做HR,要做就做COE,小红拖拉机的诗文充分说明了COE在人力资源中卓尔不群的傲娇地位,名字甚是响亮。到哪一亮身份,同行就得虎躯一震,哟呵,高手~

HRBP作为人力资源在部门的代表,那就是HRD特派大使啊,收集情报,决断人事,服务至微,说出去也是业务部门的半个人事经理啊~

再说SSC,看上去是最没含金量,是HR新人磨其锐气的必经轮岗地,看着堆了一尺高的文件和攒动的大叔阿姨的身影,揉着酸疼的颈椎腰椎,简直苦逼小桂圆(柜员)一枚……蓝瘦香菇……

从任职资格和做出政绩可行性上讲讲不被大家看好的SSC吧。


1 任职资格的差异

COE是内部的咨询顾问,要的真才实学,一言不合就得发的了车,完的成某某调研报告和薪酬福利优化方案,门槛比较高,不是想干就能干。总得来说要有知识、有经验、有思路,这三有可能难住很多人。很多大企业的COE招聘都要求有乙方咨询背景或者有较丰富的咨询项目对接经验,总得来说这是个烧智商的职位,智商的差距可以用丰富的经验弥补。

和HRBP相比,COE还算好做的,知识经验只要用心积累,多花几年还是能有所小成的,HRBP就不一样了,你能做就能做,不能做再积累也然并卵。HRBP很挑人,如果你的个性和素质,不能很快和别人建立良好人际,不能处理复杂的人际关系,在这干起来比较吃力,寸步难行。总的来说,HRBP是个烧情商的所在,情商有限的人,积累经验对胜任岗位的意义不大。

而我们SSC就不一样了,流程标准、工作基础,谁来了都能做,专业学历都不挑,基层的位置要求,干活麻利手要快,服务热情嘴要甜。主管位置要求有流程优化能力和问题解决能力,以及项目管理能力,当然了,智商情商稍微差点也不是事。

所以来说,SSC是最容易上手的岗位,因此也被认为没有含金量,没有表现机会,没有发展前景,三无岗位。那到底是不是这样?



2 做出政绩的可行性

COE的工作看着高大上而轻松,实际上整天游走在领导眼皮子底下,没有真货真心扛不住,滥竽充数总会露馅。即便你有真的才干,还要应付不同领导和利益方的诉求,考虑不到就要背黑锅。平时加班加点做调研、理数据、写材料,这就不说啥了⋯⋯


COE层级解决的问题,大多都是老板提的。所有时间都在为解决老板指出一个个问题疲于奔命,干得好是能力,干不好是常态。出问题往往比出成绩容易的多。
自己就是领导的嘴和手,工作也就是代领导写字,自己的思想是体现不出来的。所以说有政绩没?有可能有,但太难了。

HRBP是解决用人部门的问题。
部门那摊子事有多烂,部门的人最清楚,前期不规范的随意调配导致的历史遗留问题一大堆。现在设了个HRBP要解决问题,难为死他。
在所有公司HRBP就是一个夹心饼干,用人部门嫌弃他没有决断力和服务意识,解决不了问题。人力资源部嫌弃他没有执行力,推行政令不力,和部门建立的通道不畅。所以你知道对于许多HRBP,一天最难受是早起时,感叹又是tough的一天,要躺在床上搞半天心里建设才能起得来。

而SSC的业务就简单轻松多了,不拖沓地把所有的单据按时搞完,70分就拿到了。但发愁的是,不能每年年底述职汇报,只是罗列数字,今年给多少生孩子员工办理了生育补贴,辞退了多少员工,发了多少钱的工资吧?
所以咱们还得变着法做出一些创新的项目。目前来说,是企业人力资源向三支柱转型的发展期,还没有特别完善成熟的模式,SSC还有足够大的发挥空间做出花样,而且拥有着COE和BP都没有的天生的数据优势,使得做出业绩非常容易。

创新的方向有三个:

  • 建平台

这个平台是说,面向员工的服务平台。
传统的SSC都是线下服务,对于办公场地分散和非正常班次的众多员,办业务很不方便。
现在微信和APP这么火,做个员工服务的服务号或者APP投入成本也可以接受,让员工手机下单预约或直接办理相关业务,不用跑来跑去,节省了工作时间,提高了满意度,不就为公司创效益了嘛。
APP和微信号不会搞?服务商一大把呢,自己搜去。
这样搞个员工服务O2O,整个人力资源部的档次就上去了,领导面子上有光,不提拔你提拔谁?

  • 创品牌

我指的品牌,是围绕雇主品牌,打造的招聘、培训、薪酬福利、员工关系等一系列标准化服务的子品牌。努力的方向就是从员工角度出发,解决问题,满足员工工实际需求。

比如,以前的福利都是公司指定的,员工抱怨这个项目我没用,能不能换成别的?行啊,我们搞一个弹性福利系统,让员工在自己的福利额度内,自行选择福利项目组合,好不好?
比如,员工最近工作压力大,很多人情绪有点失控,如果预计到压力将持续存在,我们可不可以建立员工帮助计划EAP,让员工有问题可以打电话寻求心理辅导,平时也会提供心理健康讲座,好不好?
比如,老有员工抱怨培训不提前通知,临时安排与工作冲突,很想参加却参加不了。那能不能做一个培训系统,显示近期培训课程日历,当然对于往期的课程,也可以放个当时视频,员工在内网看看也成,好不好?
就这么说吧,围绕每年的敬业度调查报告,看看有哪些是SSC可以做的,每年选出来1、2个点作为努力方向,相信SSC会变成人力资源部里最火热的一个模块。

  • 搞数据

SSC每年做了那么多单业务,服务了那么多员工,交付了那么多招聘离职等等服务,发了那么多工资福利,最后只报个总数未免和咱们人力资源转型的深远意义相去太远了。
当我们抓着大把的数据,就要向数据要效益。充分学习一些人力资源和心理学的一些概念,结合公司营收和利润,对招聘、薪酬、绩效、离职等等数据进行一些深入的分析,作为领导决策的分析依据,那不就把SSC做出了COE的逼格嘛。

要想上面写的这样做好SSC也不是没有要求,那就是你得懂得心理学,全面薪酬、福利沟通、敬业度、组织承诺、离职倾向、弹性福利……,只有更懂心理学、组织行为学、人事经济学,才能找准方向下锄头,轻轻松松出成绩。


]]>
taoCMS-基于php+sqlite最小巧的CMS 2021-12-15 21:12:22
1240 win10内置ubuntu, “指定的网络名不再可用”解决办法

昨天电脑关机后, 今天打开启动Ubuntu子系统提示, 指定的网络名不再可用






百度的都是错误的, 特别记录正确的解决方法


搜索框搜索, 启用或关闭Windows功能


打开虚拟机平台, 重启电脑






尝试解决方案: 


在cmd中运行, 打开Hyper-V


bcdedit /set hypervisorlaunchtype auto
————————————————
版权声明:本文为CSDN博主「idjl」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010071211/article/details/113857825]]>
taoCMS-基于php+sqlite最小巧的CMS 2021-12-11 20:12:32
1239 Openconnect VPN 服务端 ocserv 的部署

ocserv(Openconnect VPN Server)是一款开源的、兼容Cisco Anyconnect VPN的VPN服务端软件。由于思科在网络设备中的特殊地位,思科的V...
 
 
ocserv(Openconnect VPN Server)是一款开源的、兼容Cisco Anyconnect VPN的VPN服务端软件。由于思科在网络设备中的特殊地位,思科的VPN一直未被特殊照顾(其实这个VPN握手过程特征应该是较为明显的)。目前状况下通讯较为稳定,干扰较小。主要优势是多平台的支持,Windows、Android、iOS都能找到它的客户端。往往可以作为shadowsocks等代理的补充。
下面简要介绍一下部署过程,以在Ubuntu系统中的部署为例。

主页: http://www.infradead.org/ocserv/

下载页面: ftp://ftp.infradead.org/pub/ocserv/

首先在上面的下载页面中找到最新的Release后使用wget下载并解压:

Shell

wget ftp://ftp.infradead.org/pub/ocserv/ocserv-0.9.2.tar.xz
tar -Jxvf ocserv-0.9.2.tar.xz
cd ocserv-0.9.2必选依赖包:

Shell

apt-get install libgnutls28-dev可选依赖包:

Shell

apt-get install pkg-config libwrap0-dev libpam0g-dev liblz4-dev libseccomp-dev libreadline-dev libnl-route-3-dev编译工具:

apt-get install build-essential autogen编译安装:

Shell

./configure && make
make install接下来是配置,建立

/ etc / ocserv

文件夹来存储相关的配置文件:

1. 下载下来的ocserv中的

doc 文件夹中有 sample . config 这一例子文件,将其拷贝至 / etc / ocserv
,命名为

ocserv . conf

,用来存储ocserv的配置信息;

2. 新建

/ etc / ocserv / ocpasswd

文件用来存储用户名密码

3. 将PEM格式的服务器证书,存储至

/ etc / ocserv / server - cert . pem

文件中(包含证书链中的中级证书)

4. 将PEM格式的服务器私钥,存储至

/ etc / ocserv / server - key . pem

文件中

5. 将PEM格式的根证书,存储至

/ etc / ocserv / ca - cert . pem

文件中

(PS:想要客户端连接没有证书错误提示的,可以试试使用StartSSL的免费证书。)

接着修改

/ etc / ocserv / ocserv . conf

文件:

设置认证方式为plain,存储文件改成刚才设置的

/ etc / ocserv / ocpasswd

文件:

auth = "plain[/etc/ocserv/ocpasswd]"可以修改允许同时连接的最大客户端数:

max-clients = 16同一个账号能连接的最大客户端数:

max-same-clients = 2修改ocserv使用的端口(客户端连接时候不填写端口的话默认使用443 使用非443端口时候,服务器填写:域名:端口号 这样的形式):

tcp-port = 443
udp-port = 443修改服务器证书和私钥配置:

server-cert = /etc/ocserv/server-cert.pem
server-key = /etc/ocserv/server-key.pem修改根证书配置:

ca-cert = /etc/ocserv/ca-cert.pem建议将dpd和cookie-timeout改大,避免客户端网络波动时候总是掉线以及无法及时自动重连:

dpd = 600
cookie-timeout = 32400配置VPN子网的的网段:

ipv4-network = 10.250.250.0
ipv4-netmask = 255.255.255.0配置DNS服务器:

dns = 8.8.8.8
dns = 8.8.4.4将其他私有地址排除,不路由:

no-route = 192.168.0.0/255.255.0.0
no-route = 172.16.0.0/255.240.0.0
no-route = 169.254.0.0/255.255.0.0
no-route = 127.0.0.0/255.0.0.0添加自启动,下面给出一个init.d脚本的sample,放到

/ etc / init . d / ocserv

并给上755权限:

点击展开全部内容

配置自启动,使用update-rc.d命令:

Shell

update-rc.d ocserv defaults启动:

service ocserv start添加用户,例:用户名testuser,密码test,用户组vpnusers:

ocpasswd -c /etc/ocserv/ocpasswd -g vpnusers vpnuser然后连续两次键入密码即可。

修改

/ etc / sysctl . conf

打开ipv4_forward:

net.ipv4.ip_forward = 1执行以下命令使其生效:

Shell

sysctl -p配置iptables转发,注意和前面配置的网段保持一致:

Shell

iptables -A FORWARD -s 10.250.250.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.250.250.0/24 -o eth0 -j MASQUERADE
iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
iptables -A FORWARD -o vpns+ -j ACCEPT
iptables -A FORWARD -i vpns+ -j ACCEPT

]]>
taoCMS-基于php+sqlite最小巧的CMS 2021-10-05 02:10:02