最近面试的时候在一家某券商企业遇到了一些关于python的问题,作为一名数据挖掘人员,虽然经常使用python,但是对于一些所以然的问题发现思考还是不深,或者以前在学习的时候有研究过,但是在工作中因为很少使用,所以就淡忘了。欢迎各位在评论区提供优质答案。
1. 已知一个无序数字列表,里面只有一个元素是频数为1,找出这个元素。
看到这个问题以后,笔者的第一反应是首先word count,然后找出频率值为1的元素;第二反应是利用hash code思想快速把相同的元素映射到同一个分区中;第三反应是首先对列表排序,然后遍历列表,如果某个元素和前后邻居元素都不同,则该元素就是所要查找的值,下面分别解释这三种方法:
(1)word count
直接统计的思想最为简单直接,可以直接统计,也可以转换为numpy、pandas类型使用group by计算,当然后者显然不是面试官想要的答案,不过可以提一下凸显自己的知识面,尤其是collections工具包:
from collections import Counter
## 利用collections
def f1(data):
for key, value in Counter(data).items():
if value == 1:
return key
return None
## 利用列表直接统计
def f2(data):
for i in set(data):
if data.count(i) == 1:
return i
return None
## 利用字典统计
def f3(data):
tmp = {}
for value in data:
tmp[value] = tmp.get(value, 0) + 1
for key, value in tmp.items():
if value == 1:
return key
return None
(2)列表排序
上面的方法,虽然可以实现功能,但是或多或少都是借用了python内置的功能,未必能给面试官留下更深的印象。下面先排序、再比较的处理方法也可以实现功能,虽然时间复杂度看起来要高些,但是可以凸显自己的发散思维:
def f4(data):
tmp = data.copy()
tmp.sort()
for i in range(len(tmp)-1):
if i==0 and tmp[0] != tmp[1]:
return tmp[0]
if i==len(tmp)-2 and tmp[-1] != tmp[-2]:
return tmp[-1]
if tmp[i] != tmp[i-1] and tmp[i] != tmp[i+1]:
return tmp[i]
return None
这里需要注意尽量不要改变原始数据,当然上面也没有考虑短数组的越界问题。
(3)参考hash code思想
在很多工具组件里面做数据分区的时候,利用的都是hash code思想,但是本人苦于虽然知道这种思想,但是从没在程序方面做过操作,不知道相关的API和函数,不过我们可以借用set来操作。为什么用set呢?因为set的in操作时间复杂度远远低于list:
def f5(data):
t1 = set()
t2 = set()
for value in data:
if value in t2:
pass
elif value in t1:
t2.add(value)
t1.remove(value)
else:
t1.add(value)
return t1
※ 面试的时候如果能够从不同角度进行发散,即使答案不是最优的,也是一种加分项。对于很多人来说,因为各种因素,在面试的时候只能发挥出七层左右的实力,有些问题(尤其是逻辑性问题),如果不是曾经接触过,确实难以在较短的时间内想出最优答案。
2. python装饰器
装饰器算是python里面为数不多的有python特色,面试官又喜欢问的问题了吧,网上资料很多,就不多做介绍了。
3. python多线程调度
都知道python多线程是伪多线程,GIL锁使得python同一个时刻只有一个线程在一个cpu上执行字节码,并且无法将多个线程映射到多个cpu上,即不能发挥多个cpu的优势。假如有十个任务,每个任务需要执行10s,十个就是100s,如果使用10个线程,是不是还是100s呢?什么情况下可能会出现远低于100s的情况呢?