mysql數據庫作分頁用limit關鍵字,它後面跟兩個參數startIndex和pageSizehtml
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
普通索引:普通索引僅有一個功能:加速查找
惟一索引:惟一索引兩個功能:加速查找和惟一約束(可含null)
主鍵索引:外鍵索引兩個功能:加速查找和惟一約束(不可爲null)
聯合索引:聯合索引是將n個列組合成一個索引,應用場景:同時使用n列來進行查詢正則表達式
存儲過程不容許執行return語句,可是能夠經過out參數返回多個值,存儲過程通常是做爲一個獨立的部分來執行,存儲過程是一個預編譯的SQL語句。redis
首先明確的是,char的長度是不可變的,而varchar的長度是可變的,
定義一個char[10]和varchar[10],若是存進去的是‘abcd’,那麼char所佔的長度依然爲10,除了字符‘abcd’外,後面跟六個空格,而varchar就立馬把長度變爲4了,取數據的時候,char類型的要用trim()去掉多餘的空格,而varchar是不須要的,
char的存取數度仍是要比varchar要快得多,由於其長度固定,方便程序的存儲與查找;可是char也爲此付出的是空間的代價,由於其長度固定,因此不免會有多餘的空格佔位符佔據空間,可謂是以空間換取時間效率,而varchar是以空間效率爲首位的。
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中是註釋符
防止:
凡涉及到執行sql中有變量時,切記不要用拼接字符串的方法
永遠不要信任用戶的輸入。對用戶的輸入進行校驗,能夠經過正則表達式,或限制長度;對單引號和
雙"-"進行轉換等。
永遠不要使用管理員權限的數據庫鏈接,爲每一個應用使用單獨的權限有限的數據庫鏈接。
不要把機密信息直接存放,加密或者hash掉密碼和敏感的信息。
應用的異常信息應該給出儘量少的提示,最好使用自定義的錯誤信息對原始錯誤信息進行包裝
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.運行及維護
一、中間件
中間件通常作認證或批量請求處理,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內。
一、 __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鏈接最顯著的特色是:客戶端發送的每次請求都須要服務器回送響應,在請求結束後,會主動釋放鏈接。從創建鏈接到關閉鏈接的過程稱爲「一次鏈接」。
四、地址欄鍵輸入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是全能語言,社區龐大,有太多的庫和框架。你只須要找到合適的工具來實現想法,省去了造輪子的精力。
coder能夠寫儘量少的代碼來實現同等的功能。
若是實現一箇中等業務複雜度的項目,在相同的時間要求內,用java實現要4-5個碼農的話,用python實現也許只須要1個。這就是python最大的優點了。
coder能夠寫儘量少的代碼來實現同等的功能。
若是實現一箇中等業務複雜度的項目,在相同的時間要求內,用java實現要4-5個碼農的話,用python實現也許只須要1個。這就是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),是最小一級的信息單位。
KB 1KB=1024B
MB 1MB=1024KB
GB 1GB=1024MB
TB 1TB=1024GB
1PB = 1000TB
1EB = 1000PB
1. 分號:不要在行尾加分號, 也不要用分號將兩條命令放在同一行。
2. 行長度:
3. 括號:寧缺毋濫的使用括號,除非是用於實現行鏈接, 不然不要在返回語句或條件語句中使用括號. 不過在元組兩邊使用括號是能夠的.
4. 縮進:用4個空格來縮進代碼,不要用tab, 也不要tab和空格混用. 對於行鏈接的狀況, 你應該要麼垂直對齊換行的元素(見 :ref:行長度 <line_length>
部分的示例), 或者使用4空格的懸掛式縮進(這時第一行不該該有參數):
5. 空行:頂級定義之間空2行, 方法定義之間空1行,頂級定義之間空兩行, 好比函數或者類定義. 方法定義, 類定義與第一個方法之間, 都應該空一行. 函數或方法中, 某些地方要是你以爲合適, 就空一行.
6. 空格:
7. 註釋:
八、字符串:
九、文件和sockets
十、導入格式:每一個導入應該獨佔一行
十一、命名:
應該避免的名稱:
單字符名稱, 除了計數器和迭代器.
包/模塊名中的連字符(-)
雙下劃線開頭並結尾的名稱(Python保留, 例如init)
命名約定:
所謂」內部(Internal)」表示僅模塊內可用, 或者, 在類內是保護或私有的.
用單下劃線(_)開頭表示模塊變量或函數是protected的(使用import * from時不會包含).
用雙下劃線(__)開頭的實例變量或方法表示類內私有.
將相關的類和頂級函數放在同一個模塊裏. 不像Java, 不必限制一個類一個模塊.
對類名使用大寫字母開頭的單詞(如CapWords, 即Pascal風格), 可是模塊名應該用小寫加下劃線的方式(如lower_with_under.py). 儘管已經有不少現存的模塊使用相似於CapWords.py這樣的命名, 但如今已經不鼓勵這樣作, 由於若是模塊名碰巧和類名一致, 這會讓人困擾.
十二、Main:
二進制轉換成十進制: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標識十六進制
import sys sys.setrecursionlimit(100000) def func(n): print(n) n += 1 func(n) if __name__ == "__main__": func(1) #默認是996左右,加上sys以後3924-3929之間浮動
ascii
開始計算機只在美國用。八位的字節一共能夠組合出256(2的8次方)種不一樣的狀態。全部的空 格、標點符號、數字、大小寫字母分別用連續的字節狀態表示,一直編到了第127號,這樣計算機就能夠用不一樣字節來存儲英語的文字了;因而你們都把這個方案叫作 ANSI 的」Ascii」編碼(American Standard Code for Information Interchange,美國信息互換標準代碼)。
後來,世界各地的都開始使用計算機,可是不少國家用的不是英文,他們的字母裏有許可能是ASCII裏沒有的,爲了能夠在計算機 保存他們的文字,他們決定採用 127號以後的空位來表示這些新的字母、符號,還加入了不少畫表格時須要用下到的橫線、豎線、交叉等形狀,一直把序號編到了最後一個狀態255。從128 到255這一頁的字符集被稱」擴展字符集「。
unicode
ISO (國際標誰化組織)廢了全部的地區性編碼方案,從新搞一個包括了地球上全部文化、全部字母和符號 的編碼,簡稱 UCS, 俗稱 「unicode「。在unicode中,不管是半角的英文字母,仍是全角的漢字,它們都是統一的」一個字符「!同時,也都是統一的」兩個字節「,一個漢字算兩個英文字符的時代已經快過去了。
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個新的漢字(包括繁體字)和符號。
一、協議
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 - [*]:服務器發生錯誤,用戶將沒法判斷髮出的請求是否成功。
一、列表
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