武漢淘寶,面試感受

本文轉載自:http://java-mzd.iteye.com/blog/1004784

題記:趕回長沙,已經是夜裏12點了,這次雖然沒有收到面試通知,但是抱着拼一拼的態度,還是趕去了武漢,很慶幸,經過自己的努力爭取,HR姐姐給了我們一個機會,只可惜,自己表現的太不給力,沒把握住。

 

面我的是“玄難”,雖然掛了我,還是很感激玄難老師吧。整個面試過程,感覺還是很輕鬆、愉悅,老師給我的感覺是很淡定、從容,一種很睿智的感覺(呵呵,果然是大師)。面試中聊了些與技術無關的東西,有關價值觀、未來等,能感覺到老師真的在用心在跟我交流這些東西,也是很真誠的給了我一些來自他的經驗和建議,在此對老師還是很感激的。只是很可惜,由於自己在技術面試上拙劣的表現,沒有達到老師的要求吧。

 

下面給出此次老師問我的題目,以及自己的回答,以及自己的回顧點評。歡迎大家在回覆中指出我的錯誤,也歡迎各種更優秀的答案。面的題目其實也比較簡單,只是由於自己的拙劣表現而失去了機會,所以也比較遺憾吧 。

 試題:

 

1.一個類A,其中有方法int f(int a,int b),怎麼通過反射調用此方法?

 

1.通過class.forName(“A”).newInstance;加載類,並初始化一個該類對象

2.通過對象的getMethod(“f”)方法得到該Method 方法對象

3.調用method對象的 invoke()方法

 其實,最可惜的就是此題。

    唉。那麼熟悉、信心滿滿的Reflection知識,還記得當初爲了搞明白Reflection實現的原理,跑去看過《深入JVM》。打印了好幾十頁的PDF,上面記滿了筆記。後面又用Reflection寫過了這麼多東西。

    結果面試的時候,居然SB的連通過反射調用對象的方法時,需要先得到該方法對象都給忘了,還是在老師的提醒下想起。

   在老師的提醒下,想起了要得到方法對象,卻又忘記了重載的可能。因爲方法可能會重載,所以同一個方法名,可能有不同的參數、返回值,都是不同的方法對象。唉,真的只能說自己表現的太拙劣了吧。這麼低級的問題居然都想不起來。

2.Web開發中,filter的作用?

1.     初級的內容,可以用來在外部和服務器間,進行字符串的過濾

2.     filter主要應該是用於安全機制,可以通過Http Request中的信息,對用戶進行各種限制,比如可以過濾只能某個地區(IP)的用戶可以接入,或者只有登錄(具有某種權限)的用戶才能訪問(某些模塊)

自己當時第一反應想到的就是這兩個,貌似老師覺得兩個少了,不太滿意?

3.給一個圖,給出最優深度查找?

唉,因爲確實自己沒看過圖的內容,就直接坦誠的告訴老師這個我不會了。

估計答到這一步的時候,我就已經基本沒戲了?

 

4.給一個稀疏矩陣,你怎麼存?

思考大約1分鐘後,我給出的答案是,用鏈表。

鏈表的每個節點的有4個數據項,分別爲:行號,列號,數據,下一個節點的指向。

 

 

    這個問題其實我應該表現的很不好吧,一開始居然沒聽明白“稀疏矩陣”,老師提點了“線性代數”了,我還是讓老師花了個例圖。應該給老師留下了“不好好上學”的印象吧。而且答完後老師似乎還是不滿意。

P.S.  賓哥說,用“鄰接鏈表”,明天查查看。

 

5.給一個四則運算的字符串,計算出結果

 我當時的考慮:因爲是字符串,而且需要解析出來,並且字符串之間有一定的規則:用數字和+-*/連接起來。於是,我想到了用正則表達式解析,然後再進行運算

而老師問這個問題的目的應該是考我數據結構,他想聽到的答案是用棧實現

 

 import Java.util.Stack;

  1. /** 
  2.  * 利用棧,進行四則運算的類 
  3.  * 用兩個棧來實現算符優先,一個棧用來保存需要計算的數據numStack,一個用來保存計算優先符priStack 
  4.  *  
  5.  * 基本<a href="http://lib.csdn.net/base/datastructure" class='replace_word' title="算法與數據結構知識庫" target='_blank' style='color:#df3434; font-weight:bold;'>算法</a>實現思路爲:用當前取得的運算符與priStack棧頂運算符比較優先級:若高於,則因爲會先運算,放入棧頂; 
  6.  * 若等於,因爲出現在後面,所以會後計算,所以棧頂元素出棧,取出操作數運算; 
  7.  *  若小於,則同理,取出棧頂元素運算,將結果入操作數棧。各個優先級'(' > '*' = '/' > '+' = '-' > ')' 
  8.  * @author java_mzd 
  9.  *  
  10.  */  
  11. public class Operate {  
  12.     private Stack<Character> priStack = new Stack<Character>();// 操作符棧  
  13.     private Stack<Integer> numStack = new Stack<Integer>();;// 操作數棧  
  14.   
  15.     /** 
  16.      * 傳入需要解析的字符串,返回計算結果(此處因爲時間問題,省略合法性驗證) 
  17.      * @param str 需要進行技術的表達式 
  18.      * @return 計算結果 
  19.      */  
  20.     public int caculate(String str) {  
  21.         // 1.判斷string當中有沒有非法字符  
  22.         String temp;// 用來臨時存放讀取的字符  
  23.         // 2.循環開始解析字符串,當字符串解析完,且符號棧爲空時,則計算完成  
  24.         StringBuffer tempNum = new StringBuffer();// 用來臨時存放數字字符串(當爲多位數時)  
  25.         StringBuffer string = new StringBuffer().append(str);// 用來保存,提高效率  
  26.   
  27.         while (string.length() != 0) {  
  28.             temp = string.substring(0, 1);  
  29.             string.delete(0, 1);  
  30.             // 判斷temp,當temp爲操作符時  
  31.             if (!isNum(temp)) {  
  32.                 // 1.此時的tempNum內即爲需要操作的數,取出數,壓棧,並且清空tempNum  
  33.                 if (!"".equals(tempNum.toString())) {  
  34.                     // 當表達式的第一個符號爲括號  
  35.                     int num = Integer.parseInt(tempNum.toString());  
  36.                     numStack.push(num);  
  37.                     tempNum.delete(0, tempNum.length());  
  38.                 }  
  39.                 // 用當前取得的運算符與棧頂運算符比較優先級:若高於,則因爲會先運算,放入棧頂;若等於,因爲出現在後面,所以會後計算,所以棧頂元素出棧,取出操作數運算;  
  40.                 // 若小於,則同理,取出棧頂元素運算,將結果入操作數棧。  
  41.   
  42.                 // 判斷當前運算符與棧頂元素優先級,取出元素,進行計算(因爲優先級可能小於棧頂元素,還小於第二個元素等等,需要用循環判斷)  
  43.                 while (!compare(temp.charAt(0)) && (!priStack.empty())) {  
  44.                     int a = (int) numStack.pop();// 第二個運算數  
  45.                     int b = (int) numStack.pop();// 第一個運算數  
  46.                     char ope = priStack.pop();  
  47.                     int result = 0;// 運算結果  
  48.                     switch (ope) {  
  49.                     // 如果是加號或者減號,則  
  50.                     case '+':  
  51.                         result = b + a;  
  52.                         // 將操作結果放入操作數棧  
  53.                         numStack.push(result);  
  54.                         break;  
  55.                     case '-':  
  56.                         result = b - a;  
  57.                         // 將操作結果放入操作數棧  
  58.                         numStack.push(result);  
  59.                         break;  
  60.                     case '*':  
  61.                         result = b * a;  
  62.                         // 將操作結果放入操作數棧  
  63.                         numStack.push(result);  
  64.                         break;  
  65.                     case '/':  
  66.                         result = b / a;// 將操作結果放入操作數棧  
  67.                         numStack.push(result);  
  68.                         break;  
  69.                     }  
  70.   
  71.                 }  
  72.                 // 判斷當前運算符與棧頂元素優先級, 如果高,或者低於平,計算完後,將當前操作符號,放入操作符棧  
  73.                 if (temp.charAt(0) != '#') {  
  74.                     priStack.push(new Character(temp.charAt(0)));  
  75.                     if (temp.charAt(0) == ')') {// 當棧頂爲'(',而當前元素爲')'時,則是括號內以算完,去掉括號  
  76.                         priStack.pop();  
  77.                         priStack.pop();  
  78.                     }  
  79.                 }  
  80.             } else  
  81.                 // 當爲非操作符時(數字)  
  82.                 tempNum = tempNum.append(temp);// 將讀到的這一位數接到以讀出的數後(當不是個位數的時候)  
  83.         }  
  84.         return numStack.pop();  
  85.     }  
  86.   
  87.     /** 
  88.      * 判斷傳入的字符是不是0-9的數字 
  89.      *  
  90.      * @param str 
  91.      *            傳入的字符串 
  92.      * @return 
  93.      */  
  94.     private boolean isNum(String temp) {  
  95.         return temp.matches("//d");  
  96.     }  
  97.   
  98.     /** 
  99.      * 比較當前操作符與棧頂元素操作符優先級,如果比棧頂元素優先級高,則返回true,否則返回false 
  100.      *  
  101.      * @param str 需要進行比較的字符 
  102.      * @return 比較結果 true代表比棧頂元素優先級高,false代表比棧頂元素優先級低 
  103.      */  
  104.     private boolean compare(char str) {  
  105.         if (priStack.empty()) {  
  106.             // 當爲空時,顯然 當前優先級最低,返回高  
  107.             return true;  
  108.         }  
  109.         char last = (char) priStack.lastElement();  
  110.         // 如果棧頂爲'('顯然,優先級最低,')'不可能爲棧頂。  
  111.         if (last == '(') {  
  112.             return true;  
  113.         }  
  114.         switch (str) {  
  115.         case '#':  
  116.             return false;// 結束符  
  117.         case '(':  
  118.             // '('優先級最高,顯然返回true  
  119.             return true;  
  120.         case ')':  
  121.             // ')'優先級最低,  
  122.             return false;  
  123.         case '*': {  
  124.             // '*/'優先級只比'+-'高  
  125.             if (last == '+' || last == '-')  
  126.                 return true;  
  127.             else  
  128.                 return false;  
  129.         }  
  130.         case '/': {  
  131.             if (last == '+' || last == '-')  
  132.                 return true;  
  133.             else  
  134.                 return false;  
  135.         }  
  136.             // '+-'爲最低,一直返回false  
  137.         case '+':  
  138.             return false;  
  139.         case '-':  
  140.             return false;  
  141.         }  
  142.         return true;  
  143.     }  
  144.   
  145.     public static void main(String args[]) {  
  146.         Operate operate = new Operate();  
  147.         int t = operate.caculate("(3+4*(4*10-10/2)#");  
  148.         System.out.println(t);  
  149.     }  
  150.   
  151. }  

使用正則的基本實現思路爲:按照優先級分組,來分隔正則表達式。

並且,每一組分出來以後,計算完成,再將結果帶入原表達式。

先分括號,即:一個括號內的所有內容(數字和運算符)分爲一組,因爲分組得到的括號內的內容,還是一個字符串,所以,可以對這個字符串進行遞歸計算。

再分* / ,即:將一個* 和 / 左右的數字 和* /號分爲一組

再分……

 

對不起各位觀衆朋友,因爲本人昨晚12點多才趕回來,現在已經早上7點半,9點半還要去材料院談項目,12點還要踢比賽,下午2點還要3.1的面試大賽,怕下午撐不住。。俺先睡2小時,晚上回來繼續寫。。大家等等,中間自己也可以想想實現。

順便,晚上附送大禮:本人和衆同學所收集的淘寶武漢衆多面試題,及我們的淺陋看法

 

 

 

現附上正則解析解法

 

 

說明:爲什麼當又括號時,選擇從最裏面一層括號開始提取解析.

1.首先從運算優先級別來看,最內一層括號最優先。

2.從邏輯上說,以最外一層爲單位提取,再遞歸,也可以。但是具體用正則表達式解析時,有如下兩個問題:

如果有括號嵌套,那麼我們需要使用貪婪模式,來把(和最後面一個)匹配。

貪婪模式面臨的問題:當爲平行括號()的時候,會把兩個都匹配出來

3+3*(2-1)+10/(4-2)

非貪婪模式面臨的問題:匹配不了嵌套括號。

3+3*(2-1*4+2*(4-2))

 

因此,使用如下解法中,從最內層開發匹配只需要一個簡單的正則即可實現

 

  1. import java.util.regex.Matcher;  
  2. import java.util.regex.Pattern;  
  3.   
  4. /** 
  5.  * 用正則表達式,解析四則運算字符串,進行四則運算 
  6.  *  
  7.  *思路:四則運算中,我們都是先算出優先級較高的運算符的結果 
  8.  * 並且用該結果代替該運算表達式(包括運算符和參與運算的數字),得到新的運算表達式,繼續進行運算。直到所有的運算符都運算完畢。 
  9.  * 四則運算中:優先級最高的爲括號,嵌套的括號,其內括號優先級也比外面的括號高。 因此,我們只需要找出每個單獨的括號,計算出結果,並用結果代替改括號內容即可。 
  10.  * 此思路自動解決了括號嵌套的問題。 同理,對於'*' '/' ’+‘ ’-‘ 運算,我們同樣只需要用計算結果代替表達式,再代入繼續計算 
  11.  */  
  12. public class RegexOperate {  
  13.   
  14.     /** 
  15.      * 傳入表達式,進行計算 
  16.      *  
  17.      * @param str 
  18.      *            需要計算的表達式 
  19.      * @return 計算結果 
  20.      */  
  21.     public int caculate(String str) {  
  22.         // 當沒有括號嵌套時,左括號’(‘與右括號’)‘直接是沒有其他的左括號’(‘的  
  23.         // 則, 左右括號內爲數字0-9或者加減乘除,且可以出現N次  
  24.         String reg = "//(([0-9//+//-//*///]*)//)";  
  25.         // 編譯正則規範  
  26.         Pattern pat = Pattern.compile(reg);  
  27.         // 用該正則規範匹配需要匹配的字符串  
  28.         Matcher match = pat.matcher(str);  
  29.         // 如果匹配成功  
  30.         if (match.find()) {  
  31.             // 整個結果是需要匹配出來的表達式式,  
  32.             String res = match.group();  
  33.             // 第二組是需要計算出結果的表達式  
  34.             String str2 = match.group(1);  
  35.             int result = caculate2(str2);  
  36.             // 將代替後的表達式重新進行計算(遞歸)  
  37.             return caculate(str.replace(res, "" + result));  
  38.         }  
  39.         // 當匹配不到括號時,直接返回計算值,即爲計算結果  
  40.         return caculate2(str);  
  41.     }  
  42.   
  43.     /**  
  44.      * 不含括號的計算  
  45.      *   
  46.      * @param str  
  47.      *            計算表達式  
  48.      * @return 計算結果  
  49.      */  
  50.     private int caculate2(String str) {  
  51.         // 1.先匹配出乘除  
  52.         // *或者/左右各有一個數字(位數爲一位或者以上)的做爲一組  
  53.         String reg = "(//d+)(//*|///)(//d+)";  
  54.         // 編譯正則規範  
  55.         Pattern pat = Pattern.compile(reg);  
  56.         // 用該正則規範匹配需要匹配的字符串  
  57.         Matcher match = pat.matcher(str);  
  58.         // 如果匹配成功  
  59.         if (match.find()) {  
  60.             // 整個結果是需要匹配出來的表達式式,  
  61.             String res = match.group();  
  62.             // 在整個組中,第一組是需要計算的第一個數  
  63.             int a = Integer.parseInt(match.group(1));  
  64.             // 第二組是需要計算的符號  
  65.             char ope = match.group(2).charAt(0);  
  66.             // 第三組是需要計算的第一個數  
  67.             int b = Integer.parseInt(match.group(3));  
  68.             // 根據需要計算的數跟計算符計算  
  69.             int result = operate(a, ope, b);  
  70.             // 將代替後的表達式重新進行計算(遞歸)  
  71.             return caculate2(str.replace(res, "" + result));  
  72.         }  
  73.   
  74.         // 當匹配不到* / 時,開始匹配+ -  
  75.         // *或者/左右各有一個數字(位數爲一位或者以上)的做爲一組  
  76.         String reg2 = "(//d+)(//+|//-)(//d+)";  
  77.         // 編譯正則規範  
  78.         Pattern pat2 = Pattern.compile(reg2);  
  79.         // 用該正則規範匹配需要匹配的字符串  
  80.         Matcher match2 = pat2.matcher(str);  
  81.         // 如果匹配成功  
  82.         if (match2.find()) {  
  83.             // 整個結果是需要匹配出來的表達式式,  
  84.             String res = match2.group();  
  85.             // 在整個組中,第一組是需要計算的第一個數  
  86.             int a = Integer.parseInt(match2.group(1));  
  87.             // 第二組是需要計算的符號  
  88.             char ope = match2.group(2).charAt(0);  
  89.             // 第三組是需要計算的第一個數  
  90.             int b = Integer.parseInt(match2.group(3));  
  91.             // 根據需要計算的數跟計算符計算  
  92.             int result = operate(a, ope, b);  
  93.             // 將代替後的表達式重新進行計算(遞歸)  
  94.             return caculate2(str.replace(res, "" + result));  
  95.         }  
  96.         return Integer.parseInt(str);  
  97.     }  
  98.   
  99.     /**  
  100.      * 根據計算符,及需要計算的數,進行計算,返回結果  
  101.      *   
  102.      * @param a  
  103.      * @param ope  
  104.      *            計算操作符  
  105.      * @param b  
  106.      * @return 計算結果  
  107.      */  
  108.     private int operate(int a, char ope, int b) {  
  109.         switch (ope) {  
  110.         case '*':  
  111.             return a * b;  
  112.         case '/':  
  113.             return a / b;  
  114.         case '+':  
  115.             return a + b;  
  116.         case '-':  
  117.             return a - b;  
  118.         }  
  119.         return 0;  
  120.     }  
  121.   
  122.     public static void main(String args[]) {  
  123.         RegexOperate r = new RegexOperate();  
  124.         System.out.println(r.caculate("2*(2+33/(10+1))+2*(1+2)"));  
  125.     }  
  126.   
  127. }  

兩種方法性能分析:

 

首先,我們知道使用自己實現的棧的比使用系統棧(遞歸),效率是要高的。

其次,兩個實現中,性能應該都是不高的,因爲都在頻繁的操作String,而String又是不可更改的(在棧的實現中,使用StringBuffer等進行了一定程度上的性能優化)。

再次,在正則的實現中,正則解析的效率,肯定是瓶頸之一。

(具體的性能測試,請讀者自己去操作下,最近實在是忙的一B)

6.什麼是平衡二叉樹?

平衡二叉樹是動態查找表的一種,二叉排序樹也是動態查找表,它在插入元素時,雖然整個查找樹還是有序的,但是同樣的數據,不同的順序,可能就會導致書的結構差異較大,從而平均查找長度可能差異很大。

而平衡二叉樹中,任何一個子節點的左右子樹深度差的絕對值不大於一,這樣可以保證對於同一組數據,不管其順序爲什麼,我們的平均查找長度都不會有什麼差異。

當我們插入數據的時候,如果左右子樹的深度差絕對值大於一,那麼我們將對改子樹進行對應的旋轉操作,以達到平衡。

 

研究了那麼久的數據結構,真的在面試中發揮作用的就是這個題了吧。可惜已經無法挽回老師對我“基礎不紮實“的印象了。

 

 

 

 

失敗原因分析:

老師給我的回覆是:專業技能的基礎還不夠紮實,沒有一個完整的知識體系。

 

其實冷靜下來仔細想想,如果有這樣一位面試者在我面前:

  1.  筆試沒過
  2. 自稱熟悉Reflection,居然簡單問題還答的不堪入目
  3.  四則運算是棧的基本應用,居然答的牛頭不對馬嘴(用正則解析)
  4. 圖是數據結構的重要分支,居然都不知道

我想,如果我是面試官,我也會覺得這樣的應聘者的基礎功太差了吧。

 

 

 

 

 

 

失敗點一:首先,基礎功差。客觀上,自己確實是半路出家搞程序而且還是商學院的,相比計算機院的同學,在硬件、算法、編譯原理、計算機原理、操作系統等知識方面,自己確實會有一定的弱勢。

 

失敗點二:然後,主觀上來說,今天自己確實發揮的太差,老師問的問題也算是根據我簡歷上的技能說明來問的,自己也確實應該是非常熟練的掌握了的,但是爲什麼都沒有答好呢?很值得自己反思。

 

題目分析:

四則運算的那個題,還可以勉強找個理由,因爲自己面的是Java研發,當時思維一直固定在用語言實現,而沒考慮到老師考的是數據結構,想要的答案是用棧來實現,而且用Java的正則也確實可以實現功能。

但是Reflection那個題,自己這麼熟悉的東西,還考的這麼基礎,自己卻莫名其妙的答成這樣,確實是自己的問題。(考前沒複習?太久沒用忘記API?等等等等)

圖的深度優先查找,這個題沒什麼好抱怨的,答不出來安全是自己的錯,而且確實是自己不會,感謝老師讓我發現了知識的漏洞。

其實數據結構本來應該是自己比較有把握的一塊,以爲自己ArrayList、LinkedList、HashMap、TreeMap等常見集合框架都自己實現過了,而且對對內部的一些關係(諸如Set和Map的關係)也研究過了,一直以爲自己是高枕無憂了。奈何自己的眼光一直只盯着Java,也就只研究過集合框架中的內容,卻把圖這樣重要的東西也給疏漏了,可以說自己今天人品不好,恰好就只問了這個,但是也確實是自己有缺陷,心服口服。

 

 

失敗點三:一直跟着老師的這個思路在走,沒有主動的向老師展示出自己比較擅長的東西。

 

自己擅長的多線程,網絡通信,數據庫等內容很遺憾都沒有被問到吧,也可能是老師看到我寫的擅長Java Reflection,然後問了個反射的問題,結果我還沒答好,所以老師失望了,就沒再繼續問下去了吧。

唉,也確實怪自己一緊張,居然連需要先通過class的方法得到Method對象數組,再通過Method對象數組匹配參數和返回值都給忘了。呵呵,現在還記得自己當時看Reflection的時候的比較上寫着,一切都是對象,每個方法都是一個Method類的對象,其中有參數和異常返回值等熟悉,怎麼今天就突然一下短路了呢?

(曾經也一直覺得數據結構自己比較熟悉,應該沒什麼問題,今天悲劇了,所以就算問其他的,可能也可能同樣悲劇吧。)

 

 

 

收穫:

1.自己的努力得到了一定的回報,所以沒有筆試成績,但是自己勇敢的去爭取到了一次面試機會,中間的各種心態變化,自己的心理素質等都得到了很多的鍛鍊和驗證。

2.發現知識漏洞:

1.自以爲掌握的很好的反射,原來太久沒用,基本API等用法都有所忘記。

2.自以爲比較熟悉的數據結構,對於棧,只是明白結構,缺乏去活用它的能力。對於圖,居然遺漏了,沒有學。

3.面試體會:在面試中,首先還是要展示自己作爲“一個人”的基本素質,特性。然後,應該適當的引導老師,儘量展現一下自己的優點。

 

面試總結的也差不多了,雖然總結就知道自己失敗了,總有點挫敗感,但是,另一個角度,反而沒有了患得患失的焦慮,可以更冷靜更合理的看待自己這次的得失。就算失敗了,也得好好分析最大程度的挖掘出這次失敗對自己的價值

 

 

題外話:一。關於計算機專業的知識結構與體系

我想,這主要應該是指:數據庫、操作系統、計算機網絡、數據結構算法。

寫這個,只是想明白自己的優缺點:

缺點:1.數據結構中Java中涉及的比較少的,自己也幾乎沒有涉及

          2.操作系統,對於Linux只是簡單的瞭解,並沒有很深入的研究過文件系統與內存管理等內容(不過還好,在一直正在學習中)

        3.算法,其實,最大的硬傷就在這,一直沒有抽空去研究算法,懂的也確實少,這個是大四初期的主要任務。


優點:1.對於數據結構其他部分還是比較清楚。

          2.對計算機網絡有比較深入的瞭解(嘿嘿,哥一直在寫的小惡意程序就要出來了)

         3.對Java語言的掌握還算比較到位

         4.數據庫掌握比較好

         5.毅力強,對技術狂熱

 

 

關於是否是計算機專業?

很多人都覺得,非計算機專業,就是基礎差的代名詞。

首先,我必須承認一個基礎的事實,普遍意義上來說,計算機專業的同學基礎好與非計算機專業。在其他的院,確實不會開數據庫、操作系統、編譯原理、計算機網絡、數據結構算法這些課程,我們是綜合學科,雖然開了,但是也確實學的很膚淺。

但是,那只是普通意義上來說。如果對於一個非計算機專業的,技術狂熱愛好者呢?我們說的專業,難道只是指的課堂上的專業?

大部分計算機相關專業的同學,或許只是在課堂上上課,大學課堂是什麼情況,大家都懂的。可是,對於狂熱愛好者呢?他並不是沒有學,他只是沒在課堂上學。

我不知道有幾個計算機相關專業的同學像我一樣,每天將近有12個小時在研究技術?
PS. 寫這個只是因爲最近連續被幾個HR鄙視不是計算機相關專業的了,我不是計算機院的,不代表哥不是專業的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章