《去哪兒》JAVA研發筆試+一面


  背景不多說了,入正題,先說下筆試吧,研發崗位總共三道編程題,總的來說不是特別難,但要求要紙上寫代碼,所以寫代碼前先三思下,可以在試卷上寫偽代碼思路(答卷分開),后在答卷上寫題,切記:一定別忘記注釋。

  筆試題:

  一、部分有序旋轉數組查找問題。

  有一遞增數組可向右移動,如:{1,2,3,4,5}向右移動后可為:{3,4,5,1,2},現在類似的數組中想找一個固定值,若存在則返回對應下標,若不存在則返回-1。需要考慮算法效率。

  題解:很容易的就想到二分查找,是不是?但問題來了:數組有可能是由兩部分遞增的數組組成的,這樣子就不能用二分查找法了。等等,這兩部分有特別發現了沒?數組第一個元素和最后一個比較,如果第一個比最后一個大,那么數組就是旋轉了,此時很容易就想到先將原數組分割成兩個遞增數組再分別二分查找。

    public int indexInTurnedArray(int[] array, int index) {// find out where the target int is
        int tmp = -1;
        if(null == array || 0 == array.length) {//error input
            tmp = -1;
        } else{
            int bound = findArrayBound(array);//get the boundary of the array, which means the bigest one in array
            if(index == array[bound]) {//the target int is the boundary
                tmp = bound + 1;
            } else {
                //the target int should in the left side of the boundary, or the right side
                //anyside should return the index of the array, else return -1
                //so, if none exist in both sides, the result will be -1
                //if the target is match to the first one of the array, the 0 should be the reslut
                tmp = 1 + binarySearch(array, 0, bound - 1, index) + binarySearch(array, bound + 1, array.length -1, index);
            }
        }
        return tmp;
    }
    
    /**
     * find the bigest element in the turned-array
     * @param array
     * @return
     */
    public int findArrayBound(int[] array) {
        if(array[0] < array[array.length - 1]) {//the array is a sequnced array, small to big...
            return array.length - 1;
        } else {
            int tmp = 0;
            //begin is used for index the last one in the bigger side
            //end is the first one in the smaller side
            int begin = 0, end = array.length - 1;
            while(begin < end) {//when the begin = end ,the circle will exist, means find the boundary
                if(1 == end - begin) {//found the boundary
                    tmp = end - 1;
                    break;
                }
                tmp = (begin + end) / 2;
                if(array[tmp] >= array[begin]) {//the middle one is bigger than begin
                    begin = tmp;
                } else if(array[tmp] <= array[end]) {//the middle one is small than end
                    end = tmp;
                }
            }
            return tmp;    
        }
    }
    
    public int binarySearch(int[] array, int begin, int end, int index) {//binary research function
        if(begin == end) {
            return index == array[begin] ? begin : -1;
        } else {
            int middle = (begin + end) / 2;
            if(index == array[middle]) {
                return middle;
            } else if(index < array[middle]){
                return binarySearch(array, begin, middle - 1, index);
            } else {
                return binarySearch(array, middle + 1, end, index);
            }
        }
    }

  二、字符串解釋

  對輸入的字符串,如:a2b3c4解密,解密結果應該為aabbbcccc。

  題解:比較簡單的一題字符操作,考查ASCII碼運用及,字符串的相關知識。

    string stringDecode(tring s)
    {
        char* c = const_cast<char*>(s.c_str());//將輸入字符串強制轉換成字符
        String tmp;
        while (*c != '\0')
        {
            char a = 0;
            int j = -1;
            if ((*c>='A' && *c <= 'Z') || (*c >= 'a'&&*c<='z'))//判定是否是字母
            {
                a = *c;
                c++;
            }
            if (*c != '\0' && *c >= '0' && *c <= '9')//判定是否是數字
            {
                while (*c != '\0' && *c >= '0' && *c <= '9')//將所有數字轉換成int
                {
                    if (-1 == j)
                    {
                        j = (int)*c-48;
                    }
                    else
                    {
                        j = j * 10 + ((int)*c-48);
                    }
                    c++;
                }
            }
            if (a != 0)//若第一個是字母,則輸出
            {
                if (-1 == j)
                {
                    tmp += a;
                }
                else
                {
                    for (int i = 0; i < j; i++)
                    {
                        tmp += a;//迭加之前的字母個數
                    }
                }
            }
        }
        return tmp;
    }

  三、多維數組操作

  有一酒店某段時間內價格是由三元組確定的,如:第一天至第30天的價格是300元,則三元組為:[1,30,300]。后來出現的三元組的價格可以覆蓋之前三元組的價格,如再出現[20, 50, 100]則其價格為:[1,19, 300], [20, 50, 100]。

  題解:題目即為輸入是二維數組,每行第一個元素是起始日期,第二個元素是截至日期,第三個元素為此段時間內價格。我很容易的想到了上萬數亂序查找哪個數不存在的問題,即:建立一個較目標大點的一維數組(此處大小為366,一年不超過366天),若輸入的三元組中規定了日期的價格,則分別將對應下標的數組中的值改為價格,后來再有重復的話將之前的價格覆蓋即可。最后在遍歷數組,找出非0的部分,值相同的一段將起始下標、終止下標、價格作為新的三元組輸出。

  

 1     public void hotelPrice(int[][] array) {
 2         int beginDay = 365, endDay = 0;    //store the begin and end day of the input
 3         int[] price = new int[366];        //the price must in a year
 4         int tmp = 0;
 5         for(int i = 0; i < array.length; i++) {    //the 3-element-array number
 6             if(beginDay > array[i][0]) {        //price begin day
 7                 beginDay = array[i][0];
 8             }
 9             if(endDay < array[i][1]) {    //price end day
10                 endDay = array[i][1];
11             }
12             tmp = array[i][0];
13             while(tmp <= array[i][1]) {
14                 price[tmp++] = array[i][2];        //pice
15             }
16         }
17         int i = beginDay;
18         while(i <= endDay) {//print result
19             if(0 == price[i]) {
20                 i++;
21                 continue;
22             } else {
23                 int begin = i;
24                 int tmpV = price[i];
25                 while(i < 366 && price[++i] == tmpV) {//find the same price day
26                     continue;
27                 }
28                 int end = i - 1;
29                 System.out.println("[" + begin + " , " + end + " , " + tmpV + "]");//print
30             }
31         }
32     }

  面試:

  主要問了些關於簡歷和筆試中的細節問題。

  一、由於之前我在銳捷實習過4個月,問了些關於銳捷實習過程中我做的一個用robotframework搭建的自動化測試平台的東西,這部分聊的比較HIGH,和面試官聊了半天算是科普了許多無線方面的知識吧,還說了一些我在項目中遇到的問題和相應的解決思路和過程。

  二、socket和http的區別。

  http是超文本傳輸協議,主要是用來在應用程序層面封裝web數據的一個協議,封裝完后再交由TCP封裝,IP封裝,最后由底層網絡送出報文交付;

  socket可以分為IP層的socket和TPC層的socket,其主要功能是為了方便程序員更好的調用協議棧完成相應工作,簡單的說就是對協議棧封裝提供一套API給開發者用。

  故,一個是協議;另一個只是一系列的接口API。

  三、什么是線程安全。

  (從度娘搬運來的)線程安全就是多線程訪問時,采用了加鎖機制,當一個線程訪問該類的某個數據時,進行保護,其它線程不能進行訪問直到該線程讀取完。不會出現數據不一致或污染。線程不安全就是不提供數據訪問保護,有可能出現多個線程先后更改數據造成所得到的數據是臟數據。

  四、Spring主要作用

  (從CSDN上搬運過來,http://blog.csdn.net/dyllove98/article/details/8586312)

   五、數據庫外鍵

  外鍵主要是用於兩個或多個表關聯時,關聯的關鍵字即是外鍵。

 

  由於當時問到銳捷項目后,問了許多python語言類的東西,本人實在太菜未系統學過,所以基本答的很亂,最后妥妥的跪了。歡迎大家來拍磚和補充。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM