去年的Python工程师面试题

来源:互联网 发布:2015 日本进出口数据 编辑:程序博客网 时间:2024/05/12 12:14

这是一年前应聘一家游戏公司后台Python工程师的笔试题,由对方发给我,我在当晚花了几个小时查资料做的。

那会对Python基本就属于有点基础语法的认识,发在百度文库居然浏览量-下载量=1,发在blog里面show下。黑颜色以外的部分以及所有答案是我回答的。



[讲解]
什么是 lambda函数?它有什么好处?另外 python在函数式编程方面提供了些什么函数和语
法?
Lambda是一种单行的表达式函数,主要好处就是能简化代码,不需要定义一些简单功能的
函数
Python中,函数可以作为参数传入,也可以作为结果被返回
提供了 lambada语法方便编程
提供了以下内置函数:
filter(function, iterable)
map(function, iterable, ...)
reduce(function, iterable[, initializer])
zip([iterable, ...])
详细说说 tuplelistdict的用法,它们的特点;
三者的用法可参考:http://blog.sina.com.cn/s/blog_540775a30101bhhx.html
Tuple一旦创建即不能进行修改(删除/增加/修改元素),但是其访问效率较高,且能保护常
量数据不被更改,所以适合于存储一些常量数据
List 适合于需要动态增删改的数据集,但不适用于需要查找的使用;因为其实现类似于 C
中的数组,也不适应于需要经常在 list 之间插入数据的场景。
Dict 就像很多语言中的 hash,可能在内部使用了红黑树或者其他数据结构存储了数据,以
达到快速定位的功能
说说 python 中装饰器、迭代器的用法;描述下 dict items() 方法与 iteritems() 方法的不
同;
装饰器即是装饰器在 python 中的使用,主要用于为类/函数动态添加新的功能,python
的用法如下:
def deco(func):
def _deco():
print("before myfunc() called.")
func()
print(" after myfunc() called.")
# 不需要返回func,实际上应返回原函数的返回值
return _deco
@deco
def myfunc():
print(" myfunc() called.")
return 'ok'
myfunc()
如果 obj 实现了__iter__以及Next(), 我们可以使用 iter(obj)来获取迭代器:并可以使用如下
方法进行访问:
fetch = iter(seq)
while 1:
try:
i = fetch.next()
except StopIteration:
break
#do_something_to(i)
dictitems()返回的是一个包含<KEY, VALUE>pairlist 对象
dict iteritems()返回的是一个可以遍历<KEY, VALUE>pair的迭代器iterator,C++中迭代器
类似,可以使用一些通用函数对其进行遍历处理
知道 greenletstackless吗?说说你对线程、协程、进程的理解;
greenlet类似于 goto 语句的功能,但是在函数或者说微线程之间实现了跳转,且在结束后
能自动回到调用处
一个 “greenlet” 是一个很小的独立微线程。可以把它想像成一个堆栈帧,栈底是初始调用,
而栈顶是当前 greenlet 的暂停位置。你使用 greenlet 创建一堆这样的堆栈,然后在他们之间
跳转执行。跳转不是绝对的:一个 greenlet 必须选择跳转到选择好的另一个 greenlet,这会
让前一个挂起,而后一个恢复。两 个 greenlet 之间的跳转称为 切换(switch)
当你创建一个 greenlet,它得到一个初始化过的空堆栈;当你第一次切换到它,他会启动指
定的函数,然后切换跳出 greenlet。当最终栈底 函数结束时, greenlet 的堆栈又编程空的了,
greenlet 也就死掉了。greenlet也会因为一个未捕捉的异常死掉。
stacklesspython 的一个协程实现版本?还没有仔细看。
线程,进程是比较经典的概念了,进程可以包括文件句柄等系统资源的单位,线程一般是
现代 CPU 的基本调度单位
而协程是通过用户调度,切换的消耗要小于线程/进程的切换。
协程的优势在于可以自己控制切换,适合于顺序执行的一些情况,而线程更加适合并行处
理数据的情况;同时使用协程可以控制调度,减少切换的消耗。
讲讲对 unicode, gbk, utf-8 等的理解,python2.x是如何处理编码问题?
UnicodeGBK是对字符编码值的规定,两者并不兼容。而 UTF-8 则是对于 Unicode 编码的具
体表现形式
Unicode 有多种表达方式,包括 UCS2,UCS4,UTF-8,UTF-7;其中手机短信就是由ASCII(只存在
ASCII 编码)UCS2 编码混合(存在任意个非ASCII 编码)
UTF-8 使用 1-4 个字节来存储单个字符,应该是目前最流行的字符集。Linux 默认字符集就是
UTF-8
一般代码头行加入 # -*- coding: utf-8 -*-
保证 python 编辑器的编码正确,或使用 u’中文保证被转换成unicode 编码,推荐使用
sys.setdefaultencoding('utf-8')来保证我们的编码
对外来输入:读取文件/读取数据库 得到的字符串使用decode
Python 是如何进行内存管理的?python 的程序会内存泄露吗?说说有没有什么方面防止或
检测内存泄露?
Python使用引用计数来实现内存管理,每一个对象都拥有引用计数,表示正在引用它的变
量个数;如果一个引用的变量出了作用域,那么对象引用计数减 1,如果引用计数到 0,内
存回收模块会回收
如果对象实现了__del__函数,那么对象间的交叉引用将导致__del__无法被调用,而本该在
__del__中释放的资源(比如数据库的连接)将无法释放
某些全局变量占用的资源不能被释放
可以使用 objgraph 工具进行对内存的监控及检测
关于 python 程序的运行性能方面,有什么手段能提升性能?
合理的使用数据结构:比如由于 dict 使用了 hash table,当需要经常在大容量 list 中使用查
找时,将 list 转换成 dict 将大大提高性能
在一些性能瓶颈问题上,考虑使用 c/c++库来实现,将大大提高程序性能
1. 使用内建函数
2. 使用 join()连接字符串.
3. 使用 Python 多重赋值,交换变量
4. 尽量使用局部变量
5. 尽量使用 "in"
6. 使用延迟加载加速
7. 为无限循环使用 "while 1"
8. 使用 list comprehension
9. 使用 xrange()处理长序列
10. 使用 Python generator
11. 了解 itertools 模块
12. 学习 bisect 模块保持列表排序
13. 理解 Python 列表,实际上是一个数组
14. 使用 dict set 测试成员
15. 使用 Schwartzian Transformsort()
16. Python 装饰器缓存结果
17. 理解 Python GIL(全局解释器锁)
[写程序]
list 对象 alist [{'name':'a','age':20},{'name':'b','age':30},{'name':'c','age':25}], 请按alist 中元素的
age 由大到小排序;
alist = [{'name':'a','age':20},{'name':'b','age':30},{'name':'c','age':25}]
alist.sort(cmp=lambdal,r:l['age']-r['age'], key=None, reverse=False)
print alist
# OR
alist = [{'name':'a','age':20},{'name':'b','age':30},{'name':'c','age':25}]
alist.sort(key=lambdak:k['age'])
print alist
两个 list 对象 alist ['a','b','c','d','e','f'], blist ['x','y','z','d','e','f'],请用简洁的方法合并这两个list
并且 list 里面的元素不能重复;
alist = ['a','b','c','d','e','f']
blist = ['x','y','z','d','e','f']
clist=list(set(alist) | set(blist))
print clist
打乱一个排好序的 list 对象 alist
import random;
alist = ['a','b','c','d','e','f']
random.shuffle(alist)
print alist
#OR
import random;
alist = ['a','b','c','d','e','f']
random.seed()
alist.sort(key=lambdak:random.random())
print alist
简单实现一个 stack
class Stack:
def __init__(self):
self.items = []
def __iter__(self):
return self.items.__iter__()
def pop(self):
return self.items.pop()
def top(self):
if len(self.items) >0:
return self.items[len(self.items)-1]
def push(self, item):
self.items.append(item)
def empty(self):
self.items = []
def size(self):
return len(self.items)
st = Stack()
st.push(8)
st.push(5)
st.push(4)
st.push(2)
st.push(6)
print st.top()
print st.pop()
print st.top()
print max(st)
输入某年某月某日,判断这一天是这一年的第几天?(可以用python 标准库)
# -*- coding: utf-8 -*-
#标准库版本
import re;
import time;
import datetime;
def getSequenceDayOfYear(year, month, day):
return int(datetime.datetime(year, month, day).strftime("%j"))
print (getSequenceDayOfYear(2014,3,27))
#自己实现版本
# -*- coding: utf-8 -*-
def getSequenceDayOfYear1(year, month, day):
lstNotLeap = [31,28,31,30,31,30,31,31,30,31,30,31]#非闰年
lstLeap = [31,29,31,30,31,30,31,31,30,31,30,31]#闰年
lst =[]
if month <1 ormonth >12:
print 'wrong month'
return 0
if (year %4 ==0)and (year %100 !=0)or (year %400 ==0):
lst = lstLeap
else:
lst = lstNotLeap
if day <1 orday > lst[month-1]:
print 'wrong day'
return 0
totalDays = 0# sum(lst.__getslice__(), 12-month)+day
for iin range(0, month-1):
totalDays = totalDays+lst[i]
totalDays = totalDays + day
return totalDays
print (getSequenceDayOfYear1(2014,3,27))
将字符串:"k:1|k1:2|k2:3|k3:4",处理成python 字典:{k:1, k1:2, ... }
# -*- coding: utf-8 -*-
s = "k:1|k1:2|d|k2:3|k3:4"
dict={}
lst = s.split('|')
for pairin lst:
try:
lstPair = pair.split(':')
dict[lstPair[0]] = lstPair[1]
except:
pass
print dict


0 0
原创粉丝点击