Linux許可權管理之基本許可權
此作業要求參見:https://edu.cnblogs.com/campus/nenu/2020Fall/homework/11207/
老楊因為留作業太多被學生投訴下崗了,去面試,剛好你是公司的面試官。出了道題,題目要求如下(別忙著答題,現在是背景,作業的要求還在後面)。
1)程式名brute,按照下面的要求讀入兩個檔案。
檔案whitelist,包含1列整數10個,隨機生成(要求老楊自己想辦法),通過命令列引數指出檔名。
檔案q,包含1列整數1000個,隨機生成(也要求老楊自己想辦法),通過控制檯讀入。
2)在檔案q中查詢所有不在whitelist中的整數,定向輸出到一個檔案中。
(讀到此處,你見老楊面露困惑,出於多年,不,一年,不,半年的師生情誼,你補充道,“楊老師,您就當這是從交易記錄q中查詢不符合白名單whitelist的非法交易。”老楊感激地點點頭。)
3)寫一份如何部署執行程式碼的readme。
老楊寫成如下程式碼:
//brute.cpp
#include <fstream> #include <iostream> #include <cstring> using namespace std; const int w_1m=1000000; int w[w_1m]; bool is_match(int t, int w[], int w_length) { for(int i=0;i<w_length;i++) { if(t!=w[i]) { return true; } } return false; } // brute -w whitelist < T int main(int argc, char *argv[]) { if(argc != 3 || strcmp(argv[1], "-w")) { return 1; } // init w //// for(int i=0;i<w_1m) //// { //// w[i]=-1; //填充非法資料 //// } ifstream infile; infile.open(argv[2]); int i=0; cout << argv[2]<< endl; while(infile>>w[i++]) { } int w_length = i-1; cout << w_length << endl; // check t int t=0; while(cin >> t) { if(is_match(t, w, w_length)) { cout << t << endl; } } }
由於資料老楊也得自己想辦法,所以老楊又寫了兩段程式碼生成資料,程式碼如下:
//create.cpp
#include <iostream> #include <stdlib.h> #include <time.h> using namespace std; int main(int argc, char* argv[]) { srand((unsigned)time(NULL)); for(int i=0; i<10;i++) { cout << rand() << "\n"; } cout << endl; return 0; }
readme文件如下:
readme.md |
|
老楊有多年的指導學生的經驗,所以會使用多種語言程式設計。既然是面試,就想著多多展示自己,所以老楊又用C#解了這道題,程式碼如下:
//foo.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace foo { class Program { static void Main(string[] args) { DateTime beforDT = System.DateTime.Now; if(args.Count() < 1) return; string path = args[0]; string[] sm = File.ReadAllLines(path); int[] p = new int[sm.Length]; //Console.WriteLine(sm.Length); int[] array = new int[1000000]; for (int i = 0; i < 1000000; i++) { array[i] = Convert.ToInt32(Console.ReadLine()); } for(int i = 1;i < sm.Length; ++i) { int temp = Convert.ToInt32(sm[i]); if(find(temp, array) == -1) Console.WriteLine(temp); } DateTime afterDT = System.DateTime.Now; TimeSpan ts = afterDT.Subtract(beforDT); Console.WriteLine("DateTime: {0}ms.", ts.TotalMilliseconds); } static int find(int key, int[] array) { for(int j = 0; j < 10; j++) { if(key == array[j]) return key; } return -1; } } }
readme文件如下:
readme.md |
|
你讀了一遍老楊的readme.md檔案,看了看老楊生成資料的程式碼,建議到:“為什麼不用命令列引數決定生成的資料量的大小呢?”你說完這句話之後老楊有點兒疑惑,你趕緊補充說:“你把for迴圈中的10替換成1000有點兒麻煩啊,何不把它定義成一個變數呢?在控制檯進行輸入。”老楊恍然大悟,馬上修改了create.cpp和readme.md。
作業0(5分)
修改create.cpp檔案,改成由命令列引數確定生成的資料的資料量。修改readme.md的對應部分。(要求貼出修改之後的程式碼和read.md。)
你看了一下程式碼,又說道:“老楊,你這結果倒是能對……但是”。你覺得程式碼的執行效率會比較低。但是你想引導他獨立完成修改,你說:“我認為你應該profile一下你的程式碼,找到程式碼最慢的地方。”
profile?還好老楊看過《構建之法》,那本書中提到過效能分析。不過老楊不明白為啥要進行效能分析,但畢竟是在面試也不好把太多疑義說出來。所以只好照做。
答:
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <string.h>
using namespace std;
int main(int argc, char* argv[])
{
srand((unsigned)time(NULL));
for (int i = 0; i < atoi(argv[1]); i++)
{
cout << rand() << "\n";
}
cout << endl;
return 0;
}
|
||
|
作業1(10分)
對上面兩段老楊寫的程式碼任選其一進行profile,觀察現象(要求有截圖記錄)。
答:
如圖 有三個佔9次,main佔5次
你是一個好人,為了讓老楊知道為什麼要對程式碼進行profile,於是你在原來的題目的基礎上做出了修改,修改之後的題要求如下:
1)讀入兩個檔案,一個用控制檯,一個用命令列引數指出檔名。
檔案biggerwhitelist,包含1列整數1M個,隨機生成(要求老楊自己想辦法),通過命令列引數指出檔名。
檔案biggerq,包含1列整數10M個,隨機生成(也要求老楊自己想辦法),通過控制檯讀入。
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <fstream>
#include <string.h>
using namespace std;
int main(int argc, char* argv[])
{
int shu;
cin >> shu;
ofstream outfile;
srand((unsigned)time(NULL));
for (int i = 0; i < atoi(argv[1]); i++)
{
cout << rand() << "\n";
}
cout << endl;
outfile.open("biggerq");
for (int i = 0; i < shu; i++)
{
outfile << rand() << endl;
}
outfile.close();
return 0;
}
2)在檔案biggerq中查詢所有不在biggerwhitelist中的整數,重定向輸出到一個檔案中。
3)寫一份如何部署執行程式碼的readme。
readme.md |
|
老楊看了一下,發現只是資料量變大了,程式碼不用變。於是換了資料又運行了一遍自己的程式碼,發現跑了很久(大概10分鐘)還沒結果。由於是在面試,老楊急壞了。這個時候作為面試官的你知道目的已經達成了,於是告訴老楊:“你看,知道為啥讓你profile了吧,你還是再profile一次吧。
作業2(10分)
以biggerwhitelist和biggerq作為輸入,對作業1中選擇的程式碼再次進行profile,找到程式碼執行最“慢”的地方,截圖為證並文字說明。
答:
由圖可以看出此程式跑了3分49秒,主要圖中有5個佔213677次,跑的最慢的就是這5個函式。
老楊再次profile之後發現了程式碼最慢的地方在哪兒。這時候你說:“既然找到了最慢的地方,那就開始對你的程式碼進行優化吧。”對於這次引導的結果,你很得意。
作業3(10分)
根據作業2找到的最慢的地方,優化作業1中你選擇的程式碼,在保證輸出結果正確的前提下,減少老楊程式執行的時間。(優化後的程式碼需要你提交到git上,作為教師的判斷依據。優化後的程式的名字應該是better.cpp或者better.cs。)
GitHub:https://github.com/zhaoyw456/baimingdan.git
老楊在優化了程式碼之後,發現果然程式碼執行“快”了很多,很是得意。這時候你想“好人”做到底,順水推舟一把。你說:“對優化後的程式碼再profile一下吧。”老楊與你意見一致。
答:
如圖所示程式碼只跑了1分13秒,主要的5個從213677次都降到了66984,明顯程式碼快了很多。
作業4(5分)
對作業3優化後的程式碼進行profile,結果與作業2的結果做對比。畫表格並文字說明。
答:
優化前 | 優化後 | |
主要的最多的5個函式 | 213677 | 66984 |
is_match() | 657 | 10176 |
我用的是折半二分查詢方式(遞迴方法),因此is_match會增加,但下降跟上升之比是1:15
最後,老楊發現了他原本程式碼的不足,並且對於你的引導表達了謝意。
但是,你還是猶豫要不要錄用老楊。因為你覺得老楊的文件(readme),註釋和程式碼風格有很大的問題,並且給老楊指了出來。
答:註釋不用連續注兩次
做業5(5分)
你覺得老楊的文件(readme),註釋和程式碼風格又哪些問題,該如何改進?
答: 多行註釋可以嘗試/**/的方式
面試結束了,你和老楊握手,對他說出了面試的結果。你說的內容,不是今天的作業題,也許是若干年以後你想對當年教你的教師說的,也許是你希望未來的面試官對你說的。你想說的是什麼呢?
答:明天上班,出去把門帶上。