• 练习题


    深圳骑士计划脱产班全栈3期统一考试

     

    深圳骑士计划脱产班全栈3期第三次统一考试

    考试时长:5个小时                   满分:150分

    评分标准(150分):  (150, 'A+'), (136, 'A'), (129, 'B+'), (121, 'B'), (106, 'B-'), (91, 'C+'), (76, 'C'), (61, 'C-'), (0, ' D')

    1.请编写一个函数实现将IP地址转换成一个整数。(5分)

    如 10.3.9.12 转换规则为:

            10            00001010


             3            00000011

             9            00001001


            12            00001100

    再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?

    答:

    复制代码
    # -*- coding: utf-8 -*-
    # __author: Tiger_Lee
    # @file: 考试题.py
    # @time: 2019 02 26
    # @email: lxh661314@163.com
    
    
    # 赠送内容:用Python获取本机ip地址
    
    from socket import gethostbyname_ex, gethostname
    
    
    local_IP_list = gethostbyname_ex(gethostname())
    local_IP = gethostbyname_ex(gethostname())[2][0]
    
    
    def decimal_to_binary(ip_add):
        """
        将ip地址转换为二进制
        :param ip_add: 
        :return: 
        """
        num_list = ip_add.split(".")
        ip_binary = ""
        for num in num_list:
            num = bin(int(num))[2:]
            binary_num = num.rjust(8, '0')
            ip_binary += binary_num + " "
    
        return ip_binary[:-1]
    
    
    binary_ip = decimal_to_binary(local_IP)
    print(binary_ip)
    
    
    def binary_to_decimal(binary):
        """
        将二进制转换为IP地址
        :param binary: 
        :return: 
        """
        ip_str = ""
        binary_list = binary.split(" ")
        for num in binary_list:
            ip_str += str(int(num, 2)) + "."
    
        return ip_str[:-1]
    
    
    print(binary_to_decimal(binary_ip))
    复制代码

    2.python递归的默认最大层数(1分),怎么更改其默认最大层数?(2分)(本题总分3分)

    复制代码
    # import sys
    # sys.setrecursionlimit(100000)
    #
    # def func(n):
    #     print(n)
    #     n += 1
    #     func(n)
    #
    # func(0)
    复制代码

    3.请写出print的结果:(3分)

        v1 = 1 or 3

        v2 = 1 and 3

        v3 = 0 and 2 and 1

        v4 = 0 and 2 or 1

        v5 = 0 and 2 or 1 or 4

        v6 = 0 or False and 1

        print(v1, v2, v3, v4, v5, v6)

    答:

    1,3,0,1,1,False

    4.用一行代码实现数值交换:(2分)


         a = 1

         b = 2

    答:

    a, b = b, a

    5.如何安装第三方模块?(1分)以及用过哪些第三方模块?(2分)(本题总分3分)

    方法1:pip install 第三方模块
    方法2:pycharm中鼠标操作
    
    用过:greenlet gevent pymysql socket

    6.谈谈你对闭包的理解?(2分)并写一个闭包函数。(2分)(本题总分4分)

    复制代码
    内层函数对外层函数非全局变量的引用,该内部函数称为闭包函数
    
    def func():
        name = '666'
        def inner():
            print(name)
        return inner
    
    
    f = func()
    f()
    复制代码

    7.什么是反射?(2分)以及应用场景?(2分)(本题总分4分)

    复制代码
    通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
    应用场景:
    
    class Foo:
        f = '类的静态变量'
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
        def say_hi(self):
            print('hi,%s'%self.name)
    
    
    obj=Foo('egon',73)
    
    
    #检测是否含有某属性
    print(hasattr(obj,'name'))
    print(hasattr(obj,'say_hi'))
    
    #获取属性
    n=getattr(obj,'name')
    print(n)
    func=getattr(obj,'say_hi')
    func()
    print(getattr(obj,'aaaaaaaa','不存在啊')) #报错
    
    
    #设置属性
    setattr(obj,'sb',True)
    setattr(obj,'show_name',lambda self:self.name+'sb')
    print(obj.__dict__)
    print(obj.show_name(obj))
    
    
    #删除属性
    delattr(obj,'age')
    delattr(obj,'show_name')
    delattr(obj,'show_name111')#不存在,则报错
    print(obj.__dict__)
    复制代码

    8.什么是面向对象的mro?(3分)

    答 :

    对于你定义的每一个类,Python 会计算出一个方法解析顺序(Method Resolution Order, MRO)列表,它代表了新式类中类继承的顺序

    9.简述 yield和yield from关键字。(3分)

    答 :

    在python中用yield和yield from都是构造一个生成器函数
    
    yield后面返回的是一个值
    yield from则是直接返回一个生成器

    10.简述 OSI 七层协议。(写出7层2分,简述每一层总分3分)(本题总分5分)

    答 :

    复制代码
    应用层  网络服务与最终用户的一个接口。
                 常见协议:HTTP FTP TFTP SMTP SNMP DNS TELNET HTTPS POP3 DHCP
    
    表示层  数据的表示、安全、压缩。(在五层模型里面已经合并到了应用层)
                 格式有,JPEG、ASCll、DECOIC、加密格式等
    
    会话层  建立、管理、终止会话。(在五层模型里面已经合并到了应用层)
                 对应主机进程,指本地主机与远程主机正在进行的会话
    
    传输层  定义传输数据的协议端口号,以及流控和差错校验。
                 常见协议:TCP UDP,数据包一旦离开网卡即进入网络传输层
                 常见的物理设备 :四层路由器、四层交换机
    
    网络层  进行逻辑地址寻址,实现不同网络之间的路径选择。
                 常见协议:ICMP IGMP IP(IPV4 IPV6) ARP RARP
                 常见物理设备:路由器、三层交换机
    
    数据链路层 建立逻辑连接、进行硬件地址寻址、差错校验 [2]  等功能。(由底层网络定义协议)
                 将比特组合成字节进而组合成帧,用MAC地址访问介质,错误发现但不能纠正。
                ,常见协议:ARP协议
                 常见物理设备:网桥、以太网交换机、网卡
    
    物理层  建立、维护、断开物理连接。(由底层网络定义协议)
                 常见物理设备:中继器、集线器、双绞线
    复制代码

    11.什么是C/S和B/S架构?(2分)

    答 :

    复制代码
    Client与Server ,中文意思:客户端与服务器端架构,这种架构也是从用户层面(也可以是物理层面)来划分的。
    这里的客户端一般泛指客户端应用程序EXE,程序需要先安装后,才能运行在用户的电脑上,对用户的电脑操作系统环境依赖较大。
    
    B/S即:Browser与Server,中文意思:浏览器端与服务器端架构,这种架构是从用户层面来划分的。
    Browser浏览器,其实也是一种Client客户端,只是这个客户端不需要大家去安装什么应用程序,只需在浏览器上通过HTTP请求服务器端相关的资源(网页资源),客户端Browser浏览器就能进行增删改查。
    复制代码

    12.简述 三次握手、四次挥手的流程。(4分)

    复制代码
    TCP的三次握手
    
    TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN+ACK[1],并最终对对方的 SYN 执行 ACK 确认。这种建立连接的方法可以防止产生错误的连接。[1]
    
    TCP三次握手的过程如下:
    客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SEND状态。
    服务器端收到SYN报文,回应一个SYN (SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态。
    客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。
    三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。
    
    
    TCP的四次挥手
    
    建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的。
    (1) 某个应用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。
    (2) 接收到这个FIN的对端执行 “被动关闭”(passive close),这个FIN由TCP确认。
    注意:FIN的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其他数据之后,因为,FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。
    (3) 一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。
    (4) 接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。[1]
    既然每个方向都需要一个FIN和一个ACK,因此通常需要4个分节。
    
    注意:
    (1) “通常”是指,某些情况下,步骤1的FIN随数据一起发送,另外,步骤2和步骤3发送的分节都出自执行被动关闭那一端,有可能被合并成一个分节。[2]
    (2) 在步骤2与步骤3之间,从执行被动关闭一端到执行主动关闭一端流动数据是可能的,这称为“半关闭”(half-close)。
    (3) 当一个Unix进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭,这也导致仍然打开的任何TCP连接上也发出一个FIN。
    无论是客户还是服务器,任何一端都可以执行主动关闭。通常情况是,客户执行主动关闭,但是某些协议,例如,HTTP/1.0却由服务器执行主动关闭。[2]
    复制代码

    13.什么是arp协议?(2分)

    地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。

    14.TCP和UDP的区别?(3分)

    TCP(Transmission Control Protocol)可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;电子邮件、文件传输程序。
    
    UDP(User Datagram Protocol)不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文,尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)。

    15.为何基于tcp协议的通信比基于udp协议的通信更可靠?(2分)

    当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,流量控制等功能,保证能从一端传到另一端。

    16.什么是粘包?(1分) socket 中造成粘包的原因是什么?(2分) 哪些情况会发生粘包现象?(2分)(本题总分5分)

    粘包 :在tcp协议中,几条连续发送的数据在接收端粘在一起。
    粘包成因 :本质是发送信息与接受信息的边界不清晰造成的
    哪些情况会发生粘包 :发送端的缓存机制、接收端的缓存机制

    17.什么是进程?(2分)请简述进程的三个状态?(2分)(本题总分4分)

    在运行中的程序就是进程
    进程是计算机中最小的资源分配单位
    进程的三状态 :就绪 运行 阻塞

    18.什么是线程?(3分)

    线程是计算机中能被CPU调度的最小单位

    19.简述 进程、线程、协程的区别?(3分) 以及应用场景?(3分)(本题总分6分)

    进程:数据隔离,可以利用多核,会产生数据不安全的现象。常用于数据隔离度高的高计算型场景
    
    线程:数据共享,在python中不能利用多核,操作系统级别,会产生数据不安全的现象。常用于数据隔离度低的高IO型场景。
    
    协程:数据共享,不能利用多核,用户级,操作系统不可见,不存在数据安全问题。常用于数据隔离度低的高IO型场景。

    20.GIL是什么?(3分)

    全局解释器锁。
    
    该锁是Cpython解释器中特有的
    
    保证了同一个python进程中的多个线程同一时刻只能有一条线程访问CPU。

    21.Python中如何使用线程池和进程池?(4分)

    复制代码
    线程池
    from concurrent.futures import ThreadPoolExecutor
    p = ThreadPoolExecutor(5)
    
    进程池
    from concurrent.futures import ProcessPoolExecutor
    p = ProcessPoolExecutor(5)
    复制代码

    22.进程之间如何进行通信?(3分)

    可以通过原生socket通信
    
    如果是在同一个进程中,也可以使用multiprocessing自带的pipe或者queue进行通信
    
    也可以使用第三方工具:memcache、redis、kafka、rabbitmq

    23.什么是并发和并行?(3分)

    并行 : 并行是指两者同时执行,比如赛跑,两个人都在不停的往前跑;(资源够用,比如三个线程,四核的CPU )
    
    并发 : 并发是指资源有限的情况下,两者交替轮流使用资源,比如一段路(单核CPU资源)同时只能过一个人,A走一段后,让给B,B用完继续给A ,交替使用,目的是提高效率。

    24.你知道几种锁(请列出)?(1分)并解释它们的作用和区别?(3分)(本题总分4分)

    互斥锁和递归锁 都是为了保证在并发编程中的数据安全问题
    
    互斥锁 :在一个进程或者线程单位中只能连续调用一次,否则就会发生死锁现象
    
    递归锁 :在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock

    25.解释什么是异步非阻塞?(4分)

    异步:程序在做多件事情的时候,不必按照顺序执行,可以各自执行各自的不受干扰
    
    非阻塞:程序中没有阻塞现象

    26.简述 gevent模块的作用和应用场景?(4分)

    协程模块
    
    可以用来规避单线程中的IO操作,提高线程对CPU的利用率
    可用于 爬虫等IO操作比较频繁的网络应用场景

    27.请实现功能 : 在不改变装饰器的情况下,给装饰器的执行加上log信息。(5分)

    def log(wrap):

       …

    @log              

    def wrapper(func):

        def inner(*args,**kwargs):

            print('before func')

            ret =  func(*args,**kwargs)

            print('after func')

            return ret

        return inner

     

    @wrapper        

    def wahaha(name):

        print('%s in wahaha'%name)

     

    wahaha('alex')

     

    答:

    复制代码
    def log(wrap):
        def log_inner(*args,**kwargs):
            inn = wrap(*args,**kwargs)
            def inner(*args,**kwargs):
                ret = inn(*args,**kwargs)
                print(wrap.__name__,'is running')
                return ret
    
            return inner
    
        return log_inner
    
    
    @log              
    def wrapper(func):
        def inner(*args,**kwargs):
            print('before func')
            ret =  func(*args,**kwargs)
            print('after func')
    
            return ret
    
        return inner
    
     
    
    @wrapper         
    def wahaha(name):
        print('%s in wahaha'%name)
    
    
    wahaha('alex')
    复制代码

    28.写代码得到两个列表的交集和差集?(4分)

    l1 = [1,2,3]

    l2 = [2,3,4]

    复制代码
    # 交集
    print(set(l1) & set(l2))
    print(set(l1).intersection(set(l2)))
    
    # 差集
    print(set(l1) - set(l2))
    print(set(l1).difference(set(l2)))
    复制代码

    29.用python正则匹配字符串,<.*>和<.*?>有什么区别?(3分)

    复制代码
    <.*>是正则默认的贪婪匹配模式,会直接匹配到最后一个>
    <.*?>是正则表达式的惰性匹配模式,会匹配到第一个>
    例如 <h1>hahaha<h1>
    
    <.*> 匹配的结果是一个  <h1>hahaha<h1>
    <.*?> 匹配的结果是两个<h1>和<h1>
    复制代码

    30.读代码写出代码运行后的结果,并解释执行过程?(6分)

    def func(num):

        n, a, b = 0, 0, 1

        while n < num:

            yield b

            print(b, 'in func')

            a, b = b, a + b

            n = n + 1

    for i in func(5):

        print(i)

    复制代码
    yield: 带有yield的函数是一个迭代器,函数返回某个值时,会停留在某个位置,返回函数值后,会在前面停留的位置继续执行,直到程序结束

    结果是: 1 1 in func 1 1 in func 2 2 in func 3 3 in func 5 5 in func
    复制代码

    31.用Python实现一个二分查找的函数。(6分)

    二分查找算法

    32.读代码写答案:(4分)

    (1)

    a = range(10)

    b = range(20)

    z = zip(a, b)

    print(len(list(z)))  # 请写出打印结果

    print(len(list(z)))  # 请写出打印结果

    答:

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

    执行结果:
    10 0

    (2)

    def func(n):

        return n % 2 == 1

    newlist = filter(func, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

    print(list(newlist))  # 请写出打印结果

    答:

    filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
    执行结果:
    [1, 3, 5, 7, 9]

    (3)

    a = map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])

    print(list(a))  # 请写出打印结果

    答:

    map() 会根据提供的函数对指定序列做映射。

    执行结果:
    [3, 7, 11, 15, 19]

    33.读代码写出打印的结果,并解释为什么是这样。(6分)

    class A(object):

        def func(self):

            print('A')

    class B(A):

        def func(self):

            super().func()

            print('B')

    class C(A):

        def func(self):

            super().func()

            print('C')

    class D(B,C):

        def func(self):

            super().func()

            print('D')

    D().func()

    答案:

    复制代码
    A
    C
    B
    D
    
    这是新式类的继承顺序导致的,根据c3算法或者mro方法给出的结论都可以得出。
    复制代码

    34.列举你所知道的面向对象的特殊方法,及其应用?(5分,每写一个得0.5分)

    复制代码
    __len__   len 一个对象就会触发 __len__方法。
    __hash__()方法应该返回一个32位长的整数,对与同一个对象,__hash__()方法应该总是返回相同的值
    __str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
    __repr__ 如果一个类中定义了__repr__方法,那么在repr(对象) 时,默认输出该方法的返回值。
    __call__ 方法的执行是由对象后加括号触发的
    __eq__ x==y 运算将会调用实例x的__eq__(self, other)方法
    __del__  析构方法,当对象在内存中被释放时,自动触发执行。
    __new__ 构造方法__new__的执行是由创建对象触发的,即:对象 = 类名() 
    
    item系列将对象视为字典使用时,就会触发item方法
    __getitem__
    __setitem__
    __delitem__
    __delattr__
    复制代码

    35.用尽量多的方法实现单例模式。(8分)

    复制代码
    class A:
        __instance = None
    
        def __init__(self,name,age):
            self.name =name
            self.age = age
    
        def __new__(cls, *args, **kwargs):
            if cls.__instance is None:
                obj = object.__new__(cls)
                cls.__instance = obj
            return cls.__instance
    复制代码

    36.读代码回答其中的问题:(本题总分12分)

    (1)

    import threading

    import time

    def _wait():

        time.sleep(60)

    # FlagA

    t = threading.Thread(target=_wait, daemon=False)

    t.start()

    # FlagB

    # 问:程序从FlagA执行到FlagB的时间大致为多少秒?并简述为什么?(2分)

    0秒左右,因为创建一个线程并启动它的时间非常短。

    # 问:deamon=True时 程序从FlagA执行到FlagB的时间大致为多少秒?并简述为什么?(2分)

    0秒左右,如果设置deamon=True那么相当于开启了一个守护线程,守护线程会等待主线程结束之后才结束,而主线程会等待所有非守护线程子线程结束之后才结束,在程序中没有其他的非守护线程的子线程,因此主线程的代码结束之后守护线程就会立即结束。

    (2)

    loop = int(1E7)

    def _add(loop: int = 1):

        global number

        for _ in range(loop):

            number += 1

    def _sub(loop: int = 1):

        global number

        for _ in range(loop):

            number -= 1

    number = 0

    ta = threading.Thread(target=_add, args=(loop,))

    ts = threading.Thread(target=_sub, args=(loop,))

    ta.start()

    ts.start()

    ta.join()

    ts.join()

    # 问此时的number是否一定为零?并简述为什么?(2分)

    不一定,因为在CPU指令中,+=操作是被拆分为两条指令的,所以可能出现数据不安全的情况。

    (3)

    number = 0

    ta = threading.Thread(target=_add, args=(loop,))

    ts = threading.Thread(target=_sub, args=(loop,))

    ta.start()

    ta.join()

    ts.start()

    ts.join()

    # 问此时的number是否一定为零?并简述为什么?(2分)

    会,如果加上join就使得代码从异步变成同步了,一定不会发生数据不安全的问题。 

    (4)

    loop = int(1E7)

    def _add(loop: int = 1):

        global numbers

        for _ in range(loop):

            numbers.append(0)

    def _sub(loop: int = 1):

        global numbers

        for _ in range(loop):

            while not numbers:

                time.sleep(1E-8)

            numbers.pop()

    numbers = [0]

    ta = threading.Thread(target=_add, args=(loop,))

    ts = threading.Thread(target=_sub, args=(loop,))

    ta.start()

    ts.start()

    ta.join()

    ts.join()

    # 问此时的numbers的长度是否一定为1?并简述为什么?(2分)

    一定为1,因为列表的append操作是线程安全的。

     (5)

    numbers = [0]

    ta = threading.Thread(target=_add, args=(loop,))

    ts = threading.Thread(target=_sub, args=(loop,))

    ta.start()

    ta.join()

    ts.start()

    ts.join()

    # 问此时的numbers的长度是否一定为1?并简述为什么?(2分)

  • 相关阅读:
    Zend Studio下调试PHP的一点注意事项
    使用FTP出现中文乱码解决方案
    C++数据类型与C#对应表
    FineUI 开发B/S系统
    c#调用带输出参数的存储过程
    经典FormsAuthenticationTicket 分析
    C# Oracle数据库操作类实例详解
    如何使用C#的Hashtable[哈希表]
    对三层架构的理解
    C# 最简单的三层架构实例 ——转载自网易博客
  • 原文地址:https://www.cnblogs.com/gzying-01/p/10438272.html
Copyright © 2020-2023  润新知