平常點滴

1.restful api     爲何要有api?html

  方便不一樣系統之間的相互調用數據前端

2 restful規範python

  使用httpsmysql

3.HTTP協議的理解web

  基於socket使用TCP協議進行數據傳輸redis

  短鏈接,一次請求和響應以後斷開鏈接算法

  無狀態,短鏈接的特性形成的sql

  數據格式數據庫

4.公司的組織架構(公司部門的配比,人數)django

  開發:前端,後端,產品經理     UI:1人    測試 、運維、運營、銷售、人事、財務

5.認證方式和權限方式

  四種認證方式:session、cookie、token、jwt(json web token)--將用戶信息加密,加密後做爲token,https://blog.csdn.net/qq_40081976/article/details/79046825       https://www.jianshu.com/p/af8360b83a9f        https://www.cnblogs.com/zaixiuxing/p/6005968.html

單點登陸

  什麼是單點登陸?單點登陸全稱Single Sign On(如下簡稱SSO),是指在多系統應用羣中登陸一個系統,即可在其餘全部系統中獲得受權而無需再次登陸,包括單點登陸與單點註銷兩部分

  單點登陸的原理:https://www.cnblogs.com/ywlaker/p/6113927.html

6.將去重規則放在redis中的意義?

  意義:除了快,最主要的是能夠實現相似於分佈式的構造,將調度器和去重規則剖離出來,能夠實現每個爬蟲應用的調度。

7.在Python環境下用盡量多的方法反轉字符串,例如將s = "abcdef"反轉成 "fedcba"

第一種:使用字符串切片

result = s[::-1]

第二種:使用列表的reverse方法

l = list(s)
result = "".join(l.reverse())

固然下面也行

l = list(s)
result = "".join(l[::-1])

第三種:使用reduce

result = reduce(lambda x,y:y+x,s)

第四種:使用遞歸函數

def func(s):
    if len(s) <1:
        return s
    return func(s[1:])+s[0]
result = func(s)

第五種:使用棧

def func(s):
    l = list(s) #模擬所有入棧
    result = ""
    while len(l)>0:
        result += l.pop() #模擬出棧
    return result
result = func(s)

第六種:for循環

def func(s):
    result = ""
    max_index = len(s)-1
    for index,value in enumerate(s):
        result += s[max_index-index]
    return result
result = func(s)
View Code

8.django和flask的區別

  django  大而全     flask 小而精

  若是應用很是簡單,使用flask就會很是的快捷;若是應用比較複雜,就使用django,由於flask把全部的第三方組件拼起來就是個django。 

9.python中的垃圾回收機制

  python做爲一門動態語言,一個簡單的賦值語句也是很值得研究的,重要特色就是引用和對象分離

  python中使用引入計數爲主,標記清除,和分代回收爲輔

 每次建立對象都會分配內存,容器對象跟數字不同呢?這是由於Python的內存池機制。

Python內存池

      若是頻繁的調用 malloc 與 free 時,是會產生性能問題的.再加上頻繁的分配與釋放小塊的內存會產生內存碎片.  

Python 在這裏主要乾的工做有:

  若是請求分配的內存在1~256字節之間就使用本身的內存管理系統,不然直接使用 malloc.

  引用計數增長的狀況:

    1.對象被建立

    2.對象被當成參數傳入函數。

    3.對象的引用被建立   好比:a=1   b=a   

    4.做爲容器對象的一個元素

  引用計數減小的狀況:

    1.對象被刪除   好比:del a

    2.對象從容器中刪除   好比:li.remove(a)

    3.對象被從新賦值

    ...

  對於循環引用的對象,好比:a=[1,2],b = a.append(a),a.append(b),會採用標記清除

  引用計數是採用輪詢的方式查看那些引用爲0,這樣就會出現一個問題,效率很是的低,爲了解決效率低的問題,python引入了分代回收的機制。

  分代回收是一種以空間換時間的操做方式,Python將內存根據對象的存活時間劃分爲不一樣的集合,每一個集合稱爲一代,Python將內存分爲了3「代」,分別爲年輕代(第0代)、中年代(第1代)、老年代(第2代),他們對應的是3個鏈表,它們的垃圾收集頻率與對象的存活時間的增大而減少。新建立的對象都會分配在年輕代,年輕代鏈表的總數達到上限時,Python垃圾收集機制就會被觸發,把那些能夠被回收的對象回收掉,而那些不會回收的對象就會被移到中年代去,依此類推,老年代中的對象是存活時間最久的對象,甚至是存活於整個系統的生命週期內。同時,分代回收是創建在標記清除技術基礎之上。分代回收一樣做爲Python的輔助垃圾收集技術處理那些容器對象

建立對象和取消建立對象的差值700的時候
# gc.get_threshold()
# 鏈表 0代 1代 2代
# 每一代被觸發垃圾回收的時候 剩下沒有被回收的對象會被移到上一代裏面
# 當0代被觸發10次的時候 會觸發1代的回收 也會回收0代的
# 當1代被觸發10次的時候 會觸發2代的回收 所有回收

10.flask-session的 做用:

  將flask中的session由原來放置在加密cookie中,改成放置到其餘數據源。

11.flask-session的原理

  在flask中,請求進來後,會先執行open_session方法,該方法讀取用戶cookie中的session_id對應的隨機字符串;若是獲取到,根據隨機字符串去redis中獲取原來設置的值,並建立一個包含該值的字典。若是未獲取到,就生成一個隨機字符串並在內存中建立一個空字典。

  在視圖函數中,能夠對該字典進行操做。

  當請求結束時,會執行save_session方法,該方法去內存中讀取這個特殊的字典,並將字典序列化爲字符串,而後寫到redis中,在將隨機字符串寫到用戶的cookie中返回。

12.DBUtils的做用和原理

  做用:建立數據庫鏈接池。

  原理: 啓動時會在內存中維護一個鏈接池,當請求鏈接數據庫時則去鏈接池中獲取一個鏈接,若是有則獲取,沒有則等待或報錯。使用完畢後,將鏈接歸還到鏈接池中

 13.寫代碼的過程當中有沒有令你印象深入的事情。

  好比:使用flask文件上傳的時候,使用flask定製上傳文件大小的錯誤信息時,使用mac是沒有問題的,而使用Windows就會報錯。系flask中的一個bug。

from gevent.pywsgi import WSGIServer    

if __name__ == '__main__':
    # app.run(host='127.0.0.1',port=5000)
    http_server = WSGIServer(('127.0.0.1', 5000), app)
    http_server.serve_forever()
解決方式

14.上傳一個excle文件並讀取每一行的內容

# 上傳一個Excel文件並讀取其中每一行的內容 xlrd 模塊
import xlrd

f = xlrd.open_workbook(r'D:\新建文件夾\工做簿1.xlsx')
ret = f.sheets()[0] # 獲取第一個表格對象
print(type(ret))   # <class 'xlrd.sheet.Sheet'>

n = ret.nrows   #獲取行數
m = ret.ncols   # 獲取列數

# 獲取全部的數據
for i in range(n):
    for j in range(m):
        print(ret.row_values(i)[j],end=' ')      # ret.row_values(i)  獲取第幾行的數據
        # print(ret.col_values(j))
    print()

15.請在Context類下完成實現

 
 

 

  執行 with-as 時,會先執行 __enter__方法,並將該方法的返回值,賦值給as 後的對象,而後執行with-as 中的代碼塊,無論代碼塊中的代碼是否有異常,都會在離開執行__exit__方法,能夠在__exit__方法中作一些收尾工做或者捕捉異常的處理操做。

  因此,使用with - as 方法時,對象必須實現__enter__和__exit__方法。

class Context(object):

    def __enter__(self):
        return self

    def do_something(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        pass

with Context() as ctx:
    ctx.do_something()
代碼實現

16.簡述SQl注入的攻擊原理以及如何在代碼層面防止?

   SQL的攻擊原理:經過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令

  代碼層面:引發的主要緣由在於後臺寫SQL語句的時候用了字符串拼接

  解決方法:1 採用預編譯語句集  2,對傳過來的參數進行過濾 好比正則檢查是否包含非法字符等

17.django內置的緩存機制。
       django的緩存有六種
          -- memchched緩存
          -- 數據庫緩存
          -- 文件系統緩存
          -- 本地內存緩存
          -- 虛擬緩存
          -- 自定義緩存
    -- 應用
        -- 全棧緩存 粒度大 中間件配置
        -- 單獨視圖緩存 粒度適中 視圖上方加裝飾器或者在路由器配置

18.什麼是xss攻擊。

  -- XSS攻擊是向網頁中注入惡意腳本,用在用戶瀏覽網頁時,在用戶瀏覽器中執行惡意腳本的攻擊。
    -- XSS分類,反射型xss ,存儲型xss
    -- 反射型xss又稱爲非持久型xss,攻擊者經過電子郵件等方式將包含注入腳本的連接發送給受害者,
        受害者經過點擊連接,執行注入腳本,達到攻擊目的。
    -- 持久型xss跟反射型的最大不一樣是攻擊腳本將被永久的存放在目標服務器的數據庫和文件中,多見於論壇
        攻擊腳本連同正常信息一同注入到帖子內容當中,當瀏覽這個被注入惡意腳本的帖子的時候,惡意腳本會被執行
    -- 防範措施 1 輸入過濾  2 輸出編碼  3 cookie防盜
        1,輸入過濾 用戶輸入進行檢測 不容許帶有js代碼
        2,輸出編碼 就是把咱們的腳本代碼變成字符串形式輸出出來
        3,cookie加密

19.偏函數的做用和好處

  把一個函數的某些參數給固定住(也就是設置默認值),返回一個新的函數,調用這個新函數會更簡單。

  當函數的參數個數太多,須要簡化時,使用functools.partial能夠建立一個新的函數,這個新函數能夠固定住原函數的部分參數,從而在調用時更簡單。

20.判斷101-200之間有多少個質數(一個大於1的天然數,除了1和它自身外,不能被其餘天然數整除的數叫質數),並輸出全部的質數。

  解題思路:首先這個數確定得大於1,並且能被其餘天然數整除,就意味着整除它的數必然小於它自己,(若是大於其自己,獲得是一個小數),因此能夠寫一個函數,將這個數被全部的數(大於1,小於自己)整除,(取餘數,若是餘數爲0,表示能夠整除,就返回一個true),根據這個函數的返回值,就能夠過濾出全部的質數。

def func(x):
    if x >1:
        if x==2:
            return True
        for i in range(2,x):
            if x % i ==0:
                return True


for i in range(101,201):
    ret = func(i)
    if not ret:
        print(i)
代碼實現

21.websocket是什麼?

  websocket是一套基於TCP鏈接的協議,這個協議規定:客戶端向服務端建立鏈接後不斷開。現象:客戶端向服務端發送請求,服務端也能夠主動向客戶端推送消息。它實現了瀏覽器與服務器全雙工(full-duplex)通訊。其本質是保持TCP鏈接,在瀏覽器和服務端經過Socket進行通訊。

22.websocket創建鏈接時,會先進行握手,認證的過程,

 

注:magic string爲:258EAFA5-E914-47DA-95CA-C5AB0DC85B11

  發起websocket請求時,會先進行一個認證握手的過程,這個過程爲:

  1.用戶發起websocket請求後,會先在請求頭中獲取Sec-WebSocket-Key對應的值,再將這個值與majic_string(魔法字符串<這個字符串是固定的>)相加,將相加的結果先經過hashlib.sha1加密,在經過base64加密,而後在將加密後的結果返回給客戶端。客戶端收到後校驗是否是採用的這張加密,經過後,創建起鏈接,不然就會拒絕鏈接。

  握手成功後才能發送數據,並且收發數據是加密的。

客戶端和服務端收發數據

  客戶端和服務端傳輸數據時,須要對數據進行【封包】和【解包】。

  客戶端的JavaScript類庫已經封裝【封包】和【解包】過程,但Socket服務端須要手動實現。

解包過程:

  服務端接收到客戶端發送的數據後,後先取出第二個字節的後七位,而後,對這後七位進行一個判斷:(後七位轉化爲數字最大爲127),若是後七位<=125,那麼前兩個字節就是報文;若是後七位=126,則繼續日後讀16個字節,也就是取前四個字節做爲報文;若是後七位=127,則日後讀64位,也就是取前10個字節做爲報文。而後剩餘的數據取前四個字節做爲masking_key(掩碼key),對剩下的數據在每一個字節的與masking_key作位運算,最終獲得真實的數據。

websocket的使用場景

  websocket主要用於頁面數據的實時更新。

web實現數據的實時更新的方案:

  1.長輪詢           兼容性好

  2.websocket          性能更優

23.給裝飾器寫log

def logwrap(wrap):
    def log_inner(func):
        print('裝飾器執行以前')
        ret = wrap(func)
        return ret
    return log_inner

@logwrap   #  wrapper = logwrap(wrapper) = log_inner
def wrapper(func):
    def inner(*args,**kwargs):
        print('before')
        ret = func(*args,**kwargs)
        print('after')
        return ret
    return inner

@wrapper    # func = wrapper(func) = log_inner(func)
def func():
    print('哈哈哈')

func()
View Code

24.

v = [lambda:x for x in range(10)]
print( v ) # 含有多個函數名的列表
print( v[0] ) # 第一個函數名
print( v[0]() ) # 9 等同於下面
for i in range(10):
def f():
return i
print(f())


25.mysql表的水平分表和垂直分表

  水平分表用於表數據量很大時,垂直分表用於表中的字段不少

1,水平分割:

 

例:QQ的登陸表。假設QQ的用戶有100億,若是隻有一張表,每一個用戶登陸的時候數據庫都要從這100億中查找,會很慢很慢。若是將這一張表分紅100份,每張表有1億條,就小了不少,好比qq0,qq1,qq1...qq99表。

 

用戶登陸的時候,能夠將用戶的id%100,那麼會獲得0-99的數,查詢表的時候,將表名qq跟取模的數鏈接起來,就構建了表名。好比123456789用戶,取模的89,那麼就到qq89表查詢,查詢的時間將會大大縮短。

 

這就是水平分割。

 

2,垂直分割:

 

垂直分割指的是:表的記錄並很少,可是字段卻很長,表佔用空間很大,檢索表的時候須要執行大量的IO,嚴重下降了性能。這時須要把大的字段拆分到另外一個表,而且該表與原表是一對一的關係。

 

26.(HBase)列存儲

2七、簡述一致性哈希原理和它要解決的問題

  詳情參考:https://blog.csdn.net/lihao21/article/details/54193868

  原理:一致性hash算法經過一個叫做一致性hash環的數據結構實現。這個環的起點是0,終點是2^32 - 1,而且起點與終點鏈接,環的中間的整數按逆時針分佈,故這個環的整數分佈範圍是[0, 2^32-1]。將對象和機器均勻的放置在hash環上,在hash環上順時針查找距離這個對象的hash值最近的機器,便是這個對象所屬的機器。當增長或者減小機器,不會緩存命中的命中率

  一致性hash算法解決了分佈式環境下機器增長或者減小時,簡單的取模運算沒法獲取較高命中率的問題。經過虛擬節點的使用,一致性hash算法能夠均勻分擔機器的負載,使得這一算法更具現實的意義。正因如此,一致性hash算法被普遍應用於分佈式系統中。

2八、C10K問題和解決方案

   C10K問題(即單機1萬個併發鏈接問題)    C10M問題(即單機1千萬個併發鏈接問題)

  解決方案:epoll和協程。

 2九、classmethod和staticmethod的使用場景

應用場景:編寫類時須要採用不少不一樣的方式來建立實例,而咱們只有一個__init__函數,此時靜態方法就派上用場了
複製代碼

class Date:
    def __init__(self,year,month,day):
        self.year=year
        self.month=month
        self.day=day
    @staticmethod
    def now(): #用Date.now()的形式去產生實例,該實例用的是當前時間
        t=time.localtime() #獲取結構化的時間格式
        return Date(t.tm_year,t.tm_mon,t.tm_mday) #新建實例而且返回
    @staticmethod
    def tomorrow():#用Date.tomorrow()的形式去產生實例,該實例用的是明天的時間
        t=time.localtime(time.time()+86400)
        return Date(t.tm_year,t.tm_mon,t.tm_mday)

a=Date('1987',11,27) #本身定義時間
b=Date.now() #採用當前時間
c=Date.tomorrow() #採用明天的時間

print(a.year,a.month,a.day)
print(b.year,b.month,b.day)
print(c.year,c.month,c.day)
staticmethod的應用場景

classmethod的使用場景:工廠模式

30.RabbitMQ的應用場景

  1,異步的處理:好比註冊後,將註冊信息持久化後,須要發送註冊郵件和註冊短信,而後返回註冊成功,而持久化數據後,發送郵件和短信不是必須的,就能夠返回註冊成功,只須要在持久化到數據庫後,將發送郵件和短信放到消息隊列中便可。而後返回註冊成功。

  2,應用的解耦:好比訂單系統和倉庫系統,當訂單量很大時,將訂單系統持久化後,就能夠加入到消息隊列中,倉庫系統能夠根據消息隊列進行操做,而不會出現系統的宕機形成數據的丟失。

  3,流量的削峯:好比秒殺活動,創建一個長度限制的消息隊列,請求進來後,將請求加入到消息隊列中,超過閾值後直接將後續的請求返回

 詳情請參考:https://baijiahao.baidu.com/s?id=1608348586147010884&wfr=spider&for=pc

 RabbitMQ三種Exchange模式(fanout,direct,topic)的性能比較
 

RabbitMQ中,全部生產者提交的消息都由Exchange來接受,而後Exchange按照特定的策略轉發到Queue進行存儲

RabbitMQ提供了四種Exchange:fanout,direct,topic,header

header模式在實際使用中較少,本文只對前三種模式進行比較。

 

性能排序:fanout > direct >> topic。比例大約爲11:10:6

 

一.Direct Exchange

0ec0f465-49c6-361c-ae2b-dd951a6ed1a9

任何發送到Direct Exchange的消息都會被轉發到RouteKey中指定的Queue。

1.通常狀況可使用rabbitMQ自帶的Exchange:」"(該Exchange的名字爲空字符串,下文稱其爲default Exchange)。

2.這種模式下不須要將Exchange進行任何綁定(binding)操做

3.消息傳遞時須要一個「RouteKey」,能夠簡單的理解爲要發送到的隊列名字。

4.若是vhost中不存在RouteKey中指定的隊列名,則該消息會被拋棄。

 

二.Fanout Exchange 

0bbdcd3d-9fc6-3107-b7e0-db67c174d46a

 

任何發送到Fanout Exchange的消息都會被轉發到與該Exchange綁定(Binding)的全部Queue上。

1.能夠理解爲路由表的模式

2.這種模式不須要RouteKey

3.這種模式須要提早將Exchange與Queue進行綁定,一個Exchange能夠綁定多個Queue,一個Queue能夠同多個Exchange進行綁定。

4.若是接受到消息的Exchange沒有與任何Queue綁定,則消息會被拋棄。

 

三.Topic Exchange

11171ab4-af07-3ff6-bdf6-d1febda679c3

 

任何發送到Topic Exchange的消息都會被轉發到全部關心RouteKey中指定話題的Queue上

1.這種模式較爲複雜,簡單來講,就是每一個隊列都有其關心的主題,全部的消息都帶有一個「標題」(RouteKey),Exchange會將消息轉發到全部關注主題能與RouteKey模糊匹配的隊列。

2.這種模式須要RouteKey,也許要提早綁定Exchange與Queue。

3.在進行綁定時,要提供一個該隊列關心的主題,如「#.log.#」表示該隊列關心全部涉及log的消息(一個RouteKey爲」MQ.log.error」的消息會被轉發到該隊列)。

4.「#」表示0個或若干個關鍵字,「*」表示一個關鍵字。如「log.*」能與「log.warn」匹配,沒法與「log.warn.timeout」匹配;可是「log.#」能與上述二者匹配。

5.一樣,若是Exchange沒有發現可以與RouteKey匹配的Queue,則會拋棄此消息。
RabbitMQ三種Exchange模式(fanout,direct,topic)的性能比較

31.HTTP協議怎麼區分長鏈接和短鏈接

  HTTP的長鏈接和短鏈接本質上是TCP長鏈接和短鏈接。

  在HTTP/1.0中默認使用短鏈接。而從HTTP/1.1起,默認使用長鏈接,用以保持鏈接特性。使用長鏈接的HTTP協議,會在響應頭加入這行代碼:Connection:keep-alive

  在使用長鏈接的狀況下,當一個網頁打開完成後,客戶端和服務器之間用於傳輸HTTP數據的TCP鏈接不會關閉,客戶端再次訪問這個服務器時,會繼續使用這一條已經創建的鏈接。Keep-Alive不會永久保持鏈接,它有一個保持時間,能夠在不一樣的服務器軟件(如Apache)中設定這個時間。實現長鏈接須要客戶端和服務端都支持長鏈接。

 3二、redis中持久化的兩種方式,區別,如何開啓

  redis中持久化的功能默認是不開啓的。

  redis的持久化分爲兩種:

    RDB    (point in time snapshot) 基於時間點的快照技術,優勢:持久化速度快,須要的磁盤較少。缺點:只能將數據定格在一個時間  點,不能記錄數據的變化過程。應用場景:經常使用於備份,主從複製就是基於RDB功能的。

    AOF:Append Only Logfile   只追加的日誌文件,保存全部鍵值對修改的變化過程 。優勢:記錄數據的變化過程,更加安全。缺點:持久  化速度相對慢,須要更多的磁盤空間。用處:須要數據安全性和一致性要求更高業務場景,Redis分佈式架構基於AOF來實現高可用。

3三、什麼是響應式佈局?

  經過頁面窗口的大小作出響應不一樣的展現效果,經過@media屬性    @media (max-size:123) {...}   

 3四、MySQL數據庫中開啓鎖的方式:begin;操做語句加for update;釋放鎖:commit;

  django中開啓鎖的方式:from api import models
            from django.db import transaction
            with transaction.atomic():
            res = models.Comment.objects.all().for_update()

 35.爲何要有消息隊列

  爲了應用之間的通訊(rpc),解決供求關係(生產者消費者模型)

36. 程序之間如何實現通訊

  1. 使用restful api(json數據格式)     2.webservice(xml數據格式)     3. rpc(基於消息隊列實現應用程序之間進行通訊)

37.令你印象最深入的官方文檔:rabbitmq  寫得通俗易懂,對於沒有接觸過的人來講,很是容易上手。

 38.tcp是如何保證不丟包的

39, 多進程的部署

40,使用列表推導式實現快排

相關文章
相關標籤/搜索