腾讯笔经面经(微信事业群)

文章目录

    • 算法题
        • 1、题目1
        • 2、题目2
        • 3、题目三
    • 技术面试
    • 疑问解答

微信事业群
时间:2019/9/10 11:00 ~ 13:30

算法题

1、题目1

对于一棵满二叉排序树深度为K,节点数为 2^K - 1 ;节点值为 1至 (2^K-1)。
给出K和任意三个节点的值,输出包含该三个节点的最小子树的根节点值
样例输入:4 10 15 13
样例输出:12

我的代码实现:

package NormalTest;

import java.util.Scanner;

public class Main1 {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        while (in.hasNextInt()) {

            String dataStr = in.nextLine();
            String[] strs = dataStr.split(" ");
            int dep = Integer.parseInt(strs[0]);
            int[] array = new int[dep-1];
            for (int i = 0; i < dep-1; i++) {
                array[i] = Integer.parseInt(strs[i+1]);
            }
            System.out.println(get(dep, array));
        }

    }

    private static int get (int dep, int[] array) {
        int cur = (int)Math.pow(2,dep-1);
        int result  = 0;

        for (int i = dep-1; i > 0; i--) {
            if (array[0] > cur && array[1] > cur && array[2] > cur)
                cur = cur + (int)Math.pow(2, i-1);
            else if (array[0] < cur && array[1] < cur && array[2] < cur)
                cur = cur - (int)Math.pow(2, i-1);
            else
            {
                result = cur;
                break;
            }

        }

        return result;
    }

}

2、题目2

回形矩阵是由1开始的自然数顺时针排列成的一个n*n矩阵,n为奇数.

1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

要求打印出它的一个子矩阵(m*m),例如在n=5的矩阵里面以起始点 xy( 2,2 ) 打印m = 2的正方形,则输出:
17,18
24,25

进阶: 是否可以应对超大规模的情况,例如n > 10000000,m<100的场景

我的代码实现

package NormalTest;

import java.util.Scanner;

public class Main2 {


    //private static int length = 0;
    private static int value = 1;
    //private static int[][] array = null;
    private static Direction lastDirection = Direction.Right;

    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String dataStr = in.nextLine();
            String[] strs = dataStr.split(" ");
            int length = Integer.parseInt(strs[0]);
            int cow = Integer.parseInt(strs[1]);
            int col = Integer.parseInt(strs[2]);
            int[][] array = new int[length][length];
            init(length, array);
            print(array, length, cow, col);
        }
    }


    private static enum Direction {
        Right, Down, Left, Up;
    }



    public static void init(int length, int[][] array) {
        int row = 0, col = 0;
        for (int i = 0; i < length * length; i++) {
            array[row][col] = value;
            lastDirection = findDirection(row, col, length);
            switch (lastDirection) {
                case Right:
                    col++;
                    break;
                case Down:
                    row++;
                    break;
                case Left:
                    col--;
                    break;
                case Up:
                    row--;
                    break;
                default:
                    System.out.println("error");
            }
            value++;
        }
    }


    private static Direction findDirection(int row, int col, int length) {
        Direction direction = lastDirection;

        switch (direction) {
            case Right: {
                if (row == 0 && col >= length-1)
                    direction=Direction.Down;
                break;
            }
            case Down: {
                if (row == length-1 && col >= length-1)
                    direction=Direction.Left;
                break;
            }
            case Left: {
                if (row == length-1&&col <= 0)
                    direction=Direction.Up;
                break;
            }
            case Up: {
                if (row == 1 && col <= 0)
                    direction=Direction.Right;
                break;
            }
        }

        return direction;
    }


    private static void print(int[][] arr, int length) {
        for (int i = 0; i < length; i++) {
            for (int j = 0; j < length; j++) {
                System.out.printf(" %2d", arr[i][j]);
            }
            System.out.println();
        }
    }

    private static void print(int[][] arr, int length, int cow, int col) {
        for (int i = cow-1; i < length; i++) {
            for (int j = col-1; j < length; j++) {
                System.out.printf(" %2d", arr[i][j]);
            }
            System.out.println();
        }
    }
}

3、题目三

一个页面有两个广告位,现有四个广告需要展示,实现一个算法输出需要展示的两个广告
要求:
a.输出的两个广告不能相同;
b.多次调用输出的四个广告的概率为:1:2:3:4 (4个广告用整形1-4来表示)
c.进阶:是否存在通用解,n个广告,概率为p1:p2:…:pn

我的代码实现:

import java.util.Scanner;
public class Main2 {
    //private static int length = 0;
    private static int value = 1;
    //private static int[][] array = null;
    private static Direction lastDirection = Direction.Right;
    
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String dataStr = in.nextLine();
            String[] strs = dataStr.split(" ");
            int length = Integer.parseInt(strs[0]);
            int cow = Integer.parseInt(strs[1]);
            int col = Integer.parseInt(strs[2]);
            int[][] array = new int[length][length];
            init(length, array);
            print(array, length, cow, col);
        }
    }

    private static enum Direction {
        Right, Down, Left, Up;
    }


    public static void init(int length, int[][] array) {
        int row = 0, col = 0;
        for (int i = 0; i < length * length; i++) {
            array[row][col] = value;
            lastDirection = findDirection(row, col, length);
            switch (lastDirection) {
                case Right:
                    col++;
                    break;
                case Down:
                    row++;
                    break;
                case Left:
                    col--;
                    break;
                case Up:
                    row--;
                    break;
                default:
                    System.out.println("error");
            }
            value++;
        }
    }


    private static Direction findDirection(int row, int col, int length) {
        Direction direction = lastDirection;

        switch (direction) {
            case Right: {
                if (row == 0 && col >= length-1)
                    direction=Direction.Down;
                break;
            }
            case Down: {
                if (row == length-1 && col >= length-1)
                    direction=Direction.Left;
                break;
            }
            case Left: {
                if (row == length-1&&col <= 0)
                    direction=Direction.Up;
                break;
            }
            case Up: {
                if (row == 1 && col <= 0)
                    direction=Direction.Right;
                break;
            }
        }

        return direction;
    }


    private static void print(int[][] arr, int length) {
        for (int i = 0; i < length; i++) {
            for (int j = 0; j < length; j++) {
                System.out.printf(" %2d", arr[i][j]);
            }
            System.out.println();
        }
    }

    private static void print(int[][] arr, int length, int cow, int col) {
        for (int i = cow-1; i < length; i++) {
            for (int j = col-1; j < length; j++) {
                System.out.printf(" %2d", arr[i][j]);
            }
            System.out.println();
        }
    }
}

技术面试

说说项目

  1. 挑战?
  2. 如何解决痛点问题的
  3. 分布式事务

谈到2PC、3阶段,TCC、AT、Saga、TX

  1. 空回滚是什么?事务悬挂又是什么?

事务悬挂是一阶段缺失二阶段的现象
事务空回滚是因为一阶段由于网络阻塞导致超时二阶段回滚,之后一阶段恢复之后导致事务悬挂

  1. 事务悬挂如何解决?

5.1 及时发现,预警
5.2 30秒/60秒拒绝空回滚
事务操作过程记录事务的状态,有空回滚的事务及时处理

疑问解答

博主实时在线,欢迎读者交流,相互学习

你可能感兴趣的:(笔经面经)