Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
root committed Mar 18, 2018
1 parent 4cf44ef commit 61b78d6
Show file tree
Hide file tree
Showing 10 changed files with 428 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"python.linting.pylintEnabled": false
}
67 changes: 67 additions & 0 deletions py-tip/mysort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# coding:utf-8

def quick_sort(NM,L,R):
if L>=R:return
key = NM[L]
low,high = L,R
while L<R:
while L<R and NM[L]<=key:
L+=1
while L<R and NM[R]>key:
R-=1
NM[L],NM[R] = NM[R],NM[L]
if NM[L-1]<key:
NM[low]=NM[L-1]
NM[L-1] = key
print L-2,L,NM[L-2],NM
quick_sort(NM,low,L-2)
quick_sort(NM,L,high)
return NM
def select_sort(NM):
"""
基本思想:第1趟,在待排序记录r1 ~ r[n]中选出最小的记录,将它与r1交换;
第2趟,在待排序记录r2 ~ r[n]中选出最小的记录,将它与r2交换;
以此类推,第i趟在待排序记录r[i] ~ r[n]中选出最小的记录,将它与r[i]交换,
使有序序列不断增长直到全部排序完毕。
"""
l = len(NM)
for i in range(l):
min = NM[i]
for j in range(i+1,l):
if NM[j]<NM[i]:
NM[i],NM[j]=NM[j],NM[i]
return NM

def insert_sort(NM):
"""
插入排序原理很简单,讲一组数据分成两组,我分别将其称为有序组与待插入组。
每次从待插入组中取出一个元素,与有序组的元素进行比较,并找到合适的位置,
将该元素插到有序组当中。就这样,每次插入一个元素,有序组增加,待插入组减少。
直到待插入组元素个数为0。当然,插入过程中涉及到了元素的移动。
"""
l = len(NM)
for i in range(1,l):
key = NM[i]
j = i-1
while j>=0:
print NM[j],key,NM
if NM[j]<key:
NM[j+1]=NM[j]
NM[j]=key
j-=1
return NM

def bubble_sort(NM):
l = len(NM)
for i in range(l):
for j in range(i+1,l):
if NM[i]>NM[j]:
NM[j],NM[i] = NM[i],NM[j]
return NM
if __name__=='__main__':
N = [2,4,1,2,3,42,1,4,2,6,1,7,8,7,2]
# NM = quick_sort(N,0,len(N)-1)
# NM = select_sort(N)
# NM = insert_sort(N)
NM = bubble_sort(N)
print NM
2 changes: 2 additions & 0 deletions py-tip/sort.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ def bobble_sort(lists):
return lists




def quick_sort(l,left,right):
"""
参考http://developer.51cto.com/art/201403/430986.htm
Expand Down
1 change: 0 additions & 1 deletion tornado/tornadofileserver/tornadofileserver/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
class Application(tornado.web.Application):
def __init__(self):
handlers = [
# (r"/", IndexHandler),
(r"\/*.*", IndexHandler),
]
settings = dict(
Expand Down
13 changes: 13 additions & 0 deletions 面试/class_var.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Person:
name=[]

p1=Person()
p2=Person()
# p1.name.append(1)
# print p1.name # [1]
# print p2.name # [1]
# print Person.name # [1]
p1.name = [2]
print p1.name # [1]
print p2.name # [1]
print Person.name # [1]
75 changes: 75 additions & 0 deletions 面试/decorate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# coding:utf-8
import time
import logging
from functools import wraps

"""
warps:
Python装饰器(decorator)在实现的时候,
被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),
为了不影响,Python的functools包中提供了一个叫wraps的decorator来消除这样的副作用。
写一个decorator的时候,最好在实现之前加上functools的wrap,它能保留原有函数的名称和docstring。
"""

#装时器限定函数运行次数
def fun_time(t):
_dict={}
def decorate(fun):
@wraps(fun)
def inner(*arg,**kw):
# print len(_dict),_dict
if len(_dict)<t:
_dict[time.time()] = fun
fun(*arg,**kw)
# print fun.__name__
else:
return None
return inner
return decorate

#装时器限定函数10s运行n次数
def fun_time2(t,during):
_dict={}
def decorate(fun):
_name = str(fun.__name__)
_dict.setdefault(_name,[])
print _name
def inner(*arg,**kw):
# print len(_dict),_dict
if _dict[_name]:
if len(_dict[_name])<t:
_dict[_name].append(time.time())
fun(*arg,**kw)
elif _dict[_name][-1]<(time.time()-during):
_dict[_name]=[time.time()]
fun(*arg,**kw)
else:
return None
else:
_dict[_name].append(time.time())
fun(*arg,**kw)
return inner
return decorate

@fun_time(2)
def args(*args,**kw):
print args,kw



if __name__ == '__main__':
# args(1,2,3,a=2)
args(*(1,),**{'a':2})
args(*(2,),**{'a':2})
print args.__name__
# time.sleep(1)
args(*(3,),**{'a':2})
args(*(4,),**{'a':2})
args(*(5,),**{'a':2})







11 changes: 11 additions & 0 deletions 面试/itertools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#coding:utf-8
#来一个例子?让我们看看4匹马比赛有多少个排名结果:
import itertools
def horse(a):
print list(itertools.permutations(a))

def main():
pass

if __name__ == '__main__':
horse(range(3))
95 changes: 95 additions & 0 deletions 面试/python面试题.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
双十一你们的手还健在吗? 还在的话来刷一波题?

希望此文可以长期更新并作为一篇Python的面试宝典。每一道题目都附有详细解答,以及更加详细的回答链接。此篇是概念篇,下一篇会更新面试题代码篇。

(一)、这两个参数是什么意思:*args,**kwargs?我们为什么要使用它们?

答:如果我们不确定往一个函数中传入多少参数,或者我们希望以元组(tuple)或者列表(list)的形式传参数的时候,我们可以使用*args(单星号)。如果我们不知道往函数中传递多少个关键词参数或者想传入字典的值作为关键词参数的时候我们可以使用**kwargs(双星号),args、kwargs两个标识符是约定俗成的用法。

另一种答法:当函数的参数前面有一个星号*号的时候表示这是一个可变的位置参数,两个星号**表示这个是一个可变的关键词参数。星号*把序列或者集合解包(unpack)成位置参数,两个星号**把字典解包成关键词参数。



(二)、谈一谈Python的装饰器(decorator)

装饰器本质上是一个Python函数,它可以让其它函数在不作任何变动的情况下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景。比如:插入日志、性能测试、事务处理、缓存、权限校验等。有了装饰器我们就可以抽离出大量的与函数功能无关的雷同代码进行重用。

有关于具体的装饰器的用法看这里:装饰器 - 廖雪峰的官方网站

(三)、简要描述Python的垃圾回收机制(garbage collection)

Python中的垃圾回收是以引用计数为主,标记-清除和分代收集为辅。

引用计数:Python在内存中存储每个对象的引用计数,如果计数变成0,该对象就会消失,分配给该对象的内存就会释放出来。
标记-清除:一些容器对象,比如list、dict、tuple,instance等可能会出现引用循环,对于这些循环,垃圾回收器会定时回收这些循环(对象之间通过引用(指针)连在一起,构成一个有向图,对象构成这个有向图的节点,而引用关系构成这个有向图的边)。
分代收集:Python把内存根据对象存活时间划分为三代,对象创建之后,垃圾回收器会分配它们所属的代。每个对象都会被分配一个代,而被分配更年轻的代是被优先处理的,因此越晚创建的对象越容易被回收。

如果你想要深入了解Python的GC机制,点击这里:[转载]Python垃圾回收机制--完美讲解!

(四)、Python多线程(multi-threading)。这是个好主意吗?

Python并不支持真正意义上的多线程,Python提供了多线程包。Python中有一个叫Global Interpreter Lock(GIL)的东西,它能确保你的代码中永远只有一个线程在执行。经过GIL的处理,会增加执行的开销。这就意味着如果你先要提高代码执行效率,使用threading不是一个明智的选择,当然如果你的代码是IO密集型,多线程可以明显提高效率,相反如果你的代码是CPU密集型的这种情况下多线程大部分是鸡肋。

想要深入详细了解多线程,点击这里:详解Python中的多线程编程_python

想了解一下IO密集和CPU密集可以点击这里:CPU-bound(计算密集型) 和I/O bound(I/O密集型)

(五)、 说明os,sys模块不同,并列举常用的模块方法?

官方文档:

os模板提供了一种方便的使用操作系统函数的方法
sys模板可供访问由解释器使用或维护的变量和与解释器交互的函数

另一种回答:

os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口。sys模块负责程序与Python解释器的交互,提供了一系列的函数和变量用户操作Python运行时的环境。

一些常用的方法:
一些常用的用法示例:

想要了解更详细的使用请访问:os和sys模块 - 君醉

(六)、什么是lambda表达式?它有什么好处?

简单来说,lambda表达式通常是当你需要使用一个函数,但是又不想费脑袋去命名一个函数的时候使用,也就是通常所说的匿名函数。

lambda表达式一般的形式是:关键词lambda后面紧接一个或多个参数,紧接一个冒号“:”,紧接一个表达式。lambda表达式是一个表达式不是一个语句。

想更加详细的了解Python中的Lamdba表达式可以点击这里:Lambda 表达式有何用处?如何使用? - Python

(七)、Python中pass语句的作用是什么?

pass语句不会执行任何操作,一般作为占位符或者创建占位程序

(八)、Python是如何进行类型转换的?

Python提供了将变量或值从一种类型转换为另一种类型的内置方法。
(九)、Python里面如何拷贝一个对象?

Python中对象之间的赋值是按引用传递的,如果要拷贝对象需要使用标准模板中的copy

copy.copy:浅拷贝,只拷贝父对象,不拷贝父对象的子对象。
copy.deepcopy:深拷贝,拷贝父对象和子对象。

(十)、__new____init__的区别。

__init__为初始化方法,__new__方法是真正的构造函数。
__new__是实例创建之前被调用,它的任务是创建并返回该实例,是静态方法
__init__是实例创建之后被调用的,然后设置对象属性的一些初始值。

总结:__new__方法在__init__方法之前被调用,并且__new__方法的返回值将传递给__init__方法作为第一个参数,最后__init__给这个实例设置一些参数。

想要更加详细的了解这两个方法,请点击:Python中的__new__及其用法

(十一)、Python中单下划线和双下划线分别是什么?

__name__:一种约定,Python内部的名字,用来与用户自定义的名字区分开,防止冲突
_name:一种约定,用来指定变量私有
__name:解释器用_classname__name来代替这个名字用以区别和其他类相同的命名

想要更加详细的了解这两者的区别,请点击:Python中的下划线(译文)

(十二)、说一说Python自省。

自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型。简单一句话就是运行时能够获得对象的类型。比如:type()、dir()、getattr()、hasattr()、isinstance()
55 changes: 55 additions & 0 deletions 面试/read_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#coding:utf-8
# 用Python读取大文件(上)
#方法一:
"""
利用open(“”, “”)系统自带方法生成的迭代对象
for line in f 这种用法是把文件对象f当作迭代对象,
系统将自动处理IO缓冲和内存管理, 这种方法是更加pythonic的方法。 比较简洁。
"""
with open('class_var.py') as f:
for line in f:
print line


#方法二:

"""将文件切分成小段,每次处理完小段内容后,释放内存
这里会使用yield生成自定义可迭代对象, 即generator, 每一个带有yield的函数就是一个generator。 """
#此方法不一定按行读取
def read_in_block(file_path):
BLOCK_SIZE = 1024
with open(file_path, "r") as f:
while True:
block = f.read(BLOCK_SIZE) # 每次读取固定长度到内存缓冲区
if block:
yield block
# import pdb;pdb.set_trace()
else:
return # 如果读取到文件末尾,则退出


def test3():
file_path = "class_var.py"
for block in read_in_block(file_path):
print block


## 以下不可取!!!!!!!!!!!!!!!

"""read ()的方法是一次性把文件的内容以字符串的方式读到内存, 放到一个字符串变量中
readlines()的方法是一次性读取所有内容, 并按行生成一个list
因为read()和readlines()是一次性把文件加载到内存, 如果文件较大,
甚至比内存的大小还大, 内存就会爆掉。 所以,这两种方法只适合读取小的文件。 """
def test1():
with open("/tmp/test.log", "r") as f:
print f.read()

def test1():
with open("/tmp/test.log", "r") as f:
print f.read()


if __name__ == '__main__':
test3()
Loading

0 comments on commit 61b78d6

Please sign in to comment.