
場景:
讓我們來玩個游戲, 假設我們是懶得"無可救葯"的壞學生, 就是死活不做題, 一根筋的要走"抄襲"路線.
How to do it?
讓我們來簡單枚舉下各自的方式:
1). copy/paste
老師: 呵呵, 也只能呵呵了
2). 名稱替換 (變量名/函數名)
老師: 能有點創意不?
3). 代碼位置置換
老師: 丟人.....
4). 添加注釋, 調整代碼書寫形式
老師 (推推鼻梁上的眼鏡): 有點意思 .....
5). 簡單重構 ( 函數合並和拆分 )
老師 : 有進步, 看來還有救.......
就此打住, 總之抄襲方法, 沒有最好, 只有更好, 眾人拾材火焰高, oh yeah.
需求分析:
基於上述的場景, 我們把代碼抄襲過程視為一次transform, 轉換前后的代碼應該是相似的.
那么代碼抄襲檢測系統的基本功能, 列舉如下所示:
1). 相似代碼檢測的准確率高
定義相似度算法, 能准確反映出代碼之間的相似程度, 通過上述的抄襲方式轉換的代碼, 彼此之間的相似度高
2). 相似代碼對比的友好展示效果
相似代碼在兩兩對比時, 能通過染色+高亮的方式來強調突出可疑的相似區域, 而不需人肉對比了.
3). 快速增量
代碼檢測需快速響應, 在大數據量代碼倉庫下的情況, 依舊能快速檢索.
難點解析:
1). 相似度如何描述和定義
不可否認, 自然語言和機器所能理解的語言, 存在着天然的鴻溝. 那如何從機器的角度去理解語言? 相似文本的檢測算法, 是否可以套用到代碼檢測上? 好像不行, 簡單的詞袋模型, 並不能表述代碼的特征(后續的文章詳細闡述). 那代碼的特征是什么, 它在那里?
2). 相似代碼對比的友好性
這個似乎簡單一點, 但它絕不是vimdiff那么簡單
3). 在大數據量的前提下, 如何支持快速檢索
顯然相似檢索時, 是不會遍歷所有的代碼做相似計算, 然后求出top n的.
例如, 我們假設相似算法計算耗時10ms, 當代碼集數量為10, 遍歷一邊耗時為100毫秒, 當如果代碼集數量達到1萬時, 需要耗時為100秒, 這顯然無法接受.
當然我們可以大致猜測的實現思路, 分如下兩步驟
(1). 快速檢索出小數據集的候選集
(2). 然后精確的計算該候選集的相似度, 並做top n排序
如何去支撐該實現, 又該選用存儲方案, 這是我們需要所面臨的問題.
而這一切, 所有的關鍵就是特征, 究竟代碼的特征是誰? 從哪里來? 將要去哪里?
先賣個關子,請期待后續的文章.

后續:
不太清楚, 自己能寫幾篇, 下一篇文章會重點介紹代碼相似度的定義和計算, 敬請關注.