「面试」微软

3-15 一面

上来先让英文自我介绍,我人都傻了,事先也没听说有这档子事儿啊,叭叭瞎说了一通,实在编不下去,直接 that’s all, 结束。

然后就是写题,不多逼逼,什么八股文,Java,压根儿不问。

  • 给一个单词序列,\0为结束符 ,反转\0 之前的单词

  • 写测试用例

  • 讲思路

微软面试官好像很重视测试用例的设计,一个劲儿的问我还有没有什么特殊用例没cover到。。。

Input:   " Nice  to meet you!  \0"
Output:  "  you! meet to  Nice \0"

public chars reverse(char[] chars){
        Stack<String> stack = new Stack<>();

      int i = 0;
      while(chars[i]!='\0'){
    //     探测到'\0' 结束      
          if(chars[i] = ' '){
              // 如果当前是空格
            int j = i;
            StringBuilder sb = new StringBuilder();
            sb.append(chars[i]);// 当前位置加进去
            while(chars[j+1] == ' '{
              // j+1 也是空格
                j++;
              sb.append(chars[j]);// j也加进去
            }
            stack.push(sb.toString());
              i = j+1;
          }else if(isCharacter(chars[i]){// 
              // 如果当前是字母
            int j = i;
            StringBuilder sb = new StringBuilder();
            sb.append(chars[i]);// 当前位置加进去
            while(isCharacter(chars[j+1])){
              // j+1 也是单词
                j++;
              sb.append(chars[j]);// j也加进去
            }
            stack.push(sb.toString());
              i = j+1;
          }
     }
    // i所在的位置: '\';
    int p = 0;
    while(!stack.isEmpty()){
        String cur = stack.pop();
      for(int j = 0;j < cur.length();j++){
          chars[p++] = cur.charAt(j);
      }
    }
    return chars;
}
//       \0
// fsdkljfsdlk\0
//  sfdk \0
//fsdkljf sjdkfl\0
// lfsdkj fsdjkl \0fsdkfjs\0
// \0
// \0\0
// \\0

虽然英文自我介绍稀碎,但好在手撕的时候和面试官交流还不错,第二天就收到邮件了。

3.19 三面(一面过了直通三面)

上来先自我介绍一下,这次没让用英文(虚晃一枪,白准备了)

讲项目,讲亮点

继续手撕

  • 一个数组,取两个数,和的绝对值最小
// helloworld

public int getMin(int[] arr){
    // 找不到两个数字
    if(arr == null || arr.length < 2){
        return 0;
    }
    Arrays.sort(arr);
    int n = arr.length;
    // 至少两个元素, n >= 2
    if(arr[0] >= 0){
        // 没有负数
        return arr[0] + arr[1];
    }
    if(arr[n-1] <= 0){
        // 没有正数
        return arr[n-1] + arr[n-2];
    }
    // 有正有负
    int left = 0;
    int right = n - 1;
    int ret = Integer.MAX_VALUE;
    while(left < right){//[left,right]
        // 特殊情况
        if(arr[left] + arr[right] == 0){
            return 0;
        }
        // 考虑当前情况
        ret = Math.min(ret, Math.abs(arr[left] + arr[right]));
        // 更新下一步
        if(Math.abs(arr[left]) > Math.abs(arr[right])){
            left++;
        }else{
            right--;
        }
    }//left = right
    return ret;
}
  • 一个数组,取两个数,和的绝对值最小

public ListNode insert(ListNode A, ListNode B, int i, int j){
    // i,j 从0开始, i, j 可以相等
    // 考虑替换的是 [i,j] 闭区间
    if(i < 0 || j < 0 || i > j){
        // i,j 不合法
        return A;
    }
    if(A == null || B == null){
        return A;
    }
    int len = 0;
    ListNode pA = A;
    while(pA != null){
        pA = pA.next;
        len++;
    }
    if(len-1 < j){
        // j 应该 <= len-1
        throw Exception;
        // i,j 不合法
    }
    // i,j 合法的情况
    pA = A;
    ListNode pre = null;
    for(int k = 0;k < i;k++){
        pre = pA;
        pA = pA.next;
    }
    // pre指向应该断开的链表的前驱
    ListNode tail = null;// 断开的链表的尾部
    for(int k = 0;k < j-i ;k++){
        tail = pA;
        pA = pA.next;
    }
    ListNode newStart = pA;
    // newStart 指向断开之后的后半截的首节点

    tail.next = null;

    pre.next = B;// 把B接上

    // 找到B的尾部节点
    ListNode preB = null;
    ListNode pB = B;
    while(pB != null){
        preB = pB;
        pB = pB.next;
    }
    preB.next = newStart;

    return A;
}

题目倒是不难,就是比较麻烦,好在微软面试不用OJ,不用严格地考虑算法正确性。思路正确即可。

主要是需要考虑各种边界值与特殊情况的判定。

3.24 收到 Information Collection 的邮件

3.31 offer邮件 !


本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

「面试」腾讯 上一篇
Java并发编程 下一篇