Python面試筆記一

目錄

1、MySQL(30題)

2、django(15題) 

3、Python部分(46題)

4、RESTful API設計指南(7題)

5、補充

1、MySQL(30題)

一、mysql如何作分頁

mysql數據庫作分頁用limit關鍵字,它後面跟兩個參數startIndex和pageSizehtml


二、mysql引擎有哪些,各自的特色是什麼?

innodb和myisam兩個引擎,二者區別是
innodb支持事務,myisam不支持
innodb支持外鍵,myisam不支持
innodb不支持全文索引,myisam支持全文索引
innodb提供提交、回滾、崩潰恢復能力的事物的安全能力,實現併發控制
myisam提供較高的插入和查詢記錄的效率,主要用於插入和查詢java


三、數據庫怎麼創建索引

create index account_index on `table name `(`字段名`(length)
python

四、一張表多個字段,怎麼建立組合索引

create index account_index on `table name `(`字段名`,'字段名')
mysql

五、如何應對數據的高併發,大量的數據計算

1.建立索引
2.數據庫讀寫分離,兩個數據庫,一個做爲寫,一個做爲讀
3. 外鍵去掉
4.django中orm表性能相關的
  select_related:一對多使用,查詢主動作連表
  prefetch_related:多對多或者一對多的時候使用,不作連表,作屢次查詢linux

六、數據庫內連表、左連表、右連表

內鏈接是根據某個條件鏈接兩個表共有的數據
左鏈接是根據某個條件以及左邊的錶鏈接數據,右邊的表沒有數據的話則爲null
右鏈接是根據某個條件以及右邊的錶鏈接數據,左邊的表沒有數據的話則爲nullnginx

七、視圖和表的區別

視圖是已經編譯好的sql語句,是基於sql語句的結果集的可視化的表,而表不是
視圖是窗口,表示內容
視圖沒有實際的物理記錄,而表有
視圖的創建和刪除隻影響視圖自己,不影響對應的表web

八、關係型數據庫的特色

數據集中控制
數據獨立性高
數據共享性好
數據冗餘度小
數據結構化
統一的數據保護能力ajax

九、mysql數據庫都有哪些索引

普通索引:普通索引僅有一個功能:加速查找
惟一索引:惟一索引兩個功能:加速查找和惟一約束(可含null)
主鍵索引:外鍵索引兩個功能:加速查找和惟一約束(不可爲null)
聯合索引:聯合索引是將n個列組合成一個索引,應用場景:同時使用n列來進行查詢正則表達式

十、存儲過程

存儲過程不容許執行return語句,可是能夠經過out參數返回多個值,存儲過程通常是做爲一個獨立的部分來執行,存儲過程是一個預編譯的SQL語句。redis

十二、char和vachar區別:

  1. 首先明確的是,char的長度是不可變的,而varchar的長度是可變的,

  2. 定義一個char[10]和varchar[10],若是存進去的是‘abcd’,那麼char所佔的長度依然爲10,除了字符‘abcd’外,後面跟六個空格,而varchar就立馬把長度變爲4了,取數據的時候,char類型的要用trim()去掉多餘的空格,而varchar是不須要的,

  3. char的存取數度仍是要比varchar要快得多,由於其長度固定,方便程序的存儲與查找;可是char也爲此付出的是空間的代價,由於其長度固定,因此不免會有多餘的空格佔位符佔據空間,可謂是以空間換取時間效率,而varchar是以空間效率爲首位的。

  4. char的存儲方式是,對英文字符(ASCII)佔用1個字節,對一個漢字佔用兩個字節;而varchar的存儲方式是,對每一個英文字符佔用2個字節,漢字也佔用2個字節,二者的存儲數據都非unicode的字符數據。

1三、Mechached與redis

mechached:只支持字符串,不能持久化,數據僅存在內存中,宕機或重啓數據將所有失效
不能進行分佈式擴展,文件沒法異步法。
優勢:mechached進程運行以後,會預申請一塊較大的內存空間,本身進行管理。
redis:支持服務器端的數據類型,redis與memcached相比來講,擁有更多的數據結構和併發支持更豐富的數據操做,可持久化。
五大類型數據:string、hash、list、set和有序集合,redis是單進程單線程的。
缺點:數據庫的容量受到物理內存的限制。

1四、sql注入

SQL注入攻擊指的是經過構建特殊的輸入做爲參數傳入Web應用程序,而這些輸入大都是SQL語法裏的一些組合,經過執行SQL語句進而執行攻擊者所要的操做,其主要緣由是程序沒有細緻地過濾用戶輸入的數據,導致非法數據侵入系統。

例如:

select * from users where username='marcofly' and password=md5('test')

SQL注入:select * from users where username=' ' or 1=1 # ' and password=md5('')

「#」在mysql中是註釋符
防止:

  1. 凡涉及到執行sql中有變量時,切記不要用拼接字符串的方法

  2. 永遠不要信任用戶的輸入。對用戶的輸入進行校驗,能夠經過正則表達式,或限制長度;對單引號和

  3. 雙"-"進行轉換等。

  4. 永遠不要使用管理員權限的數據庫鏈接,爲每一個應用使用單獨的權限有限的數據庫鏈接。

  5. 不要把機密信息直接存放,加密或者hash掉密碼和敏感的信息。

  6. 應用的異常信息應該給出儘量少的提示,最好使用自定義的錯誤信息對原始錯誤信息進行包裝

1五、什麼是觸發器

觸發器是一種特殊的存儲過程,主要是經過事件來觸發而被執行的,他能夠強化約束,來維護數據庫的完整性和一致性,能夠跟蹤數據內的操做從而不容許未經許可的 更新和變化,能夠聯級運算。
只有表支持觸發器,視圖不支持觸發器

1六、遊標是什麼?

是對查詢出來的結果集做爲一個單元來有效的處理,遊標能夠定在該單元中的特定行,從結果集的當前行檢索一行或多行,能夠對結果集當前行作修改,
通常不使用遊標,可是須要逐條處理數據的時候,遊標顯得十分重要

1七、 數據庫支持多有標準的SQL數據類型,重要分爲三類

數值類型(tinyint,int,bigint,浮點數,bit)
字符串類型(char和vachar,enum,text,set)
日期類型(date,datetime,timestamp)

1八、mysql慢查詢

慢查詢對於跟蹤有問題的查詢頗有用,能夠分析出當前程序裏哪些sql語句比較耗費資源
慢查詢定義:
指mysql記錄全部執行超過long_query_time參數設定的時間值的sql語句,慢查詢日誌就是記錄這些sql的日誌。
mysql在windows系統中的配置文件通常是my.ini找到mysqld
log-slow-queries = F:\MySQL\log\mysqlslowquery.log 爲慢查詢日誌存放的位置,通常要有可寫權限
long_query_time = 2 2表示查詢超過兩秒才記錄

1九、memcached命中率

命中:能夠直接經過緩存獲取到須要的數據
不命中:沒法直接經過緩存獲取到想要的數據,須要再次查詢數據庫或者執行其餘的操做,緣由多是因爲緩存中根本不存在,或者緩存已通過期
緩存的命中率越高則表示使用緩存的收益越高,應額用的性能越好,抗病發能力越強
運行state命令能夠查看memcached服務的狀態信息,其中cmd—get表示總的get次數,get—hits表示命中次數,命中率=get—hits / cmd—get

20、Oracle和MySQL該如何選擇,爲何?

他們都有各自的優勢和缺點。考慮到時間因素,我傾向於MySQL
選擇MySQL而不選Oracle的緣由
MySQL開源
MySQL輕便快捷
MySQL對命令行和圖形界面的支持都很好
MySQL支持經過Query Browser進行管理

2一、什麼狀況下適合創建索引?

1.爲常常出如今關鍵字order by、group by、distinct後面的字段,創建索引
2.在union等集合操做的結果集字段上,創建索引,其創建索引的目的同上
3.爲常常用做查詢選擇的字段,創建索引
4.在常常用做錶鏈接的屬性上,創建索引

2二、數據庫底層是用什麼結構實現的,你大體畫一下:

底層用B+數實現,結構圖參考:
http://blog.csdn.net/cjfeii/article/details/10858721
http://blog.csdn.net/tonyxf121/article/details/8393545

2三、sql語句應該考慮哪些安全性?

1.防止sql注入,對特殊字符進行轉義,過濾或者使用預編譯的sql語句綁定變量
2.最小權限原則,特別是不要用root帳戶,爲不一樣的類型的動做或者組建使用不一樣的帳戶
3.當sql運行出錯時,不要把數據庫返回的錯誤信息所有顯示給用戶,以防止泄漏服務器和數據庫相關信息

2四、數據庫事物有哪幾種?

隔離性、持續性、一致性、原子性

2五、MySQ數據表在什麼狀況下容易損壞?

服務器忽然斷電致使數據文件損壞
強制關機,沒有先關閉mysq服務器等

2六、drop,delete與truncate的區別

drop直接刪除表
truncate刪除表中數據,再插入時自增加id又從1開始
delete刪除表中數據,能夠加where子句

2七、數據庫範式

1.第一範式:就是無重複的列
2.第二範式:就是非主屬性非部分依賴於主關鍵字
3.第三範式:就是屬性不依賴於其餘非主屬性(消除冗餘)

2八、MySQL鎖類型

根據鎖的類型分:能夠分爲共享鎖、排他鎖、意向共享鎖和意向排他鎖
根據鎖的粒度分:能夠分爲行鎖、表鎖
對於mysql而言,事務機制更可能是靠底層的存儲引擎來實現的,所以,mysql層面只有表鎖,
而支持事物的innodb存儲引發則實現了行鎖(在行相應的索引記錄上的鎖)
說明:對於更新操做(讀不上鎖),只有走索引纔可能上行鎖
MVCC(多版本併發控制)併發控制機制下,任何操做都不會阻塞讀取操做,
讀取操做也不會阻塞任何操做,只由於讀不上鎖
共享鎖:由讀表操做加上的鎖,加鎖後其餘用戶只能獲取該表或行的共享鎖,不能獲取排他鎖,
也就是說只能讀不能寫
排他鎖:由寫表操做加上的鎖,加鎖後其餘用戶不能獲取該表或該行的任何鎖,典型mysql事物中的更新操做
意向共享鎖(IS):事物打算給數據行加行共享鎖,事物在給一個數據行加共享鎖前必須先取得該表的IS鎖
意向排他鎖(IX):事物打算給數據行加行排他鎖,事物在給一個數據行家排他鎖前必須先取得該表的IX鎖

2九、如何解決MYSQL數據庫中文亂碼問題?

1.在數據庫安裝的時候指定字符集
2.若是在按完了之後能夠更改配置文件
3.創建數據庫時候:指定字符集類型
4.建表的時候也指定字符集

30、數據庫應用系統設計

1.規劃
2.需求分析
3.概念模型設計
4.邏輯設計
5.物理設計
6. 程序編制及調試
7.運行及維護

2、django(15題) 

一、中間件

中間件通常作認證或批量請求處理,django中的中間件,實際上是一個類,在請求和結束後,django會根據本身的規則在合適的時機執行中間件中相應的方法,
如請求過來 執行process_request, view,process_response方法

二、Django、Tornado、Flask各自的優點

Django:Django無socket,django的目的是簡便,快速開發,並遵循MVC設計,多個組件能夠很方便的以「插件」形式服務於整個框架,
django有許多功能強大的第三方插件。django具備很強的可擴展性。
Tornado:它是非阻塞式服務器,並且速度至關快,得力於其 非阻塞的方式和對epoll的運用,Future對象,缺點:沒有session,須要自定製
Flask:是一個微型的web框架,配合SQLALchemy來使用,jinja2模板, werkzeug接口

三、 django版本,Python版本,linux版本

django:1.11
Python:3.5
linux:6.8
四、django的template的註釋是什麼樣子的

單行:{#註釋#}
多行註釋:{%comment%}

五、django怎麼弄併發的

nginx+uwsig爲django提供高併發,nginx的併發能力超過,單臺併發能力過完,在純靜態的web服務中更是突出其優越的地方,因爲底層使用epoll異步IO模型進行處理。

六、tornodo的ioloop知道是什麼嗎?

事件循環

七、select_related和prefetch_related,Q和F

select_related:一對多使用,查詢主動作連表
prefetch_related:多對多或者一對多的時候使用,不作連表,作屢次查詢
Q:用於構造複雜查詢條件
F:更新時用於獲取原來的值,專門取對象中某一列進行操做

八、什麼是ORM?

ORM,即Object-Relational Mapping(對象關係映射),它的做用是在關係型數據庫和業務實體對象之間作一個映射
ORM優缺點:
優勢:擺脫複雜的SQL操做,適應快速開發,讓數據結果變得簡單,數據庫遷移成本更低
缺點:性能較差,不適用於大型應用,複雜的SQL操做還須要經過SQL語句實現

九、CORS跨域資源共享

首先會發送"預檢"opption",請求,若是"預檢"成功,則發送真實數據。

十、Django的Form主要具備如下功能?

生成HTMl標籤,驗證用戶數據 is_vaild,HTML Form提交保留上次提交數據,初始化頁面顯示內容

十一、CBV和FBV

CBV在指定的類上面加上裝飾器或在此方法上面添加裝飾器 @method_decorator,並繼承view

十二、cookie及session

cookie:是保留在客戶端上面的一組鍵值對,cookie不是很安全,別人能夠分析存放在本地的cookie
session:是保存在服務器上面的一組鍵值對,依賴與cookie,安全指數比cookie高

1三、django的請求生命週期

請求來了先到uwsgi,把請求作一部分分裝給django框架,而後通過全部的中間件,路由,視圖,視圖處理再返回給中間件,中間件在返回給uwsgi,在返回給用戶。

1四、uwsgi和wsgi

wsgi:是web服務器網關接口,是pyhton應用程序或框架和web服務器之間的一種接口,其普遍使用的是django框架。
uwsgi:是一個web服務器,它實現了wsgi協議,Nginx中HttpUwsgiModule的做用是與Uwsgi服務器進行交換

1五、解釋下django - debug -toolbar的使用

使用django開發站點時,可使用django-debug-toolbar來進行調試,在settings.py中添加 'debug—toolbar.midleware.Debug ToolbarMiddleware'到項目的MIDDLEWARE_CLASSES內。

3、Python部分(46題)

一、 __new__.__init__區別

__new__是一個靜態方法,__init__是一個實例方法
__new__返回一個建立的實例,__init__什麼都不返回
__new__返回一個cls的實例時後面的__init__才能被調用
當建立一個新實例時調用__new__,初始化一個實例時調用__init__

二、深淺拷貝

淺拷貝只是增長了一個指針指向一個存在的地址,而深拷貝是增長一個指針而且開闢了新的內存,這個增長的指針指向這個新的內存,
採用淺拷貝的狀況,釋放內存,會釋放同一內存,深拷貝就不會出現釋放同一內存的錯誤

#調出copy庫
import copy
number=[10,22,56,[33,10,45],99,34]
number2=number.copy()  #普通copy
number[1]=200
number2[1]=500
number[3][0]='22'
number2[3][1]='11'
print(number)
print(number2)
#深度copy,徹底複製嵌套列表中的數值,兩個列表互不影響
number3=copy.deepcopy(number)
number[3][0]='aaa'
number3[3][1]='jjjj'
print(number)
print(number3)

三、HTTP/IP相關協議,分別位於哪層

IP地址是指互聯網協議地址,爲計算機網絡相互鏈接進行通訊而設計的協議,是IP協議提供的一種統一的地址格式,它爲互聯網上的每個網絡和每一臺主機分配一個惟一的網絡地址,以此來屏蔽物理地址的差別,位於網絡層。

HTTP協議即超文本傳送協議(Hypertext Transfer Protocol ),是一個應用層協議,由請求和響應構成,是一個標準的客戶端服務器模型,是Web聯網的基礎,也是手機聯網經常使用的協議之一,HTTP協議是創建在TCP協議之上的一種應用。 
HTTP鏈接最顯著的特色是:客戶端發送的每次請求都須要服務器回送響應,在請求結束後,會主動釋放鏈接。從創建鏈接到關閉鏈接的過程稱爲「一次鏈接」。

 

4.3 HTTP與HTTPS的區別

  • HTTPS加密傳輸協議,HTTP明文傳輸協議;
  • HTTPS須要用SSL證書,HTTP不用;
  • HTTPS比HTTP更加安全搜索引擎更友;
  • HTTPS標準端口443,HTTP標準端口80;
  • HTTPS基於傳輸層,HTTP基於應用層;
  • HTTPS瀏覽器顯示綠色安全鎖HTTP沒顯示。 

五、 一次完整的HTTP請求所經歷的7個步驟

  • 一、創建TCP/IP鏈接 
    在HTTP工做開始以前,客戶端與服務器經過TCP三次握手創建鏈接。
  • 二、客戶端向服務器發送HTTP請求行 
    創建了TCP鏈接,客戶端向服務器發送HTTP請求行,例如:GET/sample/hello.jsp HTTP/1.1 。
  • 三、客戶端發送請求頭和請求體 
    客戶端向服務器發送請求頭信息、請求體內容,最後客戶端會發送一空白行表示客戶端請求完畢。
  • 四、服務器應答響應行 
    服務器會作出應答,表示對客戶端請求的應答, 狀態行:HTTP/1.1 200 OK 。
  • 五、服務器向客戶端發送響應頭信息 
    服務器向客戶端發送頭信息後,它會發送一個空白行來表示頭信息的發送到此爲結束。
  • 六、服務器向客戶端發送響應包體 
    接着,服務器以Content-Type響應頭信息所描述的格式向客戶端發送響應包——所請求的實際數據。
  • 七、 服務器關閉TCP鏈接 
    若是瀏覽器或者服務器在其頭信息加入了這行代碼:Connection:keep-alive ,TCP鏈接在發送後將仍然保持打開狀態,客戶端能夠繼續經過相同的鏈接發送請求。

 

四、地址欄鍵輸入URL,按下回車以後經歷了什麼?
1.瀏覽器向DNS服務器請求解析該URL中的域名所對應的IP地址
2.解析出IP地址後,根據IP地址和默認端口80,和服務器創建TCP鏈接
3.瀏覽器發出讀取文件的http請求,該請求報文做爲TCP三次握手的第三個報文的數據發送給服務器
4.服務器對瀏覽器請求作出響應,並把對應的html文件發送給瀏覽器
5.釋放TCP鏈接
6.瀏覽器將該HMTL渲染並顯示內容

四、TCP/UDP區別

TCP協議是面向鏈接,保證高可靠性(數據無丟失,數據無失序,數據無錯誤,數據無重複達到)
UDP:不可靠的傳輸,數據丟失,無論數據包的順序、錯誤或重發(qq基於udp協議)

五、webscoket

websocket是基於http協議的,可持續化鏈接
輪詢:瀏覽器每隔幾秒就發送一次請求,詢問服務器是否有新消息
長輪詢:客戶端發起鏈接後,若是沒有消息,就一直不返回response給客戶端,直到有消息返回,返回完以後,客戶端再次發起鏈接

六、RabbitMQ:

服務器端有Erlang語言來編寫,支持多種客戶端,只會ajax,用於分佈式系統中存儲轉發消息,在易用性、擴展性、高可用性的方面不俗。
connection是RabbitMQ的socket鏈接,它封裝了socket部分相關協議邏輯
connectionFactroy爲connection的製造工廠
channel是咱們與RabbitMQ打交道的最重要的一個接口,大部分的業務操做是在chaanel這個接口中完成,包括定義Queue、定義Exchange、
綁定Queue與Exchange,發佈消息等

七、裝飾器

調用裝飾器實際上是一個閉包函數,爲其餘函數添加附加功能,不修改被裝飾函數的源代碼和其被調用的方式,裝飾器的返回值也是一個函數對象。
好比:插入日誌、性能測試、事物處理、緩存、權限驗證等,有了裝飾器,就能夠抽離出大量與函數功能自己無關的雷同代碼並繼續重用。

八、閉包

1.必須有一個內嵌函數
2.內嵌函數必須引用外部函數的變量(該函數包含對外做用域而不是全局做用域名字的引用)
3.外部函數的返回值必須是內嵌函數

九、迭代器與生成器

迭代可迭代對象對應_iter_(方法)和迭代器對應_next_(方法)的一個過程

迭代器就是一個封裝了調用函數__next__的循環,讓咱們不用一步一步調用__next__函數
生成器:包括含有yield這個關鍵字,生成器也是迭代器,調動next把函數變成迭代器。

生成器,有兩種表達方式:

  • 生成器表達式:m=(i for i in range(10))    m.__next__()

  • 生成器函數:其實就是由函數改造而來,具備生成能力的函數,標識:函數內部有yield,至關於return,可是能夠執行屢次

十、classmethod,staticmethod,property

類方法:由調用; 至少一個cls參數;執行類方法時,自動將調用該方法的類名賦值給cls
靜態方法:此方法至關於給類擴展一個功能,將類內的函數實例化,給類或對象使用,此時類內的函數就是普通函數,無論是類仍是實例化的對象均可以使用
屬性:實際上是普通方法的變種,具備方法的寫做形式,具備字段訪問形式;定義時,在普通方法的基礎上添加 @property 裝飾器,僅有一個self參數,調用時,無需括號;

十一、經常使用的狀態碼

200--服務器成功返回網頁
204--請求收到,但返回信息爲空
304--客戶端已經執行了GET,但文件未變化
400--錯誤請求,如語法錯誤
403--無權限訪問
404--請求的頁面不存在
500--服務器產生內部錯誤

十二、多進程,多線程,協程,GIL

GIL:全局解釋器鎖,是鎖在cpython解釋器上,致使同一時刻,同一進程只能有一個線程被執行
多進程:多進程模塊multiprocessing來實現,計算密集型用多進程,由於調用CPU,io密集型不佔用CPU;
多線程:多線程模塊threading來實現,IO密集型,多線程能夠提升效率
協程:依賴於geenlet,對於多線程應用。cpu經過切片的方式來切換線程間的執行,遇到IO操做自動切換,線程切換時須要耗時,
而協程的好處是沒有切換的耗時,沒有鎖定概念。
進程:是資源管理單位,進程是相互獨立的,實現高併發
線程:是最小的執行單位,線程的出現爲了下降上下文切換的消耗,提供系統的併發性

1三、IO多路複用/異步非阻塞

IO多路複用:經過一種機制,能夠監聽多個描述符 select/poll/epoll
select:鏈接數受限,查找配對速度慢,數據由內核拷貝到用戶態
poll:改善了鏈接數,可是仍是查找配對速度慢,數據由內核拷貝到用戶態
epoll:epoll是linux下多路複用IO接口,是select/poll的加強版,它能顯著提升程序在大量併發鏈接中只有少許活躍的狀況下的系統CPU利用率
異步非阻塞:異步體如今回調上,回調就是有消息返回時告知一聲兒進程進行處理。非阻塞就是不等待,不須要進程等待下去,繼續執行其餘操做,無論其餘進程的狀態。

1四、PEP8規範,規範的好處是什麼?

1.縮進:4個空實現縮進,儘可能不使用Tab
2.行:每行最大長度不超過79,換行可使用反斜槓
3.命名規範:
4.註釋規範:

1五、range-and-xrange

都在循環時使用,xrange內存性能更好,xrange用法與range徹底相同,range一個生成list對象,xrange是生成器

1六、with上下文機制原理

_enter_和_exit_,上下文管理協議,即with語句,爲了讓一個對象兼容with語句,必須在這個對象類中聲明_enter_和_exit_方法,
使用with語句的目的就是把代碼塊放入with中執行,with結束後,自動完成清理工做,無須收到干預

1七、經典類、新式類

經典類遵循:深度優先,python2中,默認不繼承object類
新式類遵循:廣度優先,Python3中,默認繼承object類

1八、有沒有一個工具能夠幫助查找Python的bug和進行靜態的代碼分析?

PyChecker是一個Python代碼的靜態分析工具,它能夠幫助查找Python代碼的bug,會對代碼的複雜度和格式提出警告,
Pylint是另一個工具能夠進行codingstandard檢查

1九、 Python是如何進行內存管理的

1.對象引用計數:
引用計數增長的狀況:
來保持追蹤內存中的對象,全部對象都用引用計數,一個對象分配一個新名稱
將其放入一個容器中(列表,字典,元祖)
引用計數減小的狀況:
使用del語句對對象別名顯示的銷燬
引用超出做用域或被從新賦值
sys.getrefcount()函數能夠得到對象的當前引用計數
2.標記-清除機制

3.分代技術

20、什麼是python?使用python有什麼好處?

python是一種編程語言,它有對象、模塊、線程、異常處理和自動內存管理。它簡潔,簡單、方便、容易擴展、有許多自帶的數據結果,並且它開源

2一、什麼是pickling和unpickling?

Pickle模塊讀入任何python對象,將它們轉換成字符串,而後使用dump函數將其轉儲到一個文件中——這個過程叫作pickling
反之從存儲的字符串文件中提取原始python對象的過程,叫作unpickling

2二、python是如何被解釋的?

Python是一種解釋性語言,它的源代碼能夠直接運行,Python解釋器會將源代碼轉換成中間語言,以後再翻譯成機器碼再執行

2三、數組和元祖之間的區別是什麼?

數組和元祖之間的區別:數組內容能夠被修改,而元祖內容是隻讀的,不可被修改的,另外元祖能夠被哈希,好比做爲字典的key

2四、參數按值傳遞和引用傳遞是怎麼實現的?

python中的一切都是類,全部的變量都是一個對象的引用。引用的值是由函數肯定的,所以沒法被改變,可是若是一個對象是能夠被修改的,你能夠改動對象

2五、Python都有哪些自帶的數據結構?

Python自帶的數據結構分爲可變和不可變的:可變的有:數組、集合、字典,不可變的是:字符串、元祖、整數

2六、什麼是python的命名空間?

在python中,全部的名字都存在於一個空間中,它們在改空間中存在和被操做——這就是命名空間,它就好像一個盒子,在每一個變量名字都對應裝着一個對象,
當查詢變量的時候,會從該盒子裏面尋找相應的對象

2七、python中的unittest是什麼?

在python中,unittest是python中的單元測試框架,它擁有支持共享搭建、自動測試、在測試中暫停代碼、將不一樣測試迭代成一組

2八、*args與**kwargs

*args表明位置參數,它會接收任意多個參數並把這些參數做爲元祖傳遞給函數。**kwargs表明的關鍵字參數,返回的是字典,位置參數必定要放在關鍵字前面

2九、在Python中什麼是slicing?

slicing是一種在有序的對象類型中(數組、元祖、字符串)節選某一段的語法

30、中的docstring是什麼?

Python中文檔字符串被稱爲docstring,它在Python中的做用是爲函數、模塊和類註釋生成文檔

3一、os與sys區別:

os是模塊負責程序與操做系統的交互,提供了訪問操做系統底層的接口
sys模塊是負責程序與python解釋器的交互,提供了一系列的函數和變量,用於操控Python時運行的環境

3二、實現一個單例模式

_new_()在 _init_()以前被調用,用於生成實例對象。利用這個方法和類的屬性的特色能夠實現設計模式的單例模式。
單例模式是指建立惟一對象,單例模式設計的類只能實例,實例化1個對象
class Singleton(object):
__instance=None
def __init__(self):
pass
def __new__(cls, *args, **kwargs):
if Singleton.__instance is None:
Singleton.__instance=object.__new__(cls,*args,**kwargs)
return Singleton.__instance

3三、算法(冒泡排序,選擇排序,插入排序)
冒泡:首先,列表每兩個相鄰的數,若是前面的比後邊的大,
那麼交換這兩個數,代碼關鍵點:趟和無序區,
時間複雜度爲:O(n2)
import random
def dublue_sort(li):
for i in range(len(li)-1):
exchange= False
for j in range(len(li)-i -1):
if li[j] > li[j+1]:
li[j],li[j+1] = li[j+1],li[j]
exchange = True
if not exchange:
return
return li
li=list(range(100))
random.shuffle(li)
print(li)
print(dublue_sort(li))

選擇:一趟遍歷記錄最小的數,放到第一個位置,再一趟遍歷記錄剩餘列表中最小的數,
繼續放置,代碼關鍵點:無序區和最小數的位置,時間複雜度爲:O(n2)
def select_sort(li):
for i in range(len(li)-1): #i是趟
min_loc=i
#找i位置到最後位置範圍內最小的數
for j in range(i,len(li)):
if li[j] < li[min_loc]:
min_loc = j
#和無序區第一個數做交換
li[min_loc],li[i] = li[i],li[min_loc]
return li
li=list(range(100))
random.shuffle(li)
print(select_sort(li))

插入:列表被分爲有序區和無序區兩個部分。最初有序區只有一個元素,
每次從無序區選擇一個元素,插入到有序區的位置,直到無序區變空,
代碼關鍵點:摸到的牌和手裏的牌,時間複雜度爲:O(n2)
def insert_sort(li):
for i in range(1,len(li)): #i 表明每次摸到的牌的下標
tmp=li[i]
j = i-1 # j表明手裏最後一張牌的下標
while True:
if j < 0 or tmp >= li[j]:
break
li[ j + 1] = li [j]
j -=1
li[j+1] = tmp
li=list(range(100))
print(insert_sort(li))

二分:列表查找:從列表中查找指定元素,輸入:列表、待查找元素,輸出:元素下標或未查找到元素。
二分查找,從有序列表的候選區data[0:n]開始,經過對待查找的值與候選區中間值的比較,
可使候選區減小一半。時間複雜爲:O(logn)
def bin_search(data,val):
low=0
high=len(data)-1
while low <= high :
mid= (low+high) //2
if data[mid] == val:
return mid
elif data[mid] < high :
low = mid + 1
else:
high = mid - 1
return None
print(bin_search([1,2,3,4,5,6,7,8],4))

一、爲何學習Python?

python是目前市面上,我我的認爲是最簡潔&&最優雅&&最有錢途&&最全能的編程語言,沒有之一。

python是全能語言,社區龐大,有太多的庫和框架。你只須要找到合適的工具來實現想法,省去了造輪子的精力。

coder能夠寫儘量少的代碼來實現同等的功能。

若是實現一箇中等業務複雜度的項目,在相同的時間要求內,用java實現要4-5個碼農的話,用python實現也許只須要1個。這就是python最大的優點了。

二、經過什麼途徑學習的Python?

 

三、Python和Java、PHP、C、C#、C++等其餘語言的對比?

coder能夠寫儘量少的代碼來實現同等的功能。

若是實現一箇中等業務複雜度的項目,在相同的時間要求內,用java實現要4-5個碼農的話,用python實現也許只須要1個。這就是python最大的優點了。

四、簡述解釋型和編譯型編程語言?

解釋型語言編寫的程序不須要編譯,在執行的時候,專門有一個解釋器可以將Python語言翻譯成機器語言,每一個語句都是執行的時候才翻譯。這樣解釋型語言每執行一次就要翻譯一次,效率比較低。

用編譯型語言寫的程序執行以前,須要一個專門的編譯過程,經過編譯系統,把源高級程序編譯成爲機器語言文件,翻譯只作了一次,運行時不須要翻譯,因此編譯型語言的程序執行效率高,但也不能一律而論,

部分解釋型語言的解釋器經過在運行時動態優化代碼,甚至可以使解釋型語言的性能超過編譯型語言。

五、Python解釋器種類以及特色?

  Python是一門解釋器語言,代碼想運行,必須經過解釋器執行,Python存在多種解釋器,分別基於不一樣語言開發,每一個解釋器有不一樣的特色,但都能正常運行Python代碼,如下是經常使用的五種Python解釋器:

CPython

Cpython,這個解釋器是用C語言開發的,因此叫 CPython,在命名行下運行python,就是啓動CPython解釋器,CPython是使用最廣的Python解釋器。

IPython

IPython是基於CPython之上的一個交互式解釋器,也就是說,IPython只是在交互方式上有所加強,可是執行Python代碼的功能和CPython是徹底同樣的,比如不少國產瀏覽器雖然外觀不一樣,但內核實際上是調用了IE。

PyPy

PyPy是另外一個Python解釋器,它的目標是執行速度,PyPy採用JIT技術,對Python代碼進行動態編譯,因此能夠顯著提升Python代碼的執行速度。

Jython

Jython是運行在Java平臺上的Python解釋器,能夠直接把Python代碼編譯成Java字節碼執行。

IronPython

IronPython和Jython相似,只不過IronPython是運行在微軟.Net平臺上的Python解釋器,能夠直接把Python代碼編譯成.Net的字節碼。

在Python的解釋器中,使用普遍的是CPython,對於Python的編譯,除了能夠採用以上解釋器進行編譯外,技術高超的開發者還能夠按照本身的需求自行編寫Python解釋器來執行Python代碼,十分的方便!

六、位和字節的關係?

位:咱們常說的bit,位就是傳說中提到的計算機中的最小數據單位:在計算機中的二進制數系統中,位,簡記爲b,也稱爲比特,每一個0或1就是一個位。說白了就是0或者1;

字節:英文單詞:(byte),byte是存儲空間的基本計量單位。1byte 存1個英文字母,utf8編碼中3個byte存一個漢字,gbk編碼中2個字節一個漢字。規定上是1個字節等於8個比特(1Byte = 8bit),可區別256(2的8次方)個數字,取值範圍:0到255。 Byte是從0-255的無符號類型,因此不能表示負數。

數據存儲是以「字節」(Byte)爲單位,數據傳輸是以大可能是以「位」(bit,又名「比特」)爲單位,一個位就表明一個0或1(即二進制),每8個位(bit,簡寫爲b)組成一個字節(Byte,簡寫爲B),是最小一級的信息單位。

七、b、B、KB、MB、GB 的關係?

KB 1KB=1024B

MB 1MB=1024KB

GB 1GB=1024MB

TB 1TB=1024GB

1PB = 1000TB

1EB = 1000PB

八、請至少列舉5個 PEP8 規範(越多越好)。

1. 分號:不要在行尾加分號, 也不要用分號將兩條命令放在同一行。

2. 行長度:

  • 每行不超過80個字符(長的導入模塊語句和註釋裏的URL除外)
  • 不要使用反斜槓鏈接行。Python會將圓括號, 中括號和花括號中的行隱式的鏈接起來 :
  • 若是一個文本字符串在一行放不下, 可使用圓括號來實現隱式行鏈接:
  • 在註釋中,若是必要,將長的URL放在一行上。

3. 括號:寧缺毋濫的使用括號,除非是用於實現行鏈接, 不然不要在返回語句或條件語句中使用括號. 不過在元組兩邊使用括號是能夠的.

4. 縮進:用4個空格來縮進代碼,不要用tab, 也不要tab和空格混用. 對於行鏈接的狀況, 你應該要麼垂直對齊換行的元素(見 :ref:行長度 <line_length> 部分的示例), 或者使用4空格的懸掛式縮進(這時第一行不該該有參數):

5. 空行:頂級定義之間空2行, 方法定義之間空1行,頂級定義之間空兩行, 好比函數或者類定義. 方法定義, 類定義與第一個方法之間, 都應該空一行. 函數或方法中, 某些地方要是你以爲合適, 就空一行.

6. 空格:

  • 按照標準的排版規範來使用標點兩邊的空格,括號內不要有空格,按照標準的排版規範來使用標點兩邊的空格
  • 不要在逗號, 分號, 冒號前面加空格, 但應該在它們後面加(除了在行尾).
  • 參數列表, 索引或切片的左括號前不該加空格.
  • 在二元操做符兩邊都加上一個空格, 好比賦值(=), 比較(==, <, >, !=, <>, <=, >=, in, not in, is, is not), 布爾(and, or, not). 至於算術操做符兩邊的空格該如何使用, 須要你本身好好判斷. 不過兩側務必要保持一致.
  • 當’=’用於指示關鍵字參數或默認參數值時, 不要在其兩側使用空格.
  • 不要用空格來垂直對齊多行間的標記, 由於這會成爲維護的負擔(適用於:, #, =等):

7. 註釋:

  • 文檔字符串: Python有一種獨一無二的的註釋方式: 使用文檔字符串。文檔字符串是包, 模塊, 類或函數裏的第一個語句. 這些字符串能夠經過對象的doc成員被自動提取, 而且被pydoc所用。 對文檔字符串的慣例是使用三重雙引號」「」。
  • 函數和方法: 每節應該以一個標題行開始. 標題行以冒號結尾. 除標題行外, 節的其餘內容應被縮進2個空格. 列出每一個參數的名字, 並在名字後使用一個冒號和一個空格, 分隔對該參數的描述.若是描述太長超過了單行80字符,使用2或者4個空格的懸掛縮進(與文件其餘部分保持一致). 描述應該包括所需的類型和含義. 若是一個函數接受*foo(可變長度參數列表)或者**bar (任意關鍵字參數), 應該詳細列出*foo和**bar. 
  • Returns: (或者 Yields: 用於生成器) 描述返回值的類型和語義. 若是函數返回None, 這一部分能夠省略. 
  • 類: 類應該在其定義下有一個用於描述該類的文檔字符串. 若是你的類有公共屬性(Attributes), 那麼文檔中應該有一個屬性(Attributes)段. 而且應該遵照和函數參數相同的格式.
  • 塊註釋和行註釋: 最須要寫註釋的是代碼中那些技巧性的部分. 若是你在下次 代碼審查 的時候必須解釋一下, 那麼你應該如今就給它寫註釋. 對於複雜的操做, 應該在其操做開始前寫上若干行註釋. 對於不是一目瞭然的代碼, 應在其行尾添加註釋.爲了提升可讀性, 註釋應該至少離開代碼2個空格.

八、字符串:

  • 避免在循環中用+和+=操做符來字符串拼接. 因爲字符串是不可變的, 這樣作會建立沒必要要的臨時對象, 而且致使二次方而不是線性的運行時間. 做爲替代方案, 你能夠將每一個子串加入列表, 而後在循環結束後用 」 .join(列表對象,鏈接符號) 鏈接列表. (也能夠將每一個子串寫入一個 cStringIO.StringIO 緩存中.)
  • 在同一個文件中, 保持使用字符串引號的一致性. 使用單引號’或者雙引號」之一用以引用字符串, 並在同一文件中沿用. 在字符串內可使用另一種引號, 以免在字符串中使用. PyLint已經加入了這一檢查.
  • 爲多行字符串使用三重雙引號」「」而非三重單引號」’. 當且僅當項目中使用單引號’來引用字符串時, 纔可能會使用三重」’爲非文檔字符串的多行字符串來標識引用. 文檔字符串必須使用三重雙引號」「」. 不過要注意, 一般用隱式行鏈接更清晰, 由於多行字符串與程序其餘部分的縮進方式不一致.

九、文件和sockets

  • 在文件和sockets結束時, 須要顯式的關閉它. 

十、導入格式:每一個導入應該獨佔一行

十一、命名:

  • 應該避免的名稱:

    單字符名稱, 除了計數器和迭代器. 
    包/模塊名中的連字符(-) 
    雙下劃線開頭並結尾的名稱(Python保留, 例如init)

  • 命名約定:

所謂」內部(Internal)」表示僅模塊內可用, 或者, 在類內是保護或私有的. 
用單下劃線(_)開頭表示模塊變量或函數是protected的(使用import * from時不會包含). 
用雙下劃線(__)開頭的實例變量或方法表示類內私有. 
將相關的類和頂級函數放在同一個模塊裏. 不像Java, 不必限制一個類一個模塊. 
對類名使用大寫字母開頭的單詞(如CapWords, 即Pascal風格), 可是模塊名應該用小寫加下劃線的方式(如lower_with_under.py). 儘管已經有不少現存的模塊使用相似於CapWords.py這樣的命名, 但如今已經不鼓勵這樣作, 由於若是模塊名碰巧和類名一致, 這會讓人困擾.

 十二、Main:

  • 即便是一個打算被用做腳本的文件, 也應該是可導入的. 而且簡單的導入不該該致使這個腳本的主功能(main functionality)被執行, 這是一種反作用. 主功能應該放在一個main()函數中. 
  • 在Python中, pydoc以及單元測試要求模塊必須是可導入的. 你的代碼應該在執行主程序前老是檢查 if name == ‘main’ , 這樣當模塊被導入時主程序就不會被執行.
  • 全部的頂級代碼在模塊導入時都會被執行. 要當心不要去調用函數, 建立對象, 或者執行那些不該該在使用pydoc時執行的操做.

九、經過代碼實現以下轉換:

二進制轉換成十進制:v = 「0b1111011」

十進制轉換成二進制:v = 18
 
八進制轉換成十進制:v = 「011」
 
十進制轉換成八進制:v = 30
 
十六進制轉換成十進制:v = 「0x12」
 
十進制轉換成十六進制:v = 87

複製代碼
#bin()接受一個十進制,轉換成一個二進制
print(bin(8))#結果爲0b1000,0b爲二進制標識,8的二進制爲1000
#oct()十進制轉八進制
print(oct(9))#結果爲0o11,0o標識八進制
#hex()十進制轉十六進制
print(hex(15))#結果爲0xf,0x標識十六進制
複製代碼

 

十一、python遞歸的最大層數?

複製代碼
import sys
sys.setrecursionlimit(100000)
def func(n):
    print(n)
    n += 1
    func(n)
if __name__ == "__main__":
    func(1)
#默認是996左右,加上sys以後3924-3929之間浮動
複製代碼

1三、ascii、unicode、utf-八、gbk 區別?

ascii

開始計算機只在美國用。八位的字節一共能夠組合出256(2的8次方)種不一樣的狀態。全部的空 格、標點符號、數字、大小寫字母分別用連續的字節狀態表示,一直編到了第127號,這樣計算機就能夠用不一樣字節來存儲英語的文字了;因而你們都把這個方案叫作 ANSI 的」Ascii」編碼(American Standard Code for Information Interchange,美國信息互換標準代碼)。

後來,世界各地的都開始使用計算機,可是不少國家用的不是英文,他們的字母裏有許可能是ASCII裏沒有的,爲了能夠在計算機 保存他們的文字,他們決定採用 127號以後的空位來表示這些新的字母、符號,還加入了不少畫表格時須要用下到的橫線、豎線、交叉等形狀,一直把序號編到了最後一個狀態255。從128 到255這一頁的字符集被稱」擴展字符集「。

unicode

ISO (國際標誰化組織)廢了全部的地區性編碼方案,從新搞一個包括了地球上全部文化、全部字母和符號 的編碼,簡稱 UCS, 俗稱 「unicode「。在unicode中,不管是半角的英文字母,仍是全角的漢字,它們都是統一的」一個字符「!同時,也都是統一的」兩個字節「,一個漢字算兩個英文字符的時代已經快過去了。

utf-8

unicode一樣也不完美,這裏就有兩個的問題,一個是,如何才能區別unicode和ascii?計算機怎麼知道三個字節表示一個符號,而不是 分別表示三個符號呢?第二個問題是,咱們已經知道,英文字母只用一個字節表示就夠了,若是unicode統一規定,每一個符號用三個或四個字節表示,那麼每 個英文字母前都必然有二到三個字節是0,這對於存儲空間來講是極大的浪費,文本文件的大小會所以大出二三倍,這是難以接受的。unicode在很長一段時間內沒法推廣,直到互聯網的出現,爲解決unicode如何在網絡上傳輸的問題,因而面向傳輸的衆多UTF(UCS Transfer Format)標準出現了

UTF-8就是每次8個位傳輸數據,最大的一個特色就是它是一種變長的編碼方式。它可使用1~4個字節表示一個符號,根據不一樣的符號而變化字節長度,當字符在ASCII 碼的範圍時,就用一個字節表示,保留了ASCII字符一個字節的編碼作爲它的一部分,注意的是unicode一箇中文字符佔2個字節,而UTF-8一箇中 文字符佔3個字節)。從unicode到uft-8並非直接的對應,而是要過一些算法和規則來轉換。

GBK

把那些127號以後的奇異符號們直接取消掉, 規定:一個小於127的字符的意義與原來相同,但兩個大於127的字符連在一塊兒時,就表示一個漢字,這樣咱們就能夠組合出大約7000多個簡體漢字了,咱們還把數學符號、羅馬希臘的 字母、日文的假名們都編進去了,連在 ASCII 裏原本就有的數字、標點、字母都通通從新編了兩個字節長的編碼,這就是常說的」全角」字符,而原來在127號如下的那些就叫」半角」字符了。 中國人民看到這樣很不錯,因而就把這種漢字方案叫作「GB2312「。GB2312 是對 ASCII 的中文擴展。可是中國的漢字太多了,咱們很快就就發現有許多人的人名沒有辦法在這裏打出來,繼續把 GB2312 沒有用到的碼位找出來不客氣地用上,只要第一個字節是大於127就固定表示這是一個漢字的開始,無論後面跟的是否是擴展字 符集裏的內容。結果擴展以後的編碼方案被稱爲 GBK 標準,GBK包括了GB2312 的全部內容,同時又增長了近20000個新的漢字(包括繁體字)和符號。

4、RESTful API設計指南(7題)

一、協議

API與用戶的通訊協議,老是使用HTTPs協議
二、域名

應該儘可能將API部署在專用域名之下
https://api.example.com
若是肯定API很簡單,不會有進一步擴展,能夠考慮放在主域名下
https://example.org/api/
三、版本

應該將API的版本號放入URL
https://api.example.com/v1/
另外一種作法是:將版本號放在HTTP頭信息中,
四、路徑
https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees
五、動詞
對於資源的具體操做類型,由HTTP動詞表示
GET(SELECT):從服務器取出資源(一項或多項)。
POST(CREATE):在服務器新建一個資源。
PUT(UPDATE):在服務器更新資源(客戶端提供改變後的完整資源)。
PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性)。
DELETE(DELETE):從服務器刪除資源。
還有兩個不經常使用的HTTP動詞
GET /zoos:列出全部動物園
POST /zoos:新建一個動物園
GET /zoos/ID:獲取某個指定動物園的信息
PUT /zoos/ID:更新某個指定動物園的信息(提供該動物園的所有信息)
PATCH /zoos/ID:更新某個指定動物園的信息(提供該動物園的部分信息)
DELETE /zoos/ID:刪除某個動物園
GET /zoos/ID/animals:列出某個指定動物園的全部動物
DELETE /zoos/ID/animals/ID:刪除某個指定動物園的指定動物

六、過濾信息(Filtering)
若是記錄數量不少,服務器不可能都將它們返回給用戶,API應該提供參數,過濾返回結果
?limit=10:指定返回記錄的數量
?offset=10:指定返回記錄的開始位置。
?page=2&per_page=100:指定第幾頁,以及每頁的記錄數。
?sortby=name&order=asc:指定返回結果按照哪一個屬性排序,以及排序順序。
?animal_type_id=1:指定篩選條件

七、狀態碼(Status Code)
200 OK - [GET]:服務器成功返回用戶請求的數據,該操做是冪等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功。
202 Accepted - [*]:表示一個請求已經進入後臺排隊(異步任務)
204 NO CONTENT - [DELETE]:用戶刪除數據成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操做,該操做是冪等的。
401 Unauthorized - [*]:表示用戶沒有權限(令牌、用戶名、密碼錯誤)。
403 Forbidden - [*] 表示用戶獲得受權(與401錯誤相對),可是訪問是被禁止的。
404 NOT FOUND - [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操做,該操做是冪等的。
406 Not Acceptable - [GET]:用戶請求的格式不可得(好比用戶請求JSON格式,可是隻有XML格式)。
410 Gone -[GET]:用戶請求的資源被永久刪除,且不會再獲得的。
422 Unprocesable entity - [POST/PUT/PATCH] 當建立一個對象時,發生一個驗證錯誤。
500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤,用戶將沒法判斷髮出的請求是否成功。

 5、補充

一、列表

def func(arg,li=[]):
    li.append(arg)
    return li

v1=func(1)
# print(v1) #[1]
v2=func(2,[])
# print(v2) #[2]
v3=func(3)
# print(v3) #[1, 3]

# 代碼從上到下解釋的時候li=[]已經開闢了一塊內存
# v1和v3用的是同一塊內存
# v2從新開闢了一塊內存
print(v1) #[1, 3]
print(v2) #[2]
print(v3) #[1, 3]

n1 = [1,2,3,4,5]
n2 = n1
n3 = n1[:]
n1[0] = 66
n3[1] = 99

#n1,n2指向同一塊內存,一塊兒改變
#切片會從新開闢一塊內存
print(n1) #[66, 2, 3, 4, 5]
print(n2) #[66, 2, 3, 4, 5]
print(n3) #[1, 99, 3, 4, 5]

 二、JavaScript

  • 代碼在編譯階段,做用域就已經肯定
#做用域,一個函數就是一個做用域
var
v=123; function func(){ var v=456; function inner(){ console.log(v); } return inner; } ret = func() console.log(ret()) #輸出結果:456

 三、js中的函數代指類,首字母通常大寫的認爲是類

  • this至關於Python中的self

  • 每一個函數中都有一個this

  • 若是是建立對象obj=new Func(),this指的是obj,若是是執行函數Func(),指的就是window

  • js中無字典,只有對象,定義一個字典類型的數據至關於建立一個對象

#js中沒有類,函數代指,函數名開頭大寫時,通常是類
Name='root';
Age=18;
function Foo(name,age){
    this.Name=name;
    this.Age=age;
    this.Func=function(){
        console.log(this.Name,this.Age);
        (function(){
            console.log(this.Name,this.Age);
        })();
    }
}      
#建立對象
obj=new Foo('charlie',30);#以對象方式調用,this=obj,charlie
obj.Func()#以函數方式調用,this=window.Name,就是root
#輸出結果: charlie 30 root 18

 四、copy列表,修改原表和新表的值,互不影響;列表中嵌套的列表只是一個地址,不管修改原列表中仍是複製列表中的嵌套列表,嵌套的列表中的

值都會被改變。若是想改變嵌套列表中的值時,兩個列表互不影響,就要使用函數deepcopy()

#調出copy庫
import copy
number=[10,22,56,[33,10,45],99,34]
number2=number.copy()  #普通copy
number[1]=200
number2[1]=500
number[3][0]='22'
number2[3][1]='11'
print(number)
print(number2)
#深度copy,徹底複製嵌套列表中的數值,兩個列表互不影響
number3=copy.deepcopy(number)
number[3][0]='aaa'
number3[3][1]='jjjj'
print(number)
print(number3)

五、三元運算,也叫三目運算,就是把簡單的if--else--語句,合併成一句

#若是if後面的條件成立,就返回前面的值,不成立,返回後面的值
name = 'alex' if 1==1 else 'sb'

六、列表+lambda表達式+for循環,函數在執行以前,函數內部代碼不執行,函數中的變量由for循環定義,變量一直被從新賦值,直到循環結束,變量等於最後一個循環的值,列表

內部元素是函數,函數加()表示執行函數,獲得返回值

li = [lambda :x for x in range(10)]
ret1 = li[0]()
ret2 = li[9]()
print(ret1)#9
print(ret2)#9

#每執行一次循環,函數的參數就被從新賦值,因此函數內部的變量是已經被定好的
li = [lambda x=i:x for i in range(10)]
ret1 = li[0]()
ret2 = li[1]()
ret9 = li[9]()
print(ret1)#0
print(ret2)#1
print(ret9)#9

七、單例模式

class Foo:
    #單例模式
    instance = None
    def __init__(self,name):
        self.name = name
    @classmethod
    def get_instance(cls):
        if cls.instance:
            return cls.instance
        else:
            obj = cls('alex')
            cls.instance = obj
            return obj
obj1 = Foo.get_instance()
print(obj1)
obj2 = Foo.get_instance()
print(obj2)
#兩個對象如出一轍
# <__main__.Foo object at 0x000000B059AC92E8>
# <__main__.Foo object at 0x000000B059AC92E8>
class F1:
    #普通模式
    def __init__(self,name):
        self.name = name
f1 = F1('alex')
print(f1)
f2 = F1('alex')
print(f2)
#普通模式,參數同樣時兩個對象也不同
# <__main__.F1 object at 0x0000003E04762400>
# <__main__.F1 object at 0x0000003E04762550>

八、冒泡排序

需求:請按照從小到大對列表 [13, 22, 6, 99, 11] 進行排序
思路:相鄰兩個值進行比較,將較大的值放在右側,依次比較!

li = [13, 22, 6, 99, 11]
for i in range(1,5):
    for m in range(len(li)-i):
        if li[m] > li[m+1]:
            temp = li[m+1]
            li[m+1] = li[m]
            li[m] = temp

print(li)# [6, 11, 13, 22, 99]

九、反射

'''
反射
利用字符串的形式去對象(模塊)中(尋找/檢查/刪除/設置)成員
getattr()尋找、hasattr()檢查、delattr()刪除、setattr()設置
經過字符串導入模塊:
obj = __import__("xxx")
obj = __import__("file.xxx", fromlist=True)
'''
def func():
    inp = input("請輸入你要訪問的URL(模塊名/函數名):")
    #hasattr()檢查對象中是否包含該成員,是返回True
    m, h = inp.split("/")
    #__import__經過字符串導入模塊,obj.func()調用函數
    obj = __import__(m)
    #若是模塊在文件夾中,後面加個參數fromlist,意思是按前面的指定路徑導入
    #obj = __import__("lib." + m, fromlist=True)
    if hasattr(obj,h):
        #getattr()獲取對象中的成員
        func = getattr(obj,h)
        func()
    else:
        print("404")

十、遞歸

# 遞歸實現斐波那契數列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34,
def func(arg1,arg2):
    if arg1 == 0:
        print(arg1)
        print(arg2)
    arg3 = arg1 + arg2
    print(arg3)
    if arg3>5000:
        return
    return func(arg2, arg3)
func(0,1)

 十一、階乘

n = 1
for i in range(1,5):
    n *= i
print(n) # 24

十二、階加

n = sum(range(101))
print(n)#5050
相關文章
相關標籤/搜索