📜  亚马逊面试经历 |第 186 组(用于 SDE1)(1)

📅  最后修改于: 2023-12-03 14:49:05.595000             🧑  作者: Mango

亚马逊面试经历 | 第 186 组(用于 SDE1)

简介

本文介绍了一位程序员在亚马逊参加SDE1岗位面试时的经历。内容包括面试流程、面试题目及回答思路、面试感受等。

面试流程

本次面试共进行了四轮,每轮时间为45分钟左右。面试官来自不同团队,主要考察了技术能力和问题解决能力。

第一轮:技术面试,主要考察编程基础、算法和数据结构。

第二轮:coding面试,主要考察实际编码能力和解决问题的能力。

第三轮:系统设计面试,主要考察架构设计和问题解决能力。

第四轮:行为面试,主要考察个人素质。

面试题目及回答思路
第一轮:技术面试

1. 编程基础

题目:将一个字符串中的所有空格替换为"%20"。

思路:先遍历一遍字符串,记录下空格数量。然后计算可以扩展的长度,从后往前替换每个字符。

代码片段:

String replace(String s) {
    int count = 0;
    for (int i = 0; i < s.length(); i++) {
        if (s.charAt(i) == ' ') {
            count++;
        }
    }
    char[] ch = new char[s.length() + count * 2];
    for (int i = s.length() - 1; i >= 0; i--) {
        if (s.charAt(i) == ' ') {
            ch[i + count * 2] = '0';
            ch[i + count * 2 - 1] = '2';
            ch[i + count * 2 - 2] = '%';
            count--;
        } else {
            ch[i + count * 2] = s.charAt(i);
        }
    }
    return new String(ch);
}

2. 算法和数据结构

题目:给定一个数组,找到其中两个数之和等于目标值的下标。

思路:使用哈希表,将数组中的每个数放到哈希表中,在查询过程中可以快速判断目标值减去当前值是否已经在哈希表中出现过。

代码片段:

int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        Integer index = map.get(target - nums[i]);
        if (index != null) {
            return new int[]{index, i};
        }
        map.put(nums[i], i);
    }
    return null;
}
第二轮:coding面试

1. 实现一个简单的服务器

题目:给定一个客户端请求,从请求中解析出需要访问的文件,然后将文件内容通过TCP协议发送给客户端。

思路:使用Java的NIO库实现一个简单的服务器,并在服务器上实现一个类似于HTTP的协议,用于解析客户端请求。

代码片段:

public class SimpleServer {
    private static final int BUFFER_SIZE = 1024;
    private static final String ROOT = "/Users/me";
    
    private Selector selector;
    private ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);

    public SimpleServer(int port) throws IOException {
        ServerSocketChannel server = ServerSocketChannel.open();
        server.socket().bind(new InetSocketAddress(port));
        server.configureBlocking(false);

        selector = Selector.open();
        server.register(selector, SelectionKey.OP_ACCEPT);
    }

    public void run() throws IOException {
        while (true) {
            int count = selector.select();
            if (count > 0) {
                Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
                while (keys.hasNext()) {
                    SelectionKey key = keys.next();
                    if (key.isAcceptable()) {
                        ServerSocketChannel server = (ServerSocketChannel) key.channel();
                        SocketChannel client = server.accept();
                        client.configureBlocking(false);
                        client.register(selector, SelectionKey.OP_READ);
                    } else if (key.isReadable()) {
                        SocketChannel client = (SocketChannel) key.channel();
                        int length = client.read(buffer);
                        if (length > 0) {
                            String request = new String(buffer.array(), 0, length);
                            String[] parts = request.split("\\s+");
                            if (parts.length == 3 && "GET".equals(parts[0])) {
                                String path = parts[1];
                                if ("/".equals(path)) {
                                    path = "/index.html";
                                }
                                File file = new File(ROOT, path);
                                String response;
                                if (file.exists() && file.isFile()) {
                                    byte[] data = Files.readAllBytes(file.toPath());
                                    buffer.clear();
                                    buffer.put(data);
                                    buffer.flip();
                                    client.write(buffer);
                                } else {
                                    response = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n";
                                    buffer.clear();
                                    buffer.put(response.getBytes());
                                    buffer.flip();
                                    client.write(buffer);
                                }
                            }
                            client.close();
                        }
                    }
                    keys.remove();
                }
            }
        }
    }
}

第三轮:系统设计面试

题目:设计一个根据位置信息推荐商品的系统。

思路:首先需要定义一些核心的数据结构,如地理位置、商品、用户等,并从中抽象出一些重要的属性,如用户的搜索历史、喜好等。然后根据条件过滤商品,并按照一定的规则排序返回结果。

代码片段:

public class ProductRecommendationSystem {
    private static final double EARTH_RADIUS = 6378.137;

    private Set<Product> products = new HashSet<>();
    private Map<String, Set<Product>> productMap = new HashMap<>();
    private Map<String, User> userMap= new HashMap<>();

    public ProductRecommendationSystem() {
        loadData();
    }

    public List<Product> findProducts(String keyword, double latitude, double longitude, int radius) {
        List<Product> result = new ArrayList<>();
        Set<Product> match = productMap.get(keyword);
        if (match != null) {
            for (Product product : match) {
                if (withinRadius(product, latitude, longitude, radius)) {
                    result.add(product);
                }
            }
            Collections.sort(result, new ProductComparator(latitude, longitude));
        }
        return result;
    }

    private boolean withinRadius(Product product, double latitude, double longitude, int radius) {
        double distance = distance(product.latitude, product.longitude, latitude, longitude);
        return distance <= radius;
    }

    private double distance(double lat1, double lng1, double lat2, double lng2) {
        double radLat1 = Math.toRadians(lat1);
        double radLat2 = Math.toRadians(lat2);
        double a = radLat1 - radLat2;
        double b = Math.toRadians(lng1) - Math.toRadians(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        return s * EARTH_RADIUS * 1000;
    }

    private void loadData() {
        products.add(new Product("A", "apple", 100, 39.9042, 116.4074));
        products.add(new Product("B", "banana", 200, 31.2304, 121.4737));
        products.add(new Product("C", "cake", 150, 22.3964, 114.1095));

        for (Product product : products) {
            String[] keywords = product.keywords.split("\\s+");
            for (String keyword : keywords) {
                Set<Product> set = productMap.get(keyword);
                if (set == null) {
                    set = new HashSet<>();
                    productMap.put(keyword, set);
                }
                set.add(product);
            }
        }

        userMap.put("A", new User("A", "1 2 3"));
        userMap.put("B", new User("B", "hello world"));
        userMap.put("C", new User("C", "apple banana"));
    }

    private static class ProductComparator implements Comparator<Product> {
        private double latitude;
        private double longitude;

        private ProductComparator(double latitude, double longitude) {
            this.latitude = latitude;
            this.longitude = longitude;
        }

        @Override
        public int compare(Product o1, Product o2) {
            double d1 = distance(o1.latitude, o1.longitude, latitude, longitude);
            double d2 = distance(o2.latitude, o2.longitude, latitude, longitude);
            if (d1 < d2) {
                return -1;
            } else if (d1 > d2) {
                return 1;
            } else {
                return 0;
            }
        }
    }
}

class Product {
    String id;
    String name;
    int price;
    double latitude;
    double longitude;
    String keywords;

    public Product(String id, String name, int price, double latitude, double longitude) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.latitude = latitude;
        this.longitude = longitude;
        this.keywords = name.toLowerCase() + " " + price;
    }
}

class User {
    String id;
    String searchHistory;
    String interests;

    public User(String id, String searchHistory) {
        this.id = id;
        this.searchHistory = searchHistory;
    }
}

第四轮:行为面试

行为面试主要考察个人素质和工作经验,主要是与面试官进行一些简单的交流。

面试感受

本次面试难度适中,题目难度与我之前的准备相当。面试官都十分友善,问题也都很有针对性,对我的技术水平和解决问题的能力都有很好的考察和提升。面试过程中有些紧张,但是最终还是顺利通过了面试。