1. 程式人生 > >面試題 - 1

面試題 - 1

1. 下面程式碼會輸出什麼?說明理由。

def f(x,L=[]):
    for i in range(x):
        L.append(i*i)
    print(L)

f(2)
f(3,[3,2,1])
f(3)

答案: 

[0, 1]
[3, 2, 1, 0, 1, 4]
[0, 1, 0, 1, 4]

原因:函式的形參如果設定了預設引數,且預設引數為可變型別,在呼叫時,如果不傳遞引數值,使用預設引數,則預設引數使用同一個引用地址的資料,不會進行二次初始化

2. 下面程式碼會輸出什麼?說明理由。

a = [1,2,3]
b = a
b += [1,2,3]
print(a,b)

c = [1,2,3]
d = c
d = d + [1,2,3]
print(c,d)

答案:

a = [1,2,3]
b = a # a,b用的同一塊記憶體空間
b += [1,2,3] # b.extend([1,2,3]) 在列表末尾一次性追加另一個序列中的多個值(用新列表擴充套件原來的列表)
print(id(a))  # 140276163651016
print(id(b))  # 140276163651016
print(a,b) # [1, 2, 3, 1, 2, 3] [1, 2, 3, 1, 2, 3]

c = [1,2,3]
d = c # 此時c,d用的同一塊記憶體空間
d = d + [1,2,3] # 修改了d的指向,又開闢了一塊空間
print(id(c))  # 140276162975624
print(id(d))  # 140276162975880
print(c,d)  # [1, 2, 3] [1, 2, 3, 1, 2, 3]

3. 使用map和匿名函式生成一個列表,其中列中的元素都滿足對1-10內的資料做平方和再加1的處理。

答案:

"""
map(function, iterable):會根據提供的函式對指定序列做對映,
                第一個引數 function 以引數序列中的每一個元素呼叫 function 函式,
                返回包含每次 function 函式返回值的新列表
引數:
    function -- 函式
    iterable -- 一個或多個序列
返回值:
    Python 2.x 返回列表。
    Python 3.x 返回迭代器。
"""

num_list = map(lambda x: x * x + 1, range(6))
# for num in num_list:
#     print(num)
print(list(num_list))

4. 寫一個三次認證(程式設計):實現使用者輸入使用者名稱和密碼,當用戶名為 admin 或 guest 且 密碼為 123 時,顯示登入成功,否則登入失敗,失敗時允許重複輸入三次。

答案:

i = 0
while i < 3:
    username = input("請輸入使用者名稱:")
    pwd = input("請輸入密碼:")
    if username in ('admin', 'guest') and pwd == '123':
        print("登陸成功!")
        break
    else:
        if i < 2:
            print("登陸失敗,請再次輸入(^_^)")
        else:
            print("登陸失敗!")
        i += 1

5. 隨意編寫兩個對輸入引數做加減乘除運算的函式(需要有除法),寫完後,用裝飾器實現對函數出現除數為0這種異常的捕獲,如果有異常,使用print列印日誌

答案:

"""
日誌級別: debug < info < warning < error < critical
logging.debug('debug級別,最低級別,一般開發人員用來列印一些除錯資訊')
logging.info('info級別,正常輸出資訊,一般用來列印一些正常的操作')
logging.warning('waring級別,一般用來列印警告資訊')
logging.error('error級別,一般用來列印一些錯誤資訊')
logging.critical('critical 級別,一般用來列印一些致命的錯誤資訊,等級最高')

"""

import logging


def func(func):
    def call_func(*args, **kwargs):
        # 捕獲異常
        try:
            func(*args, **kwargs)
        except Exception as error:
            logging.warning(error)

    return call_func


@func
def op(num1, num2):
    a = num1 + num2
    b = num1 - num2
    c = num1 * num2
    d = num1 / num2
    print(a, b, c, d)


num1 = int(input("請輸入第一個數字:"))
num2 = int(input("請輸入第二個數字:"))
op(num1, num2)

6. 簡述python中的垃圾回收機制。

答案:

  1. 當記憶體中有不再使用的部分時,即引用計數(一種python的記憶體管理機制)為0的物件,垃圾收集器就會把他們清理掉。還有一種情況也會被垃圾收集器清掉:當兩個物件相互引用時,他們本身其他的引用已經為0了。
  2. 垃圾回收機制還有一個迴圈垃圾回收器,確保釋放迴圈引用物件(a引用b,b引用a,導致其引用計數永遠不為0)。

7. 簡述python成員私有化的原理。下例中,如何在外部直接將 __score 改為120?

class score:
    def __init__(self):
        self.__score = 59

    def get_score(self):
        print(self.__score)

    def set_score(self, value):
        if value <= 100:
            self.__score = value
            print(self.__score)
        else:
            print("....")

答案:

原理:python會對私有成員進行名稱改編為_Class__object,即儲存的是:_score__score

class score:
    def __init__(self):
        self.__score = 59

    def get_score(self):
        print(self.__score)

    def set_score(self, value):
        if value <= 100:
            self.__score = value
            print(self.__score)
        else:
            print("....")


stu = score()
# print(stu._score__score)
stu._score__score = 120
print(stu._score__score)
# dir():內建函式,列出物件的所有屬性及方法
print(dir(stu))
# 輸出
"""
120
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_score__score', 'get_score', 'set_score']
"""

8. 用自己的語言說一下什麼是多型(簡潔)

答案:

多型就是同一種事物的多種形態,如不同的子類物件呼叫相同的父類方法,產生不同的執行結果