zoukankan      html  css  js  c++  java
  • Some Interview Questions About Python

    一大波超链接即将袭来

    Django认证流程
    Python实现阶乘
    Python文件处理
    Python统计日志文件IP出现次数
    JSON数据解析
    JSON数据解析2
    买卖股票的最佳时期

    读取一个大文件比如500M,计算出每一个字的频率,分别把前十频率的求出来。

    def str_count(filename):
        f = open(filename,'r',encoding='utf-8')
        dic = {}
        while True:
            line = f.readline()
            if line:
                for s in line:
                    if s in dic:
                        dic[s]+=1
                    else:
                        dic[s]=1
            else:
                break
        result = sorted(dic.items(), key=lambda k: k[1], reverse=True)
        print(dic)
        print(result)
    
    str_count(r'C:UsersAdministratorDesktop	ext.txt')
    ----------------------英文单词频率
    def word_count(filename):
        f = open(filename,'r')
        dic = {}
        while True:
            line = f.readline()
            if line:
                line = line.replace(',','')
                line = line.replace('.','')
                line = line.replace('!','')
                line = line.replace(';','')
                line = line.replace('-','')
                str_list = line.split()
                for s in str_list:
                    if s.lower() in dic:
                        dic[s.lower()]+=1
                    else:
                        dic[s.lower()] = 1
            else:
                break
        result = sorted(dic.items(), key=lambda k: k[1], reverse=True)
    
        print(result)
    word_count(r'C:UsersAdministratorDesktopabc'
               r'.txt')
    

    线程之间如何进行通信?

    1、通过queue(队列),基于queue共享数据,使用 put() 和 get() 操作来向队列中添加或者删除元素,实现线程之间的通信。
    2、可以自己通过创建自己的数据结构(例如一个列表)来实现线程间通信,
       如:threading.Condition()的notify方法,以及通过threading.Event对象
    3、基于生产者、消费者实现线程之间的通信
    

    三次登录

    count = 0    #计数器
    username = "aaa"  #登录用户名
    userpassword = "asd"   #登录密码
    f = open("aaa.txt","r")
    file_list = f.readlines()
    f.close()
    lock= []
    name = input("登录用户名:")
    for i in file_list:1
        line = i.strip("
    ")
        lock.append(line)
    if name in lock:
        print("你的账户已锁定,请联系管理员。")
    else:
        if name == username:
        #如果密码连续输错了三次,锁定账号
            while count <3:
                password = input("登录密码:")
                if name == username and password == userpassword:
                    print("欢迎%s!"%name)
                    break
                else:
                    print("账号和密码不匹配")
                    count +=1
            else:
                print("对不起,您的账号连续输错三次密码已被锁定,请联系管理员。")
                f = open("aaa.txt","w+")
                li = ['%s'%username]
                f.writelines(li)
                f.close()
        else:
            print("用户名不存在,请输入正确的用户名。")
    

    计算N天后的日期

    import datetime
    
    
    def get_day(y,m,d,n):
        the_date =datetime.datetime(y,m,d)
        result_date = the_date + datetime.timedelta(days=n)
        d = result_date.strftime("%Y-%m-%d")
        return d
    
    
    print(get_day(2018,3,25,1))
    

    计算给定日期是该年的第多少天

    def count(year, month, day):
        count = 0
        # 判断该年是平年还是闰年
        if year % 400 == 0 or (year % 4 == 0 and year % 100 != 0):
            print('%d年是闰年,2月份有29天!' % year)
            li1 = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
            for i in range(month - 1):
                count += li1[i]
            return count + day
        else:
            print('%d年是平年,2月份有29天!' % year)
            li2 = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
            for i in range(month - 1):
                count += li2[i]
            return count + day
    
    
    if __name__ == "__main__":
        year = int(input('请输入年份:'))
        month = int(input('请输入月份:'))
        day = int(input('请输入日期:'))
        count = count(year, month, day)
        print('%d年%d月%d日是今年的第%d天!' % (year, month, day, count))
    

    循环和递归实现二分查找

    	while 循环实现二分查找
    	def bin_search(data_list, val):    
    		low = 0                         # 最小数下标    
    		high = len(data_list) - 1       # 最大数下标    
    		while low <= high:        
    			mid = (low + high) // 2     # 中间数下标        
    			if data_list[mid] == val:   # 如果中间数下标等于val, 返回            
    				return mid        
    			elif data_list[mid] > val:  # 如果val在中间数左边, 移动high下标            
    				high = mid - 1        
    			else:                       # 如果val在中间数右边, 移动low下标            
    				low = mid + 1    
    		return 							# val不存在, 返回None
    	ret = bin_search(list(range(1, 100)), 66)
    	print(ret)
    			
    	递归实现二分查找
    	def bin_search(li, val, low, high):
    		if low <= high:
    			mid = (low + high) // 2
    			if li[mid] == val:
    				return mid
    			elif li[mid] > val:
    				return bin_search(li, val, low, mid - 1)
    			else:
    				return bin_search(li, val, mid + 1, high)
    		else:
    			return
    
    
    	li = list(range(1000))
    	ret = bin_search(li, 555, 0, len(li) - 1)
    	print(ret)	
    

    Python上下文管理器(Context Manager)

    	当我们需要创建一个上下文管理器类型的时候,就需要实现__enter__和__exit__方法,这对方法就称为上下文管理协议(Context Manager Protocol),定义了一种运行时上下文环境。
    	在Python中,可以通过with语句来方便的使用上下文管理器,with语句可以在代码块运行前进入一个运行时上下文(执行__enter__方法),并在代码块结束后退出该上下文(执行__exit__方法)。
    	http://python.jobbole.com/82289/
    

    括号匹配问题,把list维护成一个栈

    	SYMBOLS = {'}':'{', ']':'[', ')':'('}
    	SYMBOLS_L, SYMBOLS_R = SYMBOLS.values(), SYMBOLS.keys()
    
    	def check(s):
    	    arr = []
    	    for c in s:
    	        if c in SYMBOLS_L:
    	            # 左符号入栈
    	            arr.append(c)
    	        elif c in SYMBOLS_R:
    	            # 右符号要么出栈,要么匹配失败
    	            if arr and arr[-1] == SYMBOLS[c]:
    	                arr.pop()
    	            else:
    	                return False
    
    	    return not arr
    
    	print(check("3 * {3 +[(2 -3) * (4+5)]}"))
    	print(check("3 * {3+ [4 - 6}]"))
    

    常用正则表达式

    	邮箱
    	^w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*$
    	手机号
    	^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])d{8}$
    	IP地址
    	(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
    

    生成器相关习题

    	1.生成器函数:
    	def demo():
    	    for i in range(4):
    	        yield i
    
    	g=demo()   # 生成器
    
    	g1=(i for i in g) #生成器
    	g2=(i for i in g1) #g2 生成器
    
    	print(list(g1))   #[0,1,2,3]
    	print(list(g2))    #[]
    	2.计算生成器函数返回值
    	def add(n,i):
    	    return n+i
    
    	def test():
    	    for i in range(4):
    	        yield i
    
    	g=test()
    	for n in [1,10]:
    	    g=(add(n,i) for i in g)
    
    	print(list(g))   #[20, 21, 22, 23]
    

    生产者消费者模型

    
    	程序中有两类角色:一类负责生产数据(生产者),一类负责处理数据(消费者);引入生产者消费者模型为了解决的问题是:平衡生产者与消费者之间的工作能力,从而提高程序整体处理数据的速度;如何实现:生产者<-->队列<——>消费者;生产者消费者模型实现类程序的解耦和。
    

    如何防止sql注入

    	sql注入:在sql语句中,如果存在'--'字符,则执行sql语句时会注释掉--字符后面的内容。凡有SQL注入漏洞的程序,
    	都是因为程序要接受来自客户端用户输入的变量或URL传递的参数,并且这个变量或参数是组成SQL语句的一部分。放置方式有:
    		1、使用预编译绑定变量的SQL语句 如execute()
    		2.严格加密处理用户的机密信息
    		3.不要随意开启生产环境中Webserver的错误显示
    		4.使用正则表达式过滤传入的参数
    		5.字符串过滤
    		6.检查是否包函非法字符
    

    连表操作的区别

    	1、交叉连接:不使用任何匹配条件生成笛卡尔积
    	select * from employee,department	 
    	2、内连接:只连接匹配的行
    	selcet employee.name,employee.age,department.name from employee inner join department on employee.dep_id = department.id
    	3、外连接之左连接:优先显示左表全部内容
    	selcet employee.name,employee.age,department.name from employee left join department on employee.dep_id = department.id
    	4、外连接之右连接:优先显示右表全部内容
    	selcet employee.name,employee.age,department.name from employee right join department on employee.dep_id = department.id
    	5、全外连接:显示左右两个表全部记录(mysql不支持full join),实现方式如下:
    	select * from employee left join department on employee.dep_id = department.id
    	union
    	select * from employee right join department on employee.dep_id = department.id
    

    如何求二进制中1 的个数

        def count1(a):
            '''
                整数的二进制表达里有多少个1,复杂度为a的二进制长度。
            '''
            num = 0
            while a != 0:
                num += a & 1
                a >>= 1
            return num
    
        def count2(a):
            '''
                整数的二进制表达里有多少个1,复杂度仅为1的个数
            '''
            num = 0
            while a != 0:
                a = a & (a - 1)  # 就是这个操作,需要掌握,它的本质含义是抹去了0不考虑
                num += 1
            return num
        运算符说明:http://www.runoob.com/python/python-operators.html
    	https://blog.csdn.net/dongrixinyu/article/details/78877489
    

    统计出现频率最高的词

    	import os  
    	from collections import Counter  
    	sumsdata=[]  
    	for fname in os.listdir(os.getcwd()):  
    	    if os.path.isfile(fname) and fname.endswith('.txt'):  
    	        with open(fname,'r') as fp:  
    	            data=fp.readlines()  
    	            fp.close()  
    	        sumsdata+=[line.strip().lower() for line in data]  
    	cnt=Counter()  
    	for word in sumsdata:  
    	    cnt[word]+=1  
    	cnt=dict(cnt)  
    	for key,value in cnt.items():  
    	    print(key+":"+str(value))  
    

    子网掩码有什么用

    
      子网掩码(subnet mask)的作用实际上只是用来标识出某个IP地址哪部分是网络位的一段地址。
    

    map等使用实例

    	map(lambda x: x ** 2, [1, 2, 3, 4, 5])  # 使用 lambda 匿名函数
    	[1, 4, 9, 16, 25]
    	 
    	map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])  # 提供了两个列表,对相同位置的列表数据进行相加
    	[3, 7, 11, 15, 19]
    

    list去重

    	1、直观方法
    
    	li=[1,2,3,4,5,1,2,3]
    	new_li=[]
    	for i in li:
    	    if i not in new_li:
    	        new_li.append(i)
    	print(new_li)
    	先建立一个新的空列表,通过遍历原来的列表,再利用逻辑关系not in 来去重。
    	总结:这样可以做出来,但是过程不够简单。但是此方法保证了列表的顺序性。 
    
    	2、利用set的自动去重功能
    	li=[1,2,3,4,5,1,2,3]
    	li=list(set(li))
    	print(li)
    	将列表转化为集合再转化为列表,利用集合的自动去重功能。简单快速。缺点是:使用set方法无法保证去重后的顺序。
    

    modle中slugfield字段的用途

    	1、slug:用于生成一个有意义(valid, meaninful)URL  参考(http://stackoverflow.com/questions/427102/what-is-a-slug-in-django)
    
    	比如:http://stackoverflow.com/questions/427102/what-is-a-slug-in-django  后面的“what-is-a-slug-in-django”就是经过slug后的产物
    
    	如何使用:
    
    	需要使用slugify功能:from django.utils.text import slugify
    
    	例子:slugify(value)  If value is "Joel is a slug", the output will be "joel-is-a-slug".
    
    	2、SlugField:也是起到类似作用,只不过这个一般是后台直接添加时使用,比如:slug = models.SlugField(unique=True)   这样在后台就有个slug框,填写后,URL中就包含slug中的内容。
    
    	https://www.cnblogs.com/ohmydenzi/p/5584846.html
    

    SVN和git

    	1. Git是分布式的,SVN是集中式的,好处是跟其他同事不会有太多的冲突,自己写的代码放在自己电脑上,一段时间后再提交、合并,也可以不用联网在本地提交;
    
    	2. Git下载下来后,在本地不必联网就可以看到所有的log,很方便学习,SVN却需要联网;
    
    	3. Git鼓励分Branch,而SVN,说实话,我用Branch的次数还挺少的,SVN自带的Branch merge我还真没用过,有merge时用的是Beyond Compare工具合并后再Commit的;
    
    	4. Tortoise也有出Git版本,真是好东西;
    
    	5. SVN在Commit前,我们都建议是先Update一下,跟本地的代码编译没问题,并确保开发的功能正常后再提交,这样其实挺麻烦的,有好几次同事没有先Updata,就
    	Commit了,发生了一些错误,耽误了大家时间,Git可能这种情况会少些。
    

    cookie和session区别

    
    	cookie是把用户的数据写在用户本地浏览器上, 其他网站也可以扫描使用你的cookie,容易泄露自己网站用户的隐私,而且一般浏览器对单个网站站点有cookie数量与大小的限制。Session是把用户的数据写在用户的独占session上,存储在服务器上,一般只将session的id存储在cookie中。但将数据存储在服务器对服务器的成本会高。session是由服务器创建的,开发人员可以在服务器上通过request对象的getsession方法得到session一般情况,登录信息等重要信息存储在session中,其他信息存储在cookie中
    
    				Cookie											Session
    	储存位置	客户端											服务器端
    	目的		跟踪会话,保存用户偏好设置或用户名密码等 		跟踪会话
    	安全性		不安全											安全
    
    	session技术是要使用到cookie的,之所以出现session技术,主要是为了安全。
    

    apache和nginx的区别

    
    	https://www.cnblogs.com/wangzhipeng/p/7850717.html
    

    常用推导式

    	列表推导式
    	字典推导式
    	集合推导式
    	https://www.cnblogs.com/cenyu/p/5718410.html
    

    闭包代码

    	闭包函数的实例
    	outer是外部函数 a和b都是外函数的临时变量
    	def outer( a ):
    	    b = 10
    	    # inner是内函数
    	    def inner():
    	        #在内函数中 用到了外函数的临时变量
    	        print(a+b)
    	    # 外函数的返回值是内函数的引用
    	    return inner
    
    	if __name__ == '__main__':
    	    # 在这里我们调用外函数传入参数5
    	    #此时外函数两个临时变量 a是5 b是10 ,并创建了内函数,然后把内函数的引用返回存给了demo
    	    # 外函数结束的时候发现内部函数将会用到自己的临时变量,这两个临时变量就不会释放,会绑定给这个内部函数
    	    demo = outer(5)
    	    # 我们调用内部函数,看一看内部函数是不是能使用外部函数的临时变量
    	    # demo存了外函数的返回值,也就是inner函数的引用,这里相当于执行inner函数
    	    demo() # 15
    
    	    demo2 = outer(7)
    	    demo2()#17
    	https://www.cnblogs.com/Lin-Yi/p/7305364.html
    

    python读取大文件20G

    	with open(filename, 'r') as flie:
    	    for line in file:
    	        ....
    	--------------
    	text = linecache.getline(filename, 2)	# 使用linecache模块
    	https://www.cnblogs.com/wulaa/p/7852592.html
    

    数据库引擎特点

    	MyISAM: 
    	有存储限制,表的定义语句,数据,索引分文件存储,分别为.frm文件,.MYD(MyDate),.MYI文件(MyIndex),存储方式分静态表(默认),动态表,压缩表。静态表中表字段定长,存储速度快,容易缓存,出现故障容易恢复,但是空间浪费严重。动态表中表字段不定长,空间浪费小,但是崩溃不易恢复,频繁的删除和更新会产生大量的碎片,可以使用OPTIMIZE TABLE命令定期清理碎片。同时MyISAM存储殷勤不支持外键,也不支持事务处理,但是其优势为访问速度快,在使用中中,如果对事务完整性没有要求,或者数据库操作主要以Select或者Insert为主的应用基本上可以使用这种存储引擎,而且MyISAM存储殷勤在也是5.5版本之前MySQL默认的存储引擎。 
    	InnoDB: 
    	提供回滚,提交,崩溃恢复的事务安全,唯一支持外键,表中的自动增长列必须是索引,如果是组合索引,必须是组合索引的第一列,并且自动增长列支持手动插入,但是如果插入值为空或者0,则实际值为增长后的值。创建外键时,要求父表必须有对应的索引,子表在创建外键的时候,也会自动创建对应的索引。如果某个表被其他表创建了外键参照,那么该表的对应索引或者主键禁止被删除。但是在创建索引时,可以指定在对父表进行删除或者更新时,子表所对应的操作,这些操作包括以下几种: 
    	RESTRICT,CASCADE,SET NULL,NO ACTION,其实RESTRICT和NO ACTION作用相同,是指在子表有关联记录的时候,父表不允许更新,CASCADE是指在父表执行更新或者删除操作时,更新或者删除子表对应的记录,SET NULL是指在父表执行删除或者更新操作时,子表相应字段设置为NULL。 
    	InnoDB在存储方式上,分为共享表空间和使用多表空间存储。 
    
    	https://blog.csdn.net/qq_34985719/article/details/78637119
    

    select和epoll原理和区别

    	其实所有的I/O都是轮询的方法,只不过实现的层面不同罢了.
    
    	这个问题可能有点深入了,但相信能回答出这个问题是对I/O多路复用有很好的了解了.其中tornado使用的就是epoll的.
    
    	selec,poll和epoll区别总结
    
    	基本上select有3个缺点:
    
    	连接数受限
    	查找配对速度慢
    	数据由内核拷贝到用户态
    	poll改善了第一个缺点
    
    	epoll改了三个缺点.
    
    	关于epoll的: http://www.cnblogs.com/my_life/articles/3968782.html
    

    dict转列表

    	a = {'a' : 1, 'b': 2, 'c' : 3}  
    	  
    	 
    	key_value = list(a.keys())  #字典中的key转换为列表 
    	print('字典中的key转换为列表:', key_value)  
    	  
    
    	value_list = list(a.values())  #字典中的value转换为列表  
    	print('字典中的value转换为列表:', value_list)  
    

    XSS攻击

    
    	XSS 攻击,全称是“跨站点脚本攻击”(Cross Site Scripting),之所以缩写为 XSS,主要是为了和“层叠样式表”(Cascading StyleSheets,CSS)区别开,以免混淆。XSS 是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。这些代码包括HTML代码和客户端脚本。对于跨站脚本攻击,黑客界共识是:跨站脚本攻击是新型的“缓冲区溢出攻击”,而JavaScript是新型的“ShellCode”。
    

    线程安全

    
    	线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。 线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。
    

    1+2+3+...+n用python怎么用递归实现?

    	for
    	while
    	https://blog.csdn.net/fang_zz/article/details/51530796
    

    斐波那契数列不同版本

    	while循环版
    	a=0
    	b=1
    	while b < 1000:
    	    print(b)
    	    a, b = b, a+b
    
    
    	递归版
    	lis = []
    	for i in range(20):
    	    if i == 0 or i == 1:  # 第1,2项 都为1
    	        lis.append(1)
    	    else:
    	        lis.append(lis[i - 2] + lis[i - 1])  # 从第3项开始每项值为前两项值之和
    	print(lis)
    
    	for循环版
    	def fib(n):
    	    a, b = 0, 1
    	    for _ in range(n):
    	        a, b = b, a + b
    	    return b
    

    init()和__new__()的区别

    	__init__ 只是单纯的对实例进行某些属性的初始化,以及执行一些需要在新建对象时的必要自定义操作,无返回值。而 __new__ 返回的是用户创建的实例,这个才是真正用来创建实例的,所以 __new__ 是在 __init__ 之前执行的,先创建再初始化。
    

    利用Python实现栈和队列

    	# 后进先出
    	class Stack():
    	    def __init__(self, size):
    	        self.size = size
    	        self.stack = []
    	        self.top = -1
    
    	    # 入栈之前检查栈是否已满
    	    def push(self, x):
    	        if self.isfull():
    	            raise exception("stack is full")
    	        else:
    	            self.stack.append(x)
    	            self.top = self.top + 1
    
    	    # 出栈之前检查栈是否为空
    	    def pop(self):
    	        if self.isempty():
    	            raise exception("stack is empty")
    	        else:
    	            self.top = self.top - 1
    	            self.stack.pop()
    
    	    def isfull(self):
    	        return self.top + 1 == self.size
    
    	    def isempty(self):
    	        return self.top == '-1'
    
    	    def showStack(self):
    	        print(self.stack)
    
    
    	s = Stack(10)
    	for i in range(6):
    	    s.push(i)  # 入栈
    	s.showStack()  # [0, 1, 2, 3, 4, 5]
    
    	for i in range(2):
    	    s.pop()  # 出栈
    	s.showStack()  # [0, 1, 2, 3]
    	-------------------
    	# 先进先出
    	class Queue():
    
    	    def __init__(self,size):
    	        self.size=size
    	        self.front=-1
    	        self.rear=-1
    	        self.queue=[]
    
    	    def enqueue(self,ele):  # 入队操作
    	        if self.isfull():
    	            raise exception("queue is full")
    	        else:
    	            self.queue.append(ele)
    	            self.rear=self.rear+1
    
    	    def dequeue(self):  # 出队操作
    	        if self.isempty():
    	            raise exception("queue is empty")
    	        else:
    	            self.queue.pop(0)
    	            self.front=self.front+1
    
    	    def isfull(self):
    	        return self.rear-self.front+1 == self.size
    	    def isempty(self):
    	        return self.front == self.rear
    	    def showQueue(self):
    	        print(self.queue)
    
    	q=Queue(10)
    	for i in range(6):
    	    q.enqueue(i)
    	q.showQueue()
    	for i in range(3):
    	    q.dequeue()
    	q.showQueue()
    	print(q.isempty())
    

    Python 中的 GIL 是什么?举个例子说说其具体体现。

    	GIL 全称 Global Interpreter Lock(全局解释器锁),任何 Python 线程执行前,必须先获得 GIL 锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。要避免这种“现象”利用操作系统的多核优势可以有下面几种方法:
    		使用 C 语言编写扩展,创建原生线程,摆脱 GIL,但是即使是扩展,在 Python 代码内,任意一条Python 代码还是会有 GIL 限制
    		使用多进程代替多线程,使用多进程时,每个进程都有自己的 GIL。故不存在进程与进程之间的 GIL 限制。但是多进程不能共享内存。
    
  • 相关阅读:
    mac 安装mysql. 使用brew install mysql 报错
    当忙碌成为借口的时候
    MySQL数据库导入导出详解[转发]
    一些模拟浏览器自动Post到服务器的工具(备忘)
    [转]一句css代码让你的网站变灰,一起悼念地震中逝去的生命!
    MYSQL命令行常用操作
    国外达人收集的Cheet Sheet
    SQL Server:将6字节的十六进制页面号转化成【文件号:页面号】格式函数
    javaWEB核心
    电商
  • 原文地址:https://www.cnblogs.com/iyouyue/p/9120215.html
Copyright © 2011-2022 走看看