最近看到的某公司后端開發工程師面試題,拿來研究學習一下,感覺提高技術,看面試題也是一個挺好的方法:(
Redis Incr 命令將 key 中儲存的數字值增一。
如果 key 不存在,那么 key 的值會先被初始化為 0 ,然后再執行 INCR 操作。(incr具有原子性。)
//先獲取相關用戶參數並且驗證 $redis_lock = $Redis::incr($user_id."alipay_lock"); if($redis_lock <= 1){ $redis::expire($redis_lock,10);//設置超時時間 //數據庫操作 //向支付寶發送轉賬請求操作 $Redis::del($redis_lock); }else{ //返回提示信息,表示轉賬正在進行 }
file
改為
redis
會提高速度,由於redis是在內存中讀取的,其讀取速度必然比在文件中讀取速度快,同時解決了session共享的問題。
$fp=fopen('/tmp/lock.txt','w+'); if (flock($fp,LOCK_EX)){
//do something flock($fp,LOCK_UN); }else{ echo 'Couldn't lock the file !'; } fclose($fp);
打開文件后,先對文件加鎖。加鎖后,意味着只有這個進程可以訪問lock.txt文件 。在操作完成后,打開鎖。這個方法操作比較簡易,對於需要同步執行的程序出錯概率低的情況,較為適用;可是它的缺點是沒有超時時間的限制,一旦在do something的時候出現什么問題。這個鎖就解不開了。會占用cpu。其他進程也無法執行該操作了。
2)可以用redis緩存實現鎖。前面答案已經描述。這個適用於隨機響應的情況,如果需要響應每一個請求,且按請求的先后順序進行依次處理。則不太適合,應當構建隊列。
3)使用隊列來響應並發請求(隊列依然依賴redis的list數據結構實現)。來一個排隊一個,依次處理。處理程序可以用php寫一個守護程序。按順序去redis里的list去取請求處理,如果list為空,則等待1秒再去取。(大概邏輯是這樣)。
4.這個網上答案很多。
區別:1)myisam的text支持索引,innodb不支持;
2)innodb支持事務,myisam不支持,對於InnoDB每一條SQL語言都默認封裝成事務,自動提交,這樣會影響速度,所以最好把多條SQL語言放在begin和commit之間,組成一個事務;
3)innodb有行鎖,myisam只是表鎖;
4)myisam的查詢效率高於innodb;
5)InnoDB不保存表的具體行數,執行select count(*) from table時需要全表掃描。而MyISAM用一個變量保存了整個表的行數,執行上述語句時只需要讀出該變量即可,速度很快;
6)InnoDB支持外鍵,而MyISAM不支持。對一個包含外鍵的InnoDB表轉為MYISAM會失敗;
7)InnoDB是聚集索引,數據文件是和索引綁在一起的,必須要有主鍵,通過主鍵索引效率很高。但是輔助索引需要兩次查詢,先查詢到主鍵,然后再通過主鍵查詢到數據。因此,主鍵不應該過大,因為主鍵太大,其他索引也都會很大。而MyISAM是非聚集索引,數據文件是分離的,索引保存的是數據文件的指針。主鍵索引和輔助索引是獨立的。
參考:https://www.zhihu.com/question/20596402
5.分布式拒絕服務(DDoS:Distributed Denial of Service)攻擊指借助於客戶/服務器技術,將多個計算機聯合起來作為攻擊平台,對一個或多個目標發動DDoS攻擊,從而成倍地提高拒絕服務攻擊的威力。(來源百度百科)
如何防范:1)關閉不必要的服務,如只開放80端口響應Http請求;2)獲取可疑攻擊ip,加入黑名單,禁止訪問;3)使用cdn服務,將流量分散到網絡各個節點,減少對服務器的壓力等等。(具體的方法網絡上很多,有各種的總結和攻防的案例)。
6. 簡單來說,http是明文傳輸的協議,客戶端和服務器通訊的所有內容都明文暴露在公共的互聯網上,一旦http包被截獲,信息就會被別人獲取;https則是加密傳輸的協議,客戶端和服務器通訊的關鍵內容都是有密匙加密過的,雖然也是在公共的網絡上傳遞,但是通訊的包被截獲,別人拿到加密后的內容也無法解密獲取到通訊的內容。具體的介紹可以參考前端牛人小卡的一篇介紹,寫的很詳細。雖然https的瀏覽器私人密匙怎么生成我還是不太了解,是不是可以窮舉?
2018/5/9 服務器發給客戶端的證書的數字簽名,需要客戶端用CA的公匙解密。這個CA的公匙是保存在瀏覽器或者操作系統中的。所以使用php的時候依然可以做https請求!
http包泄露的方式: 1)自己的電腦被入侵,接受和發送的http包都會被黑客監聽獲取到;2)電腦所在的局域網關被黑客入侵,http包也會被截獲;3)在公共互聯網上也有很多節點(如代理服務器)可能被截獲。
7. php7的新特性有很多,最實惠的是性能(無論是服務器的cpu占用率,響應請求數量還是請求處理時間)提高了至少一倍。參考http://hansionxu.blog.163.com/blog/static/24169810920158704014772/,和鳥哥的個人網站。有空我需要再把php的底層實現再看看吧。
8. 防止sql注入的方法:1)嚴格限制用戶輸入(長度,類型,特殊字符);2)使用mysql_escape_string轉義特殊字符;3)使用pdo模式操作數據庫,預編譯語句,參數化查詢,分開的發送到數據庫服務端進行解析。
具體的php綁定和分預編譯語句,變量參數化兩次傳遞給msql服務器的細節內容可以參考月影無痕的分析。至於將SQL模板和變量是分兩次發送給MySQL后,mysql的處理細節,我繼續使用google。查詢到文章:預編譯語句(Prepared Statements)介紹,以MySQL為例 。里面介紹了預編譯語句在mysql端是如何實現的,但是還是沒有解決我的核心問題,預編譯語句為什么能防止sql注入? 知乎相關問題中,不二的回答提到了占位符的概念很有意思,sql語句在包含占位符的情況下編譯,理論上來說,以后就不會再改變了。這是否決定了該語句的運行結果被限制在一定的范圍內了,后面用參數代替占位符(會將參數字符串轉義)后的結果也會限定在這個范圍內? 有待於進一步研究吧。
9.MySQL之間數據復制的基礎是二進制日志文件(binary log file)。一台MySQL數據庫一旦啟用二進制日志后,其作為master,它的數據庫中所有操作都會以“事件”的方式記錄在二進制日志中,其他數據庫作為slave通過一個I/O線程與主服務器保持通信,並監控master的二進制日志文件的變化,如果發現master二進制日志文件發生變化,則會把變化復制到自己的中繼日志中,然后slave的一個SQL線程會把相關的“事件”執行到自己的數據庫中,以此實現從數據庫和主數據庫的一致性,也就實現了主從復制。
具體參考:https://www.cnblogs.com/gl-developer/p/6170423.html
這個時候我又腦洞大開,既然已經想到了php的異步調用了。那么會不會有像其他語言里面一樣的回調函數存在呢,比如js里面的call這樣的。於是google了一樣還真有這樣的東西。不過它是同步文件中的,如果異步調用非得要回調,可以把回調的一些參數放在請求參數中,這樣在請求的文件中調用回調的內容就可以了。
關於php的回調函數實現,可以參考:http://www.cnitblog.com/CoffeeCat/archive/2009/04/21/56541.html