【python】python面试题

先了解一下python的知识结构图(转)

一、Python基础

1 代码中要修改不可变数据会出现什么问题?抛出什么异常?

代码不会正常运行,抛出TypeError异常。

2 print调用Python中底层的什么方法?

print方法默认调用sys.stdout.write方法,即往控制台打印字符串。

3 python怎么定义类?

class 类名(继承类):

           pass

class Child1(Parent):   
    pass  

4 、input()和raw_input()有什么区别?

Python3:

input():不管输入什么,获取的都是字符串类型的;

Python2:

raw_input():raw_input()和Python3中的input()作用是一样的,不管输入什么,都是获取字符串。

input()输入的是什么数据类型的,获取到的就是什么数据类型的。

5 、

zip() 函数的用法?

用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

(python3中返回的是zip对象)

什么是‘可迭代的对象’?

迭代:python中可以用for循环使用取值操作过程.
可迭代对象:可以使用for循环遍历的对象,我们称之为可迭代对象

迭代器:提供数据和记录位置。
生成器:如果函数中有yield我们称之为生成器。

python三大器?(这里是补充,后面还会继续讲)

  • 迭代器: 有__iter__()和__next__()方法
  • 生成器:函数中将return换成yield
  • 装饰器:闭包的本质。

6、 Python2 中,range和xrange的区别?        

两者用法相同,不同的是:

①range返回的结果是一个列表,而xrange的结果是一个生成器。

②前者是直接开辟一块内存空间来保存列表,后者是边循环边使用,只有使用时才会开辟内存空间。      

 所以当列表很长时,使用xrange性能要比range好。

7、 4G内存怎么读取一个5G的数据?

方法一: 可以通过生成器,分多次读取,每次读取数量相对少的数据(比如500MB)进行处理,处理结束后在读取后面的 500MB的数据。

方法二: 可以通过linux命令split将数据切割成小文件,然后再对数据进行处理,此方法效率比较高。可以按照行数切割,可以按照文件大小切割。  

8、 read、readline和readlines的区别? read:读取整个文件。 readline:读取下一行,使用生成器方法。 readlines:读取整个文件到一个迭代器以供我们遍历。

8、python怎么写路径?

(1)复制粘贴前面加个r:比如 r'C:\360Downloads\Software’。反斜杠(enter上边的),转义符,需要加r。

(2)不加r的是'C:/360Downloads/Software’   斜杠是数字键旁边的,除号。

9、 介绍一下except的作用和用法?

except: #捕获所有异常

except: <异常名>  #捕获指定异常

except:<异常名1, 异常名2> #捕获异常1 或者异常2

except:<异常名>,<数据>#捕获指定异常及其附加的数据

except:<异常名 1,异常名 2><数据>:#捕获异常名 1 或者异常名 2,及附加的数据

10、 Python的各种库:

标准库:os操作系统,time时间,random随机,pymysql连接数据库,threading线程,multiprocessing进程,queue队列。

第三方库: django和flask也是第三方库,requests,virtualenv,selenium,scrapy,xadmin,celery,re,hashlib,md5。

科学计算库:如Numpy,Scipy,Pandas。

11、 unittest是什么?

在Python中,unittest是Python中的单元测试框架。

它拥有支持共享搭建、自动测试、在测试中暂停代码、将不同测试迭代成一组等功能。

12、 模块和包是什么?

模块:

是搭建程序的一种方式。每一个Python代码文件都是一个模块,并可以引用其他的模块,比如对象和属性。

包(包>=模块):

包含许多Python代码的文件夹是一个包。一个包可以包含模块和子文件夹。  

13、 Python 是强类型的,动态的,脚本语言。

强类型语言:不允许不同类型相加。

动态语言:不需要先数据类型声明,且确定一个变量的类型是在第一次给它赋值的时候。

脚本语言:一般也是解释型语言,运行代码只需要一个解释器,不需要编译。

14、 什么是解释性语言,什么是编译性语言?

计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序。

解释性语言在运行程序的时候才会进行翻译。

编译型语言写的程序在执行之前,需要一个专门的编译过程,把程序编译成机器语言(可执行文件)

15、 第三方工具包说明:

16、 工具安装问题:

windows环境:      

Python2: 

无法安装mysqlclient。

Python3 :

无法安装MySQL-python、 flup、functools32、Gooey、Pywin32、 webencodings。      

matplotlib在python3环境中安装报错:The following required packages can not be built:freetype, png。需要手动下载安装源码包安装解决。 scipy在Python3环境中安装报错,numpy.distutils.system_info.NotFoundError,需要自己手工下载对应的安装包,依赖numpy,pandas必须严格根据python版本、操作系统、64位与否。运行matplotlib后发现基础包    numpy+mkl安装失败,需要自己下载,国内暂无下载源

centos环境下      

Python2无法安装mysql-python和mysqlclient包,报错:EnvironmentError: mysql_config not found,解决方案是安装mysql-devel包解决。使用matplotlib报错:no module named _tkinter,安装Tkinter、tk-devel、tc-devel解决。 pywin32也无法在centos环境下安装。

17、 关于Python程序的运行方面,有什么手段能提升性能?

1、使用多进程,充分利用机器的多核性能 2、对于性能影响较大的部分代码,可以使用C或C++编写 3、对于IO阻塞造成的性能影响,可以使用IO多路复用来解决 4、尽量使用Python的内建函数 5、尽量使用局部变量(少用全局变量)

18、 你所遵循的代码规范是什么?请举例说明其要求?

PEP8规范:

1. 变量

常量:大写加下划线 USER_CONSTANT

私有变量 : 小写和一个前导下划线 _private_value。 Python中不存在私有变量一说,若是遇到需要保护的变量,使用小写和一个前导下划线。但这只是程序员之间的一个约定,用于警告说明这是一个私有变量,外部类不要去访问它。但实际上,外部类还是可以访问到这个变量。

内置变量 : 小写,两个前导下划线和两个后置下划线: __class__ 两个前导下划线会导致变量在解释期间被更名。这是为了避免内置变量和其他变量产生冲突。用户定义的变量要严格避免这种风格。以免导致混乱。

2. 函数和方法

总体而言应该使用,小写和下划线。但有些比较老的库使用的是混合大小写,即首单词小写,之后每个单词第一个字母大写,其余小写。但现在,小写和下划线已成为规范。

私有方法 :小写和一个前导下划线 这里和私有变量一样,并不是真正的私有访问权限。同时也应该注意一般函数不要使用两个前导下划线(当遇到两个前导下划线时,Python 的名称改编特性将发挥作用)。

特殊方法 :小写和两个前导下划线,两个后置下划线 这种风格只应用于特殊函数,比如操作符重载等。

函数参数 : 小写和下划线,缺省值等号两边无空格

3. 类

类总是使用驼峰格式命名,即所有单词首字母大写其余字母小写。类名应该简明,精确,并足以从中理解类所完成的工作。常见的一个方法是使用表示其类型或者特性的后缀,例如: SQLEngine,MimeTypes对于基类而言,可以使用一个 Base 或者 Abstract 前缀BaseCookie,AbstractGroup

4. 模块和包

除特殊模块 __init__ 之外,模块名称都使用不带下划线的小写字母。 若是它们实现一个协议,那么通常使用lib为后缀,例如: import smtplib   import os import sys

5. 关于参数

5.1 不要用断言来实现静态类型检测。

断言可以用于检查参数,但不应仅仅是进行静态类型检测。 Python 是动态类型语言,静态类型检测违背了其设计思想。断言应该用于避免函数不被毫无意义的调用。

5.2 不要滥用 *args 和 **kwargs。

*args 和 **kwargs 参数可能会破坏函数的健壮性。它们使签名变得模糊,而且代码常常开始在不应该的地方构建小的参数解析器。

6. 其他

6.1 使用 has 或 is 前缀命名布尔元素 is_connect = True has_member = False

6.2 用复数形式命名序列 members = ['user_1', 'user_2']

6.3 用显式名称命名字典 person_address = {'user_1':'10 road WD', 'user_2' : '20 street huafu'}

6.4 避免通用名称 诸如 list, dict, sequence 或者 element 这样的名称应该避免。

6.5 避免现有名称 诸如 os, sys 这种系统已经存在的名称应该避免。

7. 一些数字

一行列数 : PEP 8 规定为 79 列。根据自己的情况,比如不要超过满屏时编辑器的显示列数。 一个函数 : 不要超过 30 行代码, 即可显示在一个屏幕类,可以不使用垂直游标即可看到整个函数。 一个类 : 不要超过 200 行代码,不要有超过 10 个方法。一个模块 不要超过 500 行。

8. 验证脚本

可以安装一个pep8脚本用于验证你的代码风格是否符合PEP8。 

19、 Linux查看某个服务的端口?

netstat -anp | grep service_name

20、 10个常用的Linux命令?

pwd 显示工作路径

ls 查看目录中的文件

cd /home 进入 '/ home' 目录'

cd .. 返回上一级目录

cd ../.. 返回上两级目录

mkdir dir1 创建一个叫做 'dir1' 的目录'

rm -f file1 删除一个叫做 'file1' 的文件',-f参数,忽略不存在的文件,从不给出提示。

rmdir dir1 删除一个叫做 'dir1' 的目录' groupadd group_name 创建一个新用户组

groupdel group_name 删除一个用户组

tar -cvf archive.tar file1 创建一个非压缩的

tarball tar -cvf archive.tar file1 file2 dir1 创建一个包含了 'file1', 'file2' 以及 'dir1'的档案文件

tar -tf archive.tar 显示一个包中的内容

tar -xvf archive.tar 释放一个包

tar -xvf archive.tar -C /tmp 将压缩包释放到 /tmp目录下

tar -cvfj archive.tar.bz2 dir1 创建一个bzip2格式的压缩包

tar -xvfj archive.tar.bz2 解压一个bzip2格式的压缩包

tar -cvfz archive.tar.gz dir1 创建一个gzip格式的压缩包

tar -xvfz archive.tar.gz 解压一个gzip格式的压缩包

21、 切片操作

变量.split(‘切片符号’)

22、 程序分析包,比较代码执行效率:

import random
import cProfile
lIn = [random.random() for i in range(100000)]
cProfile.run('f1(lIn)')
cProfile.run('f2(lIn)')
cProfile.run('f3(lIn)’)

 

二、Python进阶 

1 map函数和reduce函数?

①从参数方面来讲:      

map()包含两个参数,第一个参数是一个函数,第二个是序列(列表 或元组)。其中,函数(即 map 的第一个参数位置的函数)可以接收一个或多个参数。      

reduce()第一个参数是函数,第二个是序列(列表或元组)。但是,其函数必须接收两个参数。

②从对传进去的数值作用来讲:      

 map()是将传入的函数依次作用到序列的每个元素,每个元素都是独自被函数“作用”一次 。      

 reduce()是将传入的函数作用在序列的第一个元素得到结果后,把这个结果继续与下一个元素作用(累积计算)。

2 递归函数停止的条件?

def A(n):     

    if n   :         
        return #退出条件   
    else:         
        return #递归条件

4 Python中is和==的区别?

is判断的是a对象是否就是b对象,是通过id来判断的。

==判断的是a对象的值是否和b对象的值相等,是通过value来判断的。

5 Python的魔法方法:        

魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现 (重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动发生的。 它们经常是两个下划线包围来命名的(比如 __init__,__lt__),Python 的魔法方法是非常强大的,所以了解其使用方法也变得尤为重要!

__init__ :构造器,当一个实例被创建的时候初始化的方法。但是它并不是实例化调用的第一个方法。

__new__:才是实例化对象调用的第一个方法,它只取下 cls 参数,并把其他参数传给 __init__。 __new__很少使用,但是也有它适合的场景,尤其 是当类继承自一个像元组或者字符串这样不经常改变的类型的时候。

__call__: 允许一个类的实例像函数一样被调用 。

__getitem__: 定义获取容器中指定元素的行为,相当于 self[key] 。

__getattr__ :定义当用户试图访问一个不存在属性的时候的行为 。

__setattr__ :定义当一个属性被设置的时候的行为 。

__getattribute__: 定义当一个属性被访问的时候的行为 。

6 谈谈你对面向对象的理解?        

面向对象是相对于面向过程而言的。面向过程语言是一种基于功能分析的、以算法为中心的程序设计方法;而面向对象是一种基于结构分析的、以数据为中心的程序设计思想。在面向对象语言中有一个有很重要东西,叫做类。        

面向对象有三大特性:封装、继承、多态。

7.python面向对象技术:

(1)封装:类的实现就是封装技术。

属性和方法放到类内部,通过对象访问属性或者方法,隐藏功能的实现细节.当然还可以设置访问权限;

(2)继承:子类、父类。

子类需要复用父类里面的属性或者方法,当然子类还可以提供自己的属性和方法;

(3)多态:以封装和继承为前提,不同的子类对象调用相同的方法,产生不同的执行结果。

(多态是python设计的核心,也叫鸭子类型)

#以下例子,两个子类修改了各自的talk()方法,这也是能形成多态的原因。

#这里的call_talk()可以放很多类似于talk()的方法,以实现多个函数的多态,这就是call_talk()的意义。

class Human(object):   #父类
    def __init__(self, name):
        self.name = name
    def talk(self):  # 自己定义talk方法
        print('这是人')
    def call_talk(self):  #多态
        self.talk()

class Woman(Human):   #子类Woman
    def talk(self):   #重写talk
        print('%s很美丽' % self.name)

class Man(Human):     #子类Man
    def talk(self):   #重写talk
        print('%s很帅气' % self.name)

class People(Human): # 继承
    pass


human = Human('')
human.call_talk()

man = Man('女人')
man.call_talk()

woman = Woman('男人')
woman.call_talk()

people = People('')
people.call_talk()

输出:

8.python三大器详解:

(1)迭代器:

就是定义一个类,在类里面实现iter和next这两个方法;则这个类就是 迭代器。

可迭代,可以用for循环遍历。

意义:

节省内存,可迭代,可以用for循环遍历。

示例:

class Fibonacci(object):
    def __init__(self, num):
        # num:表示生成多少fibonacci数字
        self.num = num
        # 记录(斐波拉契数列)fibonacci前两个值,
        self.a = 0
        self.b = 1
        # 记录当前生成数字的索引
        self.current_index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.current_index < self.num:
            result = self.a
            self.a, self.b = self.b, self.a + self.b
            self.current_index += 1
            return result
        else:
            raise StopIteration

fib = Fibonacci(5)
print(next(fib))
print(next(fib))
print('迭代')
for value in fib:
    print(value)

结果:

(2)生成器:(函数,return换为yeild)

函数中将return换成yield,就是生成器函数。generator 生成器,是一个函数。

意义:

本质就是迭代器,只不过yeild里封装了,不用写__iter__()和__next__()。也是为了节省内存

可迭代,可以用for循环遍历。

示例:

def fibonacci(n):
    a,b,count=0,1,0
    while True:
        if count>n:
            break
        yield a
        count+=a
        a,b=b,a+b
fib=fibonacci(5)
print(next(fib))
print(next(fib))
print('迭代')
for i in fib:
    print(i)

结果:

(3)装饰器:

在不改变一个函数代码和调用方式的情况下给函数添加新的功能。闭包的本质。

在B函数前@一下A函数,就可以把B函数作为参数加入A函数中执行。

示例:

在原先的函数func()的基础上,添加计算运行时间的功能。

一个@time_it的装饰器(代码如下所示)。如果你想打印出某个函数或程序运行时间,只需在函数前面@一下

import time

def time_it(func):
    def inner():
        start = time.time()
        func()
        end = time.time()
        print('用时{}秒'.format(end-start))
    return inner

#这个是原先的函数,加了个@time_it,就作为参数传入time_it,执行time_it函数内的inner()函数。
@time_it
def func1():
    time.sleep(0.5)
    print("Func1 is running.")

if __name__ == '__main__':
    func1()

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值