阿里三輪面試,三道機試題


最近參加了某廠的三輪面試,每輪面試面試官均會發送鏈接,進行在線編程。
題目並不要求完整實現,只要寫出大概過程,並闡述解題思路以及注意點即可。
在我極有限的面試經歷中我,委實顯得有趣。

第一輪:轉換字符串為int

題目很簡單,將給定的字符串轉換成int。
拿到題目的時候我很錯愕,這基本是校招生都會覺得簡單的題目。
那么此題唯一需要考慮的就是corner case

首先,確定在解析失敗的情況下,返回特定數值還是拋出異常(最后約定返回-1)。
此外,需要考慮如下情況:

  • 字符串有效性;
  • 字符串正負符號;
  • 字符串解析溢出。
    public int myAtoi(String str) {
        if (str == null || str.length() == 0) {
            return -1;
        }

        str = str.trim();
        if (str.length() == 0) {
            return -1;
        }

        int res = 0, len = str.length();
        boolean flag = false;
        if (str.charAt(0) == '+') {
            flag = true;
            if (len == 1) {
                return -1;
            }
        } else if (str.charAt(0) == '-') {
            if (len == 1) {
                return -1;
            }
        } else if (str.charAt(0) <= '9' && str.charAt(0) >= '0') {
            res = str.charAt(0) - '0';
        } else {
            return -1;
        }

        for (int i = 1; i < str.length(); i++) {
            if (str.charAt(i) >= '0' && str.charAt(i) <= '9') {
                if (res > Integer.MAX_VALUE / 10) {
                    return -1;
                }
                res = res * 10 + (str.charAt(i) - '0');
            } else {
                return -1;
            }
        }

        return (!flag) ? -1 * res : res;
    }

第二輪:高並發接口設計

關於此題,無法理解自己的理解是否正確.
我需要一個支持高並發的插入和獲取接口,存放數據為鏈路監控的Trace數據.

關於Trace數據,可參考OpenTracing相關規范。

代碼此處就不進行詳細展示。
具體思路就是將數據統一存放至ConcurrentHashMap,插入和查詢較為簡單,Trace數據更新時需要注意加鎖。
因為數據限定存放在內存中,那么最簡單提高並發的方式就是入參進行哈希操作,存放在若干個ConcurrentHashMap中。

第三輪:矩陣乘法以及后續優化

題目比較簡單,設計一個矩陣乘法以及相應的測試用例(概要描述即可)。

    public class Matrix {

        public int[][] plus(int[][] a, int[][] b) {
            // 校驗
            if (a.length == 0 || a[0].length == 0 || b.length == 0 || b[0].length == 0) {
                throw new Exception("xx1");
            }
            if (a.length != b[0].length || a[0].length != b.length) {
                throw new Exception("xx2");
            }

            // 計算
            int c[][] = new int[a.length][b[0].length];

            int x, i, j;
            for (i = 0; i < a.length; i++) {
                for (j = 0; j < b[0].length; j++) {
                    int tmp = 0;
                    for (x = 0; x < b.length; x++) {
                        tmp += a[i][x] * b[x][j];
                        // 需要處理數據溢出
                    }
                    c[i][j] = tmp;
                }
            }

            return c;
        }
    }

    //test1: 傳入空數據(數組為空)
    //test2:傳入不規整數據(矩陣長度不一致)
    //test3:傳入乘積累加后溢出的數據
    //test4: 傳入矩陣維數為1的數據
    //test5: 傳入較小維度矩陣
    //test6: 傳入維度巨大矩陣

代碼比較簡單,但是在面試官的提示下,漏掉了1*m矩陣和m*1矩陣相乘的情況。
因為面試時間有限,就沒有設計類存放矩陣數據,從而避免1*m矩陣和m*1矩陣相乘的特例。
追加問題:

(1) 上述代碼,如何更改能夠提升性能?

上述代碼在排除雙重循環的問題后,聯想到b矩陣的數據是按列獲取的。
這也意味着每輪獲取b[i][j]的數據,都無法利用到cpu的緩存,因此可以將乘法進行優化,盡量按照行去讀取數據。

(2)高維稀疏矩陣如何進行優化呢?

僅保留不為0的數據,此時需要設計數據結構,保存數據的三要素:行號,列號以及數值;
此外建立數組存放三元組數據,格式如下所示:

typedef struct NODE{    //定義稀疏矩陣結點
 int j;                 //列
 int data;              //值
} Node;

typedef struct MATRIX{  //定義稀疏矩陣(可以快速訪問)
 int mu, nu, tu;        // mu為矩陣行數,nu為矩陣列數,tu為矩陣中非零元素的個數
 Node matrix[MAXSIZE+1];
 int rpos[MAXR+1];
} Matrix;

// 摘抄網上代碼,當時只提出了想法

針對三元組表示的矩陣乘法,在網上有較多的示例,大家可自行查閱。

說實話,三次面試的機試題都很有趣,題目難度不大,但是面試官會層層遞進的詢問,不斷發掘疏忽的細節。

PS:
如果您覺得我的文章對您有幫助,請關注我的微信公眾號,謝謝!
程序員打怪之路


免責聲明!

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



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