1. 程式人生 > >Python2018秋招(持續更新...)

Python2018秋招(持續更新...)

畢業即失業,苦逼的大四狗傷不起喲。

又到了一年一度的秋招了,筆者也在拉勾,智聯,boss直聘註冊了,投了50份簡歷,3個面試,然而全掛了。

筆者痛定思痛決定將自己的經歷貼出,希望可以幫到要面試的同學。

雨軒戀原創 轉載請註明來源 雨軒戀i - 部落格園  http://www.cnblogs.com/yuxuanlian/

 

演算法程式設計題

1 氣泡排序

思想:氣泡排序從小到大排序:一開始交換的區間為0~N-1,將第1個數和第2個數進行比較,前面大於後面,交換兩個數,否則不交換。再比較第2個數和第三個數,前面大於後面,交換兩個數否則不交換。依次進行,最大的數會放在陣列最後的位置。然後將範圍變為0~N-2,陣列第二大的數會放在陣列倒數第二的位置。依次進行整個交換過程,最後範圍只剩一個數時陣列即為有序。

程式碼:

#交換排序.氣泡排序
L = [1, 3, 2, 32, 5, 4]
def Bubble_sort(L):
    for i in range(len(L)):
        for j in range(i+1,len(L)):
            if L[i]>L[j]:
                # temp = L[j]
                # L[j] = L[i]
                # L[i] = temp
                L[i], L[j] = L[j], L[i]#交換順序

    print (L)
Bubble_sort(L)

 

2 插入排序

思想:插入排序從小到大排序:首先位置1上的數和位置0上的數進行比較,如果位置1上的數大於位置0上的數,將位置0上的數向後移一位,將1插入到0位置,否則不處理。位置k上的數和之前的數依次進行比較,如果位置K上的數更大,將之前的數向後移位,最後將位置k上的數插入不滿足條件點,反之不處理。

程式碼:

#1.直接插入排序
L = [1, 3, 2, 32, 15, 5, 4]
def Insert_sort(L):
    for i in range(1,len(L)):
        for j in range(0,i):#這裡面其實也是從前向後比較
            if L[i]<L[j]:
                L.insert(j,L[i])#在不大於的位置插入L[i],這個時候,列表加長了1位,L[i]插入到指定位置了,但它的值也向後移動了一位
                L.pop(i+1)#把原來L[i]的值刪除。
    print(L)
    #空間複雜度為O(1),時間複雜度為O(n*n)
Insert_sort(L)
# print sorted(L)#自帶的兩種排序
# L.sort()
# print L

 

3 選擇排序

思想:選擇排序從小到大排序:一開始從0~n-1區間上選擇一個最小值,將其放在位置0上,然後在1~n-1範圍上選取最小值放在位置1上。重複過程直到剩下最後一個元素,陣列即為有序。

程式碼:

L = [6, 3, 2, 32, 5, 4]
def Select_sort(L):
    for i in range(0,len(L)):
        for j in range(i,len(L)):
            if L[i] > L[j]:         #打擂臺的形式
                # temp = L[i]
                # L[i] = L[j]
                # L[j] = temp
                L[i],L[j] = L[j],L[i]
    return  L
print (Select_sort(L))

 

4 快速排序

思想:快速排序從小到大排序:在陣列中隨機選一個數(預設陣列首個元素),陣列中小於等於此數的放在左邊,大於此數的放在右邊,再對陣列兩邊遞迴呼叫快速排序,重複這個過程。

程式碼:

#1.高質量程式碼
def quick_sort(lists, left, right):
    # 快速排序
    if left >= right:
        return lists
    key = lists[left]
    low = left
    high = right
    while left < right:
        while left < right and lists[right] >= key:
            right -= 1
        lists[left] = lists[right]
        while left < right and lists[left] <= key:
            left += 1
        lists[right] = lists[left]
    lists[left] = key
    quick_sort(lists, low, left - 1)
    quick_sort(lists, left + 1, high)
    return lists
print (quick_sort(L,0,5))

 

  1. 斐波那契數列

斐波那契數列,又稱黃金分割數列,指的是這樣一個數列:0、1、1、2、3、5、8、13、21、34、……在數學上,斐波納契數列以如下被以遞迴的方法定義:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)

程式碼:

#最簡單的方法為陣列,其次為迴圈,最垃圾的為遞迴,到了40就算好久。。日後再琢磨陣列
a=[1,1]
def fn(n):
    count=0
    f0=1
    f1=1
    f2=0
    while count<n:
        count+=1
        f2=f1+f0
        f0=f1
        f1=f2
        a.append(f2)
    print('第%s項的項數為:%s'%(b,f2))
    print('斐波那契數列為:')
    print(a)
b=int(input('請輸入項數:'))
fn(b-2)

 

6 二分法查詢

思想:二分查詢又稱折半查詢,優點是比較次數少,查詢速度快,平均效能好;其缺點是要求待查表為有序表,且插入刪除困難。 此方法適用於不經常變動而查詢頻繁的有序列表。

程式碼:

l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
find_num = int(input('請輸入一個數字:'))
start = 0
end = len(l) - 1

while True:
    middle = (start + end) // 2
    if find_num == l[middle]:
        print('找到了!索引是:', middle)
        break
    elif find_num > l[middle]:
        start = middle + 1
    elif find_num < l[middle]:
        end = middle - 1
    if start > end:
        print('沒找到!', find_num)
        break

 

7 一個不知道長度的字串,即很長很長的字串,求字串每個詞的數量

類似a=dkjhagklfh豐¥270997樑hfjak

程式碼:

str='mynameisbobiamfromchina嘿嘿嘿嘿'
str=','.join(str) #以逗號分隔字串
print(str)
li=str.split(',')
print(li) #變成列表了
#統計每一個字元出現的次數:
for i in set(li):
    if li.count(i) >= 1:
        print('%s 出現了%d 次!'%(i, li.count(i)))

 

8 多重巢狀列表,輸出成一個列表,類似[1,[2[3,4],5],6,7],輸出[1,2,3,4,5,6]

程式碼:

l=[1,2,[3,4,[5,6],[7,8],9],10]
l1=[]
#遞迴函式實現:
def getitem(l):
    for item in l:
        if isinstance(item,list):
            getitem(item)
        else:
            print(item)
            l1.append(item)

getitem(l)
print(l1)

 

9 手寫列表逆輸出,[1,2,4,5,3,6]輸出[6,3,5,4,2,1]

程式碼:

a=[0,1,2,3,4,5,6,7,8,9,10]
b=[]
print(a[::-1]) #逆輸出

#手寫程式碼
count=len(a)
for i in range(len(a),0,-1):
    count-=1
    b.append(a[count])
print(b)

 

10 列表去重,也是不知道長度,[1,2,3,2,3,1,2,3,1,1,1]輸出[1,2,3]

程式碼:

ids = [1,2,3,3,4,2,3,4,5,6,1,6,4,3,2,3,]
news_ids = []
for id in ids:
    if id not in news_ids:
        news_ids.append(id)
print (news_ids)

 

11 待續...

 

 

資料庫相關知識

 

1 MySQL資料庫與Oracle資料庫的區別。

1、體積不同。

Oracle它體積比較龐大,一般是用來開發大型應用(例如分散式)的。而MySQL的體積相對來說比較小,較之Oracle更容易安裝、維護以及管理,操作也簡單,最重要的是它是三個中唯一一個開源資料庫,但目前也屬於Oracle公司的產品了。

2、容量不同。

Oracle容量無限,根據配置決定;而MySQL使用MyISAM儲存引擎,最大表尺寸為65536TB。 MySQL資料庫的最大有效表尺寸通常是由作業系統對檔案大小的限制決定的,而不是由MySQL內部限制決定。

3、平臺支援及速度的區別。

Oracle支援大多數平臺;而MySQL支援各種平臺,適合Linux。至於速度,Oracle在Linux下的效能,在少量資料時速度低於MySQL,在千萬級時速度快於MySQL。

4、資料庫崩潰造成的影響不同。

Oracle資料庫崩潰後恢復很麻煩,因為他把很多東西放在記憶體裡;資料庫連線要慢些,最好用連線池;而MySQL使用預設的IP埠,但是有時候這些IP也會被一些黑客闖入,使用MyISAM配置,不慎損壞資料庫,結果可能會導致所有的資料丟失。

 

2 MySQL資料庫中查100w條資料和Oracle中查100w條資料的區別。

MySQL資料庫實現分頁比較簡單,提供了 LIMIT函式。一般只需要直接寫到sql語句後面就行了。

LIMIT子 句可以用來限制由SELECT語句返回過來的資料數量,它有一個或兩個引數,如果給出兩個引數, 第一個引數指定返回的第一行在所有資料中的位置,從0開始(注意不是1),第二個引數指定最多返回行數。例如:

select * from table WHERE … LIMIT 10; #返回前10行

select * from table WHERE … LIMIT 0,10; #返回前10行

select * from table WHERE … LIMIT 10,20; #返回第10-20行資料

 

ORCALE資料庫實現分頁查詢可以使用 row_number()函式或者使用rownum 虛列兩種方法。

第二種方法:直接使用rownum 虛列

select * from

(select t.*,rownum as rowno from TABLE1 )

where rowno between 10 and 20

這兩種方法比較,顯然第二種方法比較好。因為不用order by語句,會提高檢索資料的速度的,尤其資料量越大時,第二種方法快速檢索資料越明顯。

 

3 SQL注入是什麼。

SQL注入:利用現有應用程式,將(惡意)的SQL命令注入到後臺資料庫引擎執行的能力,這是SQL注入的標準釋義。

隨著B/S模式被廣泛的應用,用這種模式編寫應用程式的程式設計師也越來越多,但由於開發人員的水平和經驗參差不齊,相當一部分的開發人員在編寫程式碼的時候,沒有對使用者的輸入資料或者是頁面中所攜帶的資訊(如Cookie)進行必要的合法性判斷,導致了攻擊者可以提交一段資料庫查詢程式碼,根據程式返回的結果,獲得一些他想得到的資料。

 

4 資料庫的三正規化。

第一正規化:確保每列的原子性.

第二正規化:在第一正規化的基礎上更進一層,目標是確保表中的每列都和主鍵相關.

第三正規化:在第二正規化的基礎上更進一層,目標是確保每列都和主鍵列直接相關,而不是間接相關.

 

5 什麼是事務,MySQL如何支援事務。

MySQL 事務主要用於處理操作量大,複雜度高的資料。比如說,在人員管理系統中,你刪除一個人員,你即需要刪除人員的基本資料,也要刪除和該人員相關的資訊,如信箱,文章等等,這樣,這些資料庫操作語句就構成一個事務!

 

在 MySQL 中只有使用了 Innodb 資料庫引擎的資料庫或表才支援事務。

事務處理可以用來維護資料庫的完整性,保證成批的 SQL 語句要麼全部執行,要麼全部不執行。

事務用來管理 insert,update,delete 語句

一般來說,事務是必須滿足4個條件(ACID)::原子性(Atomicity,或稱不可分割性)、一致性(Consistency)、隔離性(Isolation,又稱獨立性)、永續性(Durability)。

 

6 MySQL主鍵和外來鍵的區別。

主鍵是能確定一條記錄的唯一標識,比如,一條記錄包括身份正號,姓名,年齡。身份證號是唯一能確定你這個人的,其他都可能有重複,所以,身份證號是主鍵。

外來鍵用於與另一張表的關聯。是能確定另一張表記錄的欄位,用於保持資料的一致性。一個表可以有多個外來鍵。

 

 

 

 

7 使用ORM和原生SQL的優缺點。

ORM框架:

    物件關係對映,通過建立一個類,這個類與資料庫的表相對應!類的物件代指資料庫中的一行資料。

簡述ORM原理:

    讓使用者不再寫SQL語句,而是通過類以及物件的方式,和其內部提供的方法,進行資料庫操作!把使用者輸入的類或物件轉換成SQL語句,轉換之後通過pymysql執行完成資料庫的操作。

ORM的優缺點:

  優點:

    提高開發效率,降低開發成本

    使開發更加物件化

    可移植

    可以很方便地引入資料快取之類的附加功能

  缺點:

    在處理多表聯查、where條件複雜之類的查詢時,ORM的語法會變得複雜。就需要寫入原生SQL。

 

8.待續...

 

 

 

 

技能和專案

1 裝飾器的寫法以及應用

#裝飾器的應用場景:比如插入日誌,效能測試,事務處理,快取等等場景。
def outer(func):
    def inner(*args,**kwargs):
        print("認證成功!")
        result = func(*args,**kwargs)
        print("日誌新增成功")
        return result
    return inner

@outer
def f1(name,age):
    print("%s 正在連線業務部門1資料介面......"%name)

呼叫方法
f1("jack",18)
#裝飾器呼叫方法,其實是把函式 f1 當成 outer的引數

 

2 生成器的寫法以及應用

#如果列表元素可以按照某種演算法推算出來,那我們是否可以在迴圈的過程中不斷推算出後續的元素呢?
這樣就不必建立完整的list,從而節省大量的空間。
Python中,這種一邊迴圈一邊計算的機制,稱為生成器(Generator

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
fib(8)
#生成器呼叫方法,其實是

 

3 HTTP中常見的請求頭

Accept:瀏覽器端可以接受的媒體型別,萬用字元 * 代表任意型別

Accept-Encoding:瀏覽器申明自己接收的編碼方法,例如: Accept-Encoding: zh-CN,zh;q=0.8

Accept-Language: 瀏覽器申明自己接收的語言,

Connection: 如Connection: keep-alive 當一個網頁開啟完成後,客戶端和伺服器之間用於傳輸HTTP資料的TCP連線不會關閉,如果客戶端再次訪問這個伺服器上的網頁,會繼續使用這一條已經建立的連線。

Referer:當瀏覽器向web伺服器傳送請求的時候,一般會帶上Referer,告訴伺服器我是從哪個頁面連結過來的,伺服器籍此可以獲得一些資訊用於處理。

User-Agent:告訴HTTP伺服器, 客戶端使用的作業系統和瀏覽器的名稱和版本.

Cookie:Cookie是用來儲存一些使用者資訊以便讓伺服器辨別使用者身份的(大多數需要登入的網站上面會比較常見),比如cookie會儲存一些使用者的使用者名稱和密碼,當用戶登入後就會在客戶端產生一個cookie來儲存相關資訊,這樣瀏覽器通過讀取cookie的資訊去伺服器上驗證並通過後會判定你是合法使用者,從而允許檢視相應網頁。

 

一般爬蟲的代理設定就在User-Agent裡面

 

4 HTTP中常見的狀態碼

1開頭(資訊)

       2開頭(成功)

           200(OK):請求成功

           202(Accepted):已接受請求,尚未處理

           204(No Content):請求成功,且不需返回內容

       3開頭(重定向)

           301(Moved Permanently):被請求的資源已永久移動到新位置

           301(Moved Temporarily):被請求的資源已臨時移動到新位置

       4開頭(客戶端錯誤)

           400(Bad Request):請求的語義或是引數有錯

           403(Forbidden):伺服器拒絕了請求

           404(Not Found):未找到請求的資源

       5開頭(伺服器錯誤)

          500(Internal Server Error):伺服器遇到錯誤,無法完成請求

          502(Bad Getway):閘道器錯誤,一般是伺服器壓力過大導致連線超時       

          503(Service Unavailable):伺服器宕機

 

5 Scrapy如何處理反爬蟲

  1. 隨機user-agent
  2. 新增Referer
  3. 延時處理
  4. 隨機代理ip

 

6 Scrapy爬蟲程式中斷如何繼續

總之我們要想保證爬取資料的完整就要犧牲程式的效率。

1.把所有爬取過的url列表儲存到一個檔案當中,然後再次啟動的時候每次爬取要和檔案當中的url列表對比,如果相同則不再爬取。

2.在scrapy再次啟動爬取的時候和資料庫裡面的資料做對比,如果相同則不存取。

3.就是利用Request中的優先順序(priority)

 

7 Flask框架的優勢

一、整體設計方面

首先,兩者都是非常優秀的框架。整體來講,兩者設計的哲學是區別最大的地方。Django提供一站式的解決方案,從模板、ORM、Session、Authentication等等都分配好了,連app劃分都做好了,總之,為你做盡量多的事情,而且還有一個killer級的特性,就是它的admin,配合django-suit,後臺就出來了,其實最初Django就是由在新聞釋出公司工作的人設計的。Flask只提供了一些核心功能,非常簡潔優雅。它是一個微框架,其他的由擴充套件提供,但它的blueprint使它也能夠很方便的進行水平擴充套件。

二、路由設計

Django的路由設計是採用集中處理的方法,利用正則匹配。Flask也能這麼做,但更多的是使用裝飾器的形式,這個有優點也有缺點,優點是讀原始碼時看到函式就知道怎麼用的,缺點是一旦原始碼比較長,你要查路由就不太方便了,但這也促使你去思考如何更合理的安排程式碼。

三、應用模組化設計

Django的模組化是整合在命令裡的,也就是說一開始Django的目標就是為以後玩大了做準備的。每個都是一個獨立的模組,為以後的複用提供了便利。Flask通過Blueprint來提供模組化,自己對專案結構劃分成不同的模組進行組織。

四、配置

Django的配置主要還是靠settings.py來做,當然為了Development和Production環境分離,還有一些方法來處理配置。Flask的配置很靈活,有多種方法配置,不同環境的配置也非常方便。

 

8 待續...

 

 

 

 

其他雜項

1 你在學校都學過什麼課程

...資料結構,軟體工程,軟體測試,計算機網路以及各種語言。。。

2 知道cpy和pypy麼

CPython

  當 從Python官方網站下載並安裝好Python2.7後,就直接獲得了一個官方版本的直譯器:Cpython,這個直譯器是用C語言開發的,所以叫 CPython,在命名行下執行python,就是啟動CPython直譯器,CPython是使用最廣的Python直譯器。

IPython

  IPython是基於CPython之上的一個互動式直譯器,也就是說,IPython只是在互動方式上有所增強,但是執行Python程式碼的功能和CPython是完全一樣的,好比很多國產瀏覽器雖然外觀不同,但核心其實是呼叫了IE。

PyPy

  PyPy是另一個Python直譯器,它的目標是執行速度,PyPy採用JIT技術,對Python程式碼進行動態編譯,所以可以顯著提高Python程式碼的執行速度。

 

3 週末有什麼打算

...作為一名肥宅,我只想在宿舍腐爛

4 平時熬夜麼

...不熬夜啊,只是修仙而已

5 為什麼學習Python

...人生苦短,我用Python

6 你老家是山西的,你想在北京發展嗎

...不打算在北京發展,為什麼我要投北京公司的簡歷

7 你還有什麼問題要問我的嗎

...為什麼HR問的問題都這麼千奇百怪

8 在學校的英語和數學怎麼樣

...只聽過雅蠛蝶和為什麼1+1=2

9 除了語言課,你在學校在哪一方面的專業課比較好

...打LOL嗎,我亞索賊6

10 能說說瀑布模型開發嗎

...制定計劃、需求分析、軟體設計、程式編寫、軟體測試和執行維護等六個基本活動

11 什麼是OOP,即面向物件程式設計思想

...OOP,不就是OPPO Find X 你值得擁有

12 如果你學的Python,突然有個小專案需要用到java,你會怎麼做

...我選擇刪除資料庫,然後跑路

13 待續...

 

以上的題就隨緣發揮吧。。。