Python知识

本篇文章包含Python语法,操作系统内容。

Python语言

1.元类

元类: 类的类,非常的不常用,写框架的时候用到(但是我没写过…..)。
stackoverflow:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python

2.字符串格式化

方式1:使用 %
name = ‘Cooper’
‘Hi, My name is %s’ % name
% 不能同时传递多个变量或者元组,如果是name是(Cooper, Lily), 会抛出TypeError,所以为了保证准确,要这样做:
‘Hi My name is %s’ % (name, ) # 提供一个单元素的数组而不是一个参数

方式2:使用format
format不会出现以上的问题。
stackoverflow:http://stackoverflow.com/questions/5082452/python-string-formatting-vs-format

3.Python中下划线

__name__ : Python内部的名字,区分用户自定义的命名 
_name : 指定变量为私有
__name : 解释器用_classname__name 代替这个名字,用以区分其他类似相同的命名。

知乎:http://www.zhihu.com/question/19754941

4.内建函数

内建函数是python解释器启动后默认加载的属性和函数。
可以在ipython下使用命令dir(__builtins__)查看。

  • range
  • xrange
  • map
    map函数根据提供的函数对指定的序列做映射。
    实例1:

    map(lambad x: x*x, [1 ,2, 4]) # 输出结果是:[1, 4, 9]

实例2:

def f1(x, y):
    return (x, y)

l1 = [0, 1, 2, 3, 4, 5, 6]
l2 = ['Sun', 'M', 'T', 'W', 'T', 'F', 'S'] 
l3 = map(f1, l1, l2)     # 参数:map(提供的函数, 指定的序列1,指定的序列2)
# 输出 [(0, 'Sun'), (1, 'M'), (2, 'T'), (3, 'W'), (4, 'T'), (5, 'F'), (6, 'S')]
  • reduce

    5.内建属性(魔法方法)

匿名函数

4. 函数传参既不是传值也不是传引用

函数传参到底传递的是什么,传值,传参,还有的说是可变对象传引用,不可变对象传值。
其实都是不对的,函数传参传递的对象,或者说传递对象的引用。
函数的传递过程中,将整个对象传入,对于可变对象的修改在函数的外部以及内部都可见,调用者和被调用者之间可以共享这个对象;而对于不可变对象,因为不能被修改,因此修改是通过生成一个新的对象然后赋值来实现的。

5. print和stdout.write区别

print方法实际调用的是sys.stdout.write(obj + ‘\n’)。也就是在print方法中自带了一个换行的功能。
但是在sys.stdout.write中,并没有换行。所以:

sys.stdout.write('hello' + '\n')  
print('hello')

这二句是一样的作用。

Python装饰器

查看我的另一篇文章:Python-装饰器

操作系统

1.死锁

原因:

1. 竞争资源
2. 程序推进顺序不当

必要条件:

1. 互斥条件
2. 请求和保持条件
3. 不剥夺条件
4. 环路等待条件

处理死锁基本方法:

1. 预防死锁(摒弃除1以外的条件)
2. 避免死锁(银行家算法)
3. 检测死锁(资源分配图)
4. 解除死锁
5. 剥夺资源

2.select, poll, epoll

三者都是I/O轮循的方式,但实现的层面不同。
区别总结:http://www.cnblogs.com/Anker/p/3265058.html
select的缺点:

1. 连接个数限制
2. 查找配对速度慢
3. 数据从内核拷贝到用户空间

epoll改善了这3三个缺点:链接:http://www.cnblogs.com/my_life/articles/3968782.html

面试题汇总

题1:

In [18]: a = 21

In [19]: b = 'str'  

请问: a and b 返回是什么,a or b 返回是什么。
答案:

In [20]: a and b
Out[20]: 'str'

In [21]: b and a
Out[21]: 21

In [22]: a or b
Out[22]: 21

In [23]: b or a
Out[23]: 'str'  

由上述可知,and 连接时,返回是后者;or连接时,返回的是前者。
在 and 连接时,只要不是包含 0 或者 False, 都会遵循上述结论。如果包含None, 则无返回。
在 or 连接时, 只要其中一个非0或者不是False,则都会返回非0或者非False的那个。 0, False, None都是相当于假。

题2:数据库查询

如下表格(A是字段):

A
a
a
b

写出查询语句,并且是按照降序,得出:
|a|2|
|–|–|
|b|1|

题3:

def foo(*args, **kwargs):
    print("args=", args)
    print("kwargs=", kwargs)
    print("=================")

foo(1, 2, 3)
foo(a=1, b=2)
foo(1, 2, 3, a=1, b=2)
foo('a', 1, None, a=1, b=2)

以下是输出:

args= (1, 2, 3)
kwargs= {}
=================
args= ()
kwargs= {'a': 1, 'b': 2}
=================
args= (1, 2, 3)
kwargs= {'a': 1, 'b': 2}
=================
args= ('a', 1, None)
kwargs= {'a': 1, 'b': 2}
=================  

*args是位置参数,**kwargs是关键字参数。在输出的时候,args是以元组的形式输出,kwargs是以字典的形式输出。

题4:

将一个数组进行全排列:
数组list = [‘a’, ‘b’, ‘c’]
实际全排是对元素的下标进行重新排序。
代码:

from sys import stdout

def perm(li, start, end):
  if(start == end):
    for elem in li:   # 这里构造的是新的数组而已,全部输出就是新的排列内容
      stdout.write(elem)
    print ''   # 添加这个是为了换行
  else:
    for i in range(start, end):
      li[start], li[i] = li[i], li[start]  
      perm(li, start+1, end)           # +1 改变的是组合的前缀字母
      li[i], li[start] = li[start], li[i]
if __name__ == '__main__':
  li = ['a','b','c','d']
  perm(li, 0, len(li))

输出:

abcd
abdc
acbd
acdb
adcb
adbc
bacd
badc
bcad
bcda
bdca
bdac
cbad
cbda
cabd
cadb
cdab
cdba
dbca
dbac
dcba
dcab
dacb
dabc