練習題

深圳騎士計劃脫產班全棧3期統一考試html

 

深圳騎士計劃脫產班全棧3期第三次統一考試python

考試時長:5個小時                   滿分:150分mysql

 

評分標準(150分):  (150, 'A+'), (136, 'A'), (129, 'B+'), (121, 'B'), (106, 'B-'), (91, 'C+'), (76, 'C'), (61, 'C-'), (0, ' D')正則表達式

 

1.請編寫一個函數實現將IP地址轉換成一個整數。(5分)redis

 

如 10.3.9.12 轉換規則爲:算法

        10            00001010sql


         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)不可靠的、無鏈接的服務,傳輸效率高(發送前時延小),一對1、一對多、多對1、多對多、面向報文,盡最大努力服務,無擁塞控制。使用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分)

相關文章
相關標籤/搜索