zoukankan      html  css  js  c++  java
  • 面试题-python基础

    一、Python基础

    1、什么是python?使用python有什么好处?

    python是一种编程语言,它有对象、模块、线程、异常处理和自动内存管理。它简洁,简单、方便、容易扩展、有许多自带的数据结果,而且它开源

    Python是一种解释性语言,它的源代码可以直接运行,Python解释器会将源代码转换成中间语言,之后再翻译成机器码再执行

    2、可变类型与不可变类型

    可变类型:list、dict、可变集合set

    不可变类型:数字,str,tuple元组,frozenset

    内存中的那块内容(value)是否可变

    可直接在原来的地址,修改

    不可变的类型都可以被hash哈希

    3、深浅copy

    对不可变类型进行copy的话,都是深copy

    对于可变类型进行copy的话,一般都是浅copy

    浅拷贝只是增加了一个指针指向所复制的对象,共用一块内存

    深拷贝是增加一个指针并且开辟了新的内存,这个增加的指针指向这个新的内存,

    In [42]: li = [1,2,3,[4,5]]
    In [43]: li2 = copy.copy(li)
    In [44]: li3 = copy.deepcopy(li)
    
    
    In [45]: li[-1][-1] = "222"
        
    In [46]: li
    Out[46]: [1, 2, 3, [4, '222']]
    
    In [47]: li2
    Out[47]: [1, 2, 3, [4, '222']]
    
    In [48]: li3
    Out[48]: [1, 2, 3, [4, 5]]
    

    简单来说,如果有嵌套的话,浅copy只复制第一层,深copy会复制所有的

    4、range-and-xrange

        py2:
            range() 生成的是列表
            xrange() 生成的是一个生成器 
        py3:
            range() 就是一个生成器
            xrange() 没了
    

    5、闭包

    def func():
        
        def inner():
            print('aaaa')  
            
        return inner
    
    func()()  # aaaa 
    

    内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包。

    闭包的意义:返回函数对象+一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

    6、装饰器

    调用装饰器其实是一个闭包函数,

    不修改函数的代码与修饰方式,为其他函数添加附加功能

    比如:插入日志、性能测试、事物处理、缓存、权限验证等

    # 装饰器
    import time
    def login(func):
        def inner():
            start_time = time.time()
            func()
            end_time = time.time()
            print("fun 执行时间",end_time-start_time)
        return inner
    
    @login
    def test():
        for i in range(10000):
            for j in range(10000):
                pass
        print('test函数执行')
    
    test()
    # test函数执行
    # fun 执行时间 2.0163347721099854
    

    7、生成器

    延迟操作,需要的时候才产生结果,而不是立即产生结果

    在每次调用next()的时候执行,遇到yield语句返回

    创建生成器的两种方式:

    li = [i for i in range(100)]、yield方法

    8、迭代器

    for循环的数据类型:集合数据类型+生成器

    list,tuple,dict,set,str + generator

    不是一次性把数据加载到内存,而是被next()函数调用,不断返回下一个数据

    9、*args与**kwargs

    *args:位置参数 ('alex',18)

    **kwargs:关键字参数 {'name'='alex','age'=18} 关键字参数一定要放在最后面

    二、面向对象

    1、经典类、新式类

    经典类:深度优先,python2中

    新式类:广度优先,Python3中

    2、继承、多态、封装

    (1)继承:类与类之间关系,Cat类是动物类,解决代码重用问题

    重用 父类的属性与方法

    def __init__(self, name, life_value, aggresivity, weapon):
            super().__init__(name, life_value, aggresivity,)        # python3格式
            self.weapon = weapon
    
     def attack(self, enemy):
           super().attack(enemy)
    

    (2)多态:同一类事物多种形态

    一个接口,多种形态

    不应关注对象的类型本身,而是它如何使用的

    鸭子类型:如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’

    (3)封装

    私有化的属性,私有化的方法,封装起来,外部无法调用 双下划线__foo

    3、classmethod,staticmethod,property

    (1)property:特性 (统一访问 原则)

        @property
        def bmi(self):
            return self.weight / (self.height ** 2)
    

    把类的方法转换为属性,直接 alex.bmi 调用

    (2)staticmethod 静态方法 (普通函数 ) 绑定到对象上

    类内的函数实例化---> 普通函数 。 (类和对象都可以使用)

        @classmethod
        def from_conf(cls):
            obj = settings.name,
            return obj
    

    (3)classmethod 类方法 (def foo(cls)) 绑定到类上

    将cls 类本身当做参数传入,直接用类来调用函数,而不用借助类实例

    优雅地实现某个类的实例的构造

    4、 new.init区别,如何实现单例模式

    创建一个新实例时调用new new()在 init()之前被调用

    初始化一个实例时调用init

    单例模式设计的类只能实例化1个对象

    # 方式1 python模板自带单例模式
    # admin.py
    
    class Admin(object):
        def register(self):
            pass
    
    site = Admin()
    
    # test.py
    from admin import site
    site.register()
    
    # 方式2  __new__  _instance
    class Single(object):
        _instance = None
        def __new__(cls,*args,**kwargs):
            if not cls._instance:
                cls._instance = super(Single,cls).__new__(cls,*args,**kwargs)
                
            return cls._instance
    

    5、反射

    “字符串”形式,操作对象的相关属性或方法。

    hasattr, getattr, setattr, delattr

    ret = getattr(obj,'get_file')()       # 反射  obj是实例对象,name是方法 
    

    三、并发

    1、线程、进程的区别

    (1)进程:程序的运行过程, os 资源调度、分配的基本单位 os的并发

    (2)线程:进程的实体, cpu 调度、分派的基本单位 进程内部的并发

    区别

    1、进程有独立的内存空间, 线程 共享 本进程 的内存空间

    2、进程有独立的系统资源 ,线程只有(程序计数器,一组寄存器,栈) 共享本进程的资源(内存,I/O,cpu)

    3、独立性:进程崩溃,不会影响其他的(健壮) 线程崩溃,本进程的全部线程死掉

    4、开销:进程切换与创建 开销大于 线程的

    5、线程不能独立执行 进程可以

    联系

    都可并发、一个进程由1or多个线程 组成、一个进程中的所有线程共享该进程全部资源
    

    2、协程、GIL

    GIL:全局解释器锁(cpython解释器), 同一时刻,在cpu只能有一个线程执行

    协程:轻量级的线程,用户控制调度的

    单线程下(的并发), 遇到I/O阻塞,多个任务,自动切换

    3、进程同步方式

    1、Event事件 。 通知操作

    2、互斥量。 加锁

    3、信号量。 生产者消费者模型 阻塞队列Queue

    4、临界区 。保护区域

    同步问题:生产者消费者模型,作者读者问题,哲学家进餐问题

    4、通信方式

    管道,系统IPC(消息队列,信号量,信号,共享内存),套接字,远程过程调用rpc

    5、死锁

    多个进程运行,争夺资源,一种僵局;没有外力,进程,无法继续执行

    导致死锁的原因:循环等待、不可抢占、占有且等待、互斥

    死锁处理:

    1、预防 :破坏4个条件

    2、避免:银行家算法

    3、检测:算法检测,清除死锁

    4、解除: 检测到,撤销进程or剥夺资源

    6、select、poll和epoll (I/O多路复用)

    可以监视多个描述符

    一个描述符就绪,通知应用程序,执行读or写操作

    (1)select :

    把文件描述符 fd 集合maxSize=1024,用户态copy到内核态 开销大,在内核,遍历所有fd

    (2)poll:

    改善了连接数,不断轮询,fd集合 每次都copy到内核态

    (3)epoll:

    linux下的多路复用I/O接口, 只copy一次,只告知 ,刚变为就绪状态的fd

    四、mysql数据库

    1、索引

    B+数:二叉树-->平衡二叉树-->B数

    一个排序好,数据结构 (协助快速查询data) 范围查询

    create index ix_age on t1(age);
    create index 索引名1,索引名2 on 表名('字段1','字段2')
    

    (1)什么时候用?

    经常 select查询、表记录超多

    经常需要搜索的列、主键列、连接的列(外键)、范围查找 age in [20,40]、排序的列 salary、where上的列

    (2)什么时候不用?

    经常update,delete,insert 表记录少

    不经常使用的列 addr,数据值很少的列 blog,文本,image,bit 修改>查询的

    2、存储过程

    相当于 函数,封装了,一系列,可执行的sql语句,存放在mysql中

    直接调用它的名称

    create procedure p1()
    BEGIN
        select * from blog;
        INSERT into blog(name,sub_time) values("xxx",now());
    END
    

    优点:网络传输量小,程序与slq解耦

    缺点:程序猿拓展功能不方便

    3、数据库引擎

    INNODB 支持事务,外键,行锁, 查表总行数,全表扫描

    MYISAM不支持事务,不支持外键,表锁(插入data,锁定这个表),查表总行数,不需要全表扫描

    4、redis

    key-value数据库 ,经常用的data放在redis

    性能极高,支持多种数据类型 ,放在内存中 (必要时可以写入硬盘)

    五、网络

    1、http常用的状态码

    200:请求成功 OK

    202:服务器接受请求,尚未处理

    302:重定向

    304  :上次的文档,已被缓存, 还可继续使用

    400:客户端请求语法or参数错误

    403:服务器收到请求,拒绝提供服务,找不到cookie

    404:客户端请求的资源url不存在

    500: 服务器的程序出现错误

    503:服务器当前时间不能处理客户端的请求,一段时间后恢复

    2、HTTP请求方式

    HTTP1.0 GET/HEAD/POST

    HTTP1.1 PUT/DELETE/CONNECT/OPTIONS/TRACE

    3.GET/POST区别

    (1)get提交的数据放在url后 /?name=alex&age=18 http请求头

         post的数据放在http报请求体
    

    (2)GET的数据大小有限制,POST没有限制

    (3)GET方式会带来安全问题,在url出现信息,可能获得username password

    (4)在服务端 获取请求数据方式不同

    4、http请求头,请求体

    协议版本,状态码,状态码原因 HTTP /1.1 200 OK

    Cookie:

    Content-Language

    Content-Type 文本类型

    Content-Length 请求体长度

    User-Agent: 浏览器的身份标识,类型,手机端or电脑端

    Date:时间

    请求体

    5、TCP/UDP区别 (运输层)

    1、TCP 传输控制协议,面向连接的,可靠的,数据流传输 ,注重data安全性,传输慢,面向字节流

    2、UDP用户数据报文协议,非面向连接的,不可靠,数据流传输, data传输快,安全性一般,面向报文

    python部分

    4、深浅拷贝

    浅拷贝只是增加了一个指针指向一个存在的地址,
    深拷贝是增加一个指针并且开辟了新的内存,这个增加的指针指向这个新的内存,
    简单地说,浅拷贝只拷贝一层(如果有嵌套),深拷贝拷贝所有层。

    In [42]: li = [1,2,3,[4,5]]
    In [43]: li2 = copy.copy(li)
    In [44]: li3 = copy.deepcopy(li)
    
    
    In [45]: li[-1][-1] = "222"
        
    In [46]: li
    Out[46]: [1, 2, 3, [4, '222']]
    
    In [47]: li2
    Out[47]: [1, 2, 3, [4, '222']]
    
    In [48]: li3
    Out[48]: [1, 2, 3, [4, 5]]
    
    7、闭包
    内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包。

    闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

    def func():
        
        def inner():
            print('aaaa')  
            
        return inner
    
    func()()  # aaaa 
    
    6、装饰器

    调用装饰器其实是一个闭包函数,为其他函数添加附加功能,不修改被修改的源代码和不修改被修饰的方式,装饰器的返回值也是一个函数对象。
    比如:插入日志、性能测试、事物处理、缓存、权限验证等,有了装饰器,就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。

    # 装饰器
    import time
    def login(func):
        def inner():
            start_time = time.time()
            func()
            end_time = time.time()
            print("fun 执行时间",end_time-start_time)
        return inner
    
    @login
    def test():
        for i in range(10000):
            for j in range(10000):
                pass
        print('test函数执行')
    
    test()
    # test函数执行
    # fun 执行时间 2.0163347721099854
    
    1、什么是python?使用python有什么好处?

    python是一种编程语言,它有对象、模块、线程、异常处理和自动内存管理。它简洁,简单、方便、容易扩展、有许多自带的数据结果,而且它开源
    Python是一种解释性语言,它的源代码可以直接运行,Python解释器会将源代码转换成中间语言,之后再翻译成机器码再执行

    3、数组和元祖之间的区别是什么?

    数组和元祖之间的区别:数组内容可以被修改,而元祖内容是只读的,不可被修改的,另外元祖可以被哈希,比如作为字典的key

    5、os与sys区别:

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

    15、range-and-xrange
        py2:
            range() 生成的是列表
            xrange() 生成的是一个生成器 
        py3:
            range() 就是一个生成器
            xrange() 没了
    
    21、什么是pickling和unpickling?

    Pickle模块读入任何python对象,将它们转换成字符串,然后使用dump函数将其转储到一个文件中——这个过程叫做pickling
    反之从存储的字符串文件中提取原始python对象的过程,叫做unpickling

    8、迭代器与生成器

    生成器:Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。这也是生成器的主要好处。

    这里,最难理解的就是generator和函数的执行流程不一样。
    函数是顺序执行,遇到return语句或者最后一行函数语句就返回。generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次被next()调用时从上次返回的yield语句处继续执行。

    迭代器

    可以直接作用于for循环的数据类型:

    • 一类是集合数据类型,如listtupledictsetstr等;
    • 一类是generator,包括生成器和带yield的 generator function。
      不是一次性把数据加载到内存,而是被next()函数调用,不断返回下一个数据
    9、classmethod,staticmethod,property

    类方法:将类的函数转换成类方法,函数上装饰@classmethod会将函数的自动传值参数改成cls
    静态方法:此方法相当于给类扩展一个功能,将类内的函数实例化,给类或对象使用,此时类内的函数就是普通函数,不管是类还是实例化的对象都可以使用
    实例化:类的实例化就会产生一个实例(对象),可以理解为类()把虚拟的东西实例化,得到具体存在的值

    10、 new.init区别,如何实现单例模式,有什么优点

    __new__是一个静态方法,__init__是一个实例方法
    __new__返回一个创建的实例,init__什么都不返回
    new__返回一个cls的实例时后面的__init__才能被调用
    当创建一个新实例时调用__new
    ,初始化一个实例时调用__init

     _new_()在 _init_()之前被调用,用于生成实例对象。利用这个方法和类的属性的特点可以实现设计模式的单例模式。
     单例模式是指创建唯一对象,单例模式设计的类只能实例,实例化1个对象
    
                       class Singleton(object):
                            __instance=None
                            def __init__(self):
                                pass
                            def __new__(cls, *args, **kwargs):
                                if Singleton.__instance is None:
                                    Singleton.__instance=object.__new__(cls,*args,**kwargs)
                                return Singleton.__instance
    
    2. python面向对象中的反射:
    通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
    11、多进程,多线程,协程,GIL

    GIL:全局解释器锁,是锁在cpython解释器上,导致同一时刻,同一进程只能有一个线程被执行
    多进程:多进程模块multiprocessing来实现,cpu密集型,IO计算型可以用多进程
    多线程:多线程模块threading来实现,IO密集型,多线程可以提高效率
    协程:依赖于geenlet,对于多线程应用。cpu通过切片的方式来切换线程间的执行,遇到IO操作自动切换,线程切换时需要耗时,
    而协成好处没有切换的消耗,没有锁定概念。
    进程:是资源管理单位,进行是相互独立的,实现并发和并发
    线程:是最小的执行单位,线程的出现为了降低上下文切换的消耗,提供系统的并发性

    12、IO多路复用/异步非阻塞

    IO多路复用:通过一种机制,可以监听多个描述符 select/poll/epoll
    select:连接数受限,查找配对速度慢,数据由内核拷贝到用户态
    poll:改善了连接数,但是还是查找配对速度慢,数据由内核拷贝到用户态
    epoll:epoll是linux下多路复用IO接口,是select/poll的增强版,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率
    异步非阻塞:异步体现在回调上,回调就是有消息返回时告知一声儿进程进行处理。非阻塞就是不等待,不需要进程等待下去,
    继续执行其他操作,不管其他进程的状态。

    14、PEP8规范,规范的好处是什么?

    1.缩进:4个空实现缩进,尽量不使用Tab
    2.行:没行最大长度不超过79,换行可以使用反斜杠
    3.命名规范:
    4.注释规范:

    16、with上下文机制原理

    enter_和_exit,上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象类中声明_enter_和_exit_方法,
    使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须收到干预

    17、经典类、新式类

    经典类遵循:深度优先,python2中
    新式类遵循:广度优先,Python3中

    25、Python都有哪些自带的数据结构?
    可变:列表  字典
    不可变: 数字  字符串  元祖
    
    26、命名空间?

    在python中,所有的名字都存在于一个空间中,它们在改空间中存在和被操作——这就是命名空间,它就好像一个盒子,在每个变量名字都对应装着一个对象,
    当查询变量的时候,会从该盒子里面寻找相应的对象

    28、*args与**kwargs

    *args代表位置参数,它会接收任意多个参数并把这些参数作为元祖传递给函数。
    **kwargs代表的关键字参数,返回的是字典,位置参数一定要放在关键字前面

    7.索引B+树

    B+树(数据结构,平衡树,根节点,子节点,数据) 索引能够让数据库查询数据的速度上升,而使写入数据的速度下降, 因为平衡树这个结构必须一直维持在一个正确的状态, 增删改数据都会改变平衡树各节点中的索引数据内容,破坏树结构, 因此,在每次数据改变时, DBMS必须去重新梳理树(索引)的结构以确保它的正确,这会带来不小的性能开销, 也就是为什么索引会给查询以外的操作带来副作用的原因。

    8.哈希表

    (Hash Table,又称为散列表),是一种线性表的存储结构。通过把每个对象的关键字k作为自变量,通过一个哈希函数h(k),将k映射到下标h(k)处,并将该对象存储在这个位置。

    例如:数据集合{1,6,7,9},假设存在哈希函数h(x)使得h(1) = 0, h(6) = 2, h(7) = 4, h(9) = 5,那么这个哈希表被存储为[1,None, 6, None, 7, 9]。
    当我们查找元素6所在的位置时,通过哈希函数h(x)获得该元素所在的下标(h(6) = 2),因此在2位置即可找到该元素。
    

  • 相关阅读:
    SGU 271 Book Pile (双端队列)
    POJ 3110 Jenny's First Exam (贪心)
    HDU 4310 Hero (贪心)
    ZOJ 2132 The Most Frequent Number (贪心)
    POJ 3388 Japanese Puzzle (二分)
    UVaLive 4628 Jack's socks (贪心)
    POJ 2433 Landscaping (贪心)
    CodeForces 946D Timetable (DP)
    Android Studio教程从入门到精通
    Android Tips – 填坑手册
  • 原文地址:https://www.cnblogs.com/venicid/p/9669638.html
Copyright © 2011-2022 走看看