deepseek梳理java高级开发工程师算法面试题

news2025/5/16 2:57:18

Java高级工程师算法面试题与答案

一、数据结构与算法基础

1. 红黑树与AVL树比较

题目:详细说明红黑树和AVL树的区别及各自的适用场景,并用Java实现红黑树的插入操作。

答案

区别对比

┌──────────────────┬──────────────────────────────┬──────────────────────────────┐
│ 特性            │ 红黑树                        │ AVL树                        │
├──────────────────┼──────────────────────────────┼──────────────────────────────┤
│ 平衡标准        │ 松散平衡(最长路径≤2倍最短路径)│ 严格平衡(左右子树高度差≤1)  │
│ 插入/删除效率   │ O(1)旋转次数                  │ O(log n)旋转次数              │
│ 查找效率        │ 稍慢(因不够严格平衡)         │ 更快                          │
│ 存储开销        │ 1bit颜色信息                  │ 平衡因子(int)               │
│ 适用场景        │ 频繁插入删除(如Java HashMap)│ 查找密集型(如数据库索引)     │
└──────────────────┴──────────────────────────────┴──────────────────────────────┘

红黑树Java实现

class RedBlackTree {
    private static final boolean RED = true;
    private static final boolean BLACK = false;
    
    class Node {
        int key;
        Node left, right;
        boolean color;
        
        Node(int key) {
            this.key = key;
            this.color = RED; // 新节点总是红色
        }
    }
    
    private Node root;
    
    private boolean isRed(Node x) {
        return x != null && x.color == RED;
    }
    
    public void insert(int key) {
        root = insert(root, key);
        root.color = BLACK; // 根节点始终黑色
    }
    
    private Node insert(Node h, int key) {
        if (h == null) return new Node(key);
        
        if (key < h.key) h.left = insert(h.left, key);
        else if (key > h.key) h.right = insert(h.right, key);
        
        // 平衡化操作
        if (isRed(h.right) && !isRed(h.left)) h = rotateLeft(h);
        if (isRed(h.left) && isRed(h.left.left)) h = rotateRight(h);
        if (isRed(h.left) && isRed(h.right)) flipColors(h);
        
        return h;
    }
    
    private Node rotateLeft(Node h) {
        Node x = h.right;
        h.right = x.left;
        x.left = h;
        x.color = h.color;
        h.color = RED;
        return x;
    }
    
    // rotateRight和flipColors实现类似...
}

二、高级算法设计

2. 分布式ID生成算法

题目:设计一个分布式环境下高性能ID生成服务,要求满足:

  1. 全局唯一
  2. 趋势递增
  3. 高可用
  4. 每秒至少10万ID生成

答案

Snowflake算法改进版

public class DistributedIdGenerator {
    private final long twepoch = 1288834974657L; // 起始时间戳
    private final long workerIdBits = 10L; // 工作机器ID位数
    private final long maxWorkerId = ~(-1L << workerIdBits);
    private final long sequenceBits = 12L; // 序列号位数
    
    private final long workerIdShift = sequenceBits;
    private final long timestampShift = sequenceBits + workerIdBits;
    private final long sequenceMask = ~(-1L << sequenceBits);
    
    private long workerId;
    private long sequence = 0L;
    private long lastTimestamp = -1L;
    
    public DistributedIdGenerator(long workerId) {
        if (workerId > maxWorkerId || workerId < 0) {
            throw new IllegalArgumentException("workerId不合法");
        }
        this.workerId = workerId;
    }
    
    public synchronized long nextId() {
        long timestamp = timeGen();
        
        if (timestamp < lastTimestamp) {
            throw new RuntimeException("时钟回拨异常");
        }
        
        if (lastTimestamp == timestamp) {
            sequence = (sequence + 1) & sequenceMask;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }
        
        lastTimestamp = timestamp;
        
        return ((timestamp - twepoch) << timestampShift) 
            | (workerId << workerIdShift) 
            | sequence;
    }
    
    private long tilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }
    
    private long timeGen() {
        return System.currentTimeMillis();
    }
}

优化点

  1. 时钟回拨处理:抛出异常或等待
  2. 性能优化:无锁CAS(如用AtomicLong)
  3. 分段缓冲:预生成ID减少实时计算压力
  4. 监控报警:ID生成速率监控

三、并发算法

3. 高效缓存淘汰算法

题目:实现一个线程安全的LFU(Least Frequently Used)缓存,要求所有操作时间复杂度O(1)。

答案

class LFUCache {
    class Node {
        int key, value, freq;
        Node prev, next;
        Node(int key, int value) {
            this.key = key;
            this.value = value;
            this.freq = 1;
        }
    }
    
    class FreqList {
        int freq;
        Node head, tail;
        FreqList prev, next;
        
        FreqList(int freq) {
            this.freq = freq;
            head = new Node(0, 0);
            tail = new Node(0, 0);
            head.next = tail;
            tail.prev = head;
        }
        
        void addNode(Node node) {
            node.next = head.next;
            head.next.prev = node;
            head.next = node;
            node.prev = head;
        }
        
        void removeNode(Node node) {
            node.prev.next = node.next;
            node.next.prev = node.prev;
        }
        
        boolean isEmpty() {
            return head.next == tail;
        }
    }
    
    private int capacity;
    private Map<Integer, Node> cache;
    private Map<Integer, FreqList> freqMap;
    private FreqList minFreqList;
    
    public LFUCache(int capacity) {
        this.capacity = capacity;
        cache = new HashMap<>();
        freqMap = new HashMap<>();
        minFreqList = new FreqList(0);
        freqMap.put(0, minFreqList);
    }
    
    public int get(int key) {
        if (!cache.containsKey(key)) return -1;
        
        Node node = cache.get(key);
        updateFreq(node);
        return node.value;
    }
    
    public void put(int key, int value) {
        if (capacity == 0) return;
        
        if (cache.containsKey(key)) {
            Node node = cache.get(key);
            node.value = value;
            updateFreq(node);
            return;
        }
        
        if (cache.size() == capacity) {
            Node toRemove = minFreqList.tail.prev;
            minFreqList.removeNode(toRemove);
            cache.remove(toRemove.key);
            if (minFreqList.isEmpty()) {
                freqMap.remove(minFreqList.freq);
            }
        }
        
        Node newNode = new Node(key, value);
        cache.put(key, newNode);
        FreqList freqList = freqMap.getOrDefault(1, new FreqList(1));
        freqList.addNode(newNode);
        freqMap.put(1, freqList);
        minFreqList = freqList;
    }
    
    private void updateFreq(Node node) {
        FreqList oldList = freqMap.get(node.freq);
        oldList.removeNode(node);
        
        if (oldList.isEmpty() && node.freq == minFreqList.freq) {
            minFreqList = oldList.next != null ? oldList.next : oldList;
        }
        
        node.freq++;
        FreqList newList = freqMap.getOrDefault(node.freq, new FreqList(node.freq));
        newList.addNode(node);
        freqMap.put(node.freq, newList);
    }
}

时间复杂度分析

  • get操作:HashMap查询O(1) + 链表操作O(1) = O(1)
  • put操作:HashMap查询O(1) + 链表操作O(1) = O(1)
  • 空间复杂度:O(capacity)

四、分布式算法

4. 一致性哈希算法

题目:实现带虚拟节点的一致性哈希算法,解决分布式缓存数据倾斜问题。

答案

public class ConsistentHash<T> {
    private final HashFunction hashFunction;
    private final int numberOfReplicas; // 虚拟节点数
    private final SortedMap<Long, T> circle = new TreeMap<>();
    
    public ConsistentHash(HashFunction hashFunction, 
                        int numberOfReplicas,
                        Collection<T> nodes) {
        this.hashFunction = hashFunction;
        this.numberOfReplicas = numberOfReplicas;
        
        for (T node : nodes) {
            add(node);
        }
    }
    
    public void add(T node) {
        for (int i = 0; i < numberOfReplicas; i++) {
            long hash = hashFunction.hash(node.toString() + i);
            circle.put(hash, node);
        }
    }
    
    public void remove(T node) {
        for (int i = 0; i < numberOfReplicas; i++) {
            long hash = hashFunction.hash(node.toString() + i);
            circle.remove(hash);
        }
    }
    
    public T get(Object key) {
        if (circle.isEmpty()) return null;
        
        long hash = hashFunction.hash(key.toString());
        if (!circle.containsKey(hash)) {
            SortedMap<Long, T> tailMap = circle.tailMap(hash);
            hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
        }
        return circle.get(hash);
    }
    
    interface HashFunction {
        long hash(String key);
    }
    
    // 测试用例
    public static void main(String[] args) {
        Set<String> nodes = new HashSet<>(Arrays.asList("Node1", "Node2", "Node3"));
        ConsistentHash<String> ch = new ConsistentHash<>(key -> {
            // 使用MD5哈希
            try {
                MessageDigest md = MessageDigest.getInstance("MD5");
                byte[] digest = md.digest(key.getBytes());
                return ((long)(digest[3] & 0xFF) << 24) 
                     | ((long)(digest[2] & 0xFF) << 16)
                     | ((long)(digest[1] & 0xFF) << 8) 
                     | (digest[0] & 0xFF);
            } catch (NoSuchAlgorithmException e) {
                return key.hashCode();
            }
        }, 1000, nodes);
        
        System.out.println(ch.get("user123")); // 返回对应的节点
    }
}

优化点

  1. 虚拟节点数量:通常设置100-200个
  2. 哈希函数选择:MD5、MurmurHash等
  3. 数据迁移:节点增减时只影响相邻节点
  4. 监控统计:节点负载均衡监控

五、机器学习算法

5. 推荐系统相似度算法

题目:实现基于用户的协同过滤推荐算法,包含余弦相似度计算和推荐生成。

答案

public class UserCFRecommender {
    private Map<Integer, Map<Integer, Double>> userItemMatrix; // 用户-物品评分矩阵
    
    public UserCFRecommender(Map<Integer, Map<Integer, Double>> userItemMatrix) {
        this.userItemMatrix = userItemMatrix;
    }
    
    // 计算用户相似度矩阵
    public Map<Integer, Map<Integer, Double>> calculateUserSimilarities() {
        Map<Integer, Map<Integer, Double>> simMatrix = new HashMap<>();
        List<Integer> users = new ArrayList<>(userItemMatrix.keySet());
        
        for (int i = 0; i < users.size(); i++) {
            int u1 = users.get(i);
            simMatrix.putIfAbsent(u1, new HashMap<>());
            
            for (int j = i + 1; j < users.size(); j++) {
                int u2 = users.get(j);
                double similarity = cosineSimilarity(
                    userItemMatrix.get(u1),
                    userItemMatrix.get(u2)
                );
                
                simMatrix.get(u1).put(u2, similarity);
                simMatrix.putIfAbsent(u2, new HashMap<>());
                simMatrix.get(u2).put(u1, similarity);
            }
        }
        return simMatrix;
    }
    
    // 余弦相似度计算
    private double cosineSimilarity(Map<Integer, Double> v1, Map<Integer, Double> v2) {
        Set<Integer> commonItems = new HashSet<>(v1.keySet());
        commonItems.retainAll(v2.keySet());
        
        double dotProduct = 0.0;
        double norm1 = 0.0;
        double norm2 = 0.0;
        
        for (int item : commonItems) {
            dotProduct += v1.get(item) * v2.get(item);
        }
        
        for (double rating : v1.values()) {
            norm1 += Math.pow(rating, 2);
        }
        
        for (double rating : v2.values()) {
            norm2 += Math.pow(rating, 2);
        }
        
        return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
    }
    
    // 生成推荐
    public List<Integer> recommendItems(int userId, int topN) {
        Map<Integer, Double> scores = new HashMap<>();
        Map<Integer, Double> userRatings = userItemMatrix.get(userId);
        Map<Integer, Map<Integer, Double>> simMatrix = calculateUserSimilarities();
        
        for (Map.Entry<Integer, Map<Integer, Double>> entry : userItemMatrix.entrySet()) {
            int otherUserId = entry.getKey();
            if (otherUserId == userId) continue;
            
            double similarity = simMatrix.get(userId).getOrDefault(otherUserId, 0.0);
            if (similarity <= 0) continue;
            
            for (Map.Entry<Integer, Double> itemEntry : entry.getValue().entrySet()) {
                int itemId = itemEntry.getKey();
                if (userRatings.containsKey(itemId)) continue;
                
                scores.merge(itemId, itemEntry.getValue() * similarity, Double::sum);
            }
        }
        
        return scores.entrySet().stream()
            .sorted(Map.Entry.<Integer, Double>comparingByValue().reversed())
            .limit(topN)
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());
    }
}

优化方向

  1. 相似度计算:改用皮尔逊相关系数
  2. 矩阵稀疏性:使用稀疏矩阵存储
  3. 实时更新:增量计算相似度
  4. 并行计算:MapReduce实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2376532.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode - 滑动窗口问题集

目录 前言 题1 长度最小的子数组&#xff1a; 思考&#xff1a; 参考代码1&#xff1a; 参考代码2&#xff1a; 题2 无重复字符的最长子串&#xff1a; 思考&#xff1a; 参考代码1&#xff1a; 参考代码2&#xff1a; 题3 最大连续1的个数 III&#xff1a; 思考&am…

一分钟在Cherry Studio和VSCode集成火山引擎veimagex-mcp

MCP的出现打通了AI模型和外部数据库、网页API等资源&#xff0c;成倍提升工作效率。近期火山引擎团队推出了 MCP Server SDK&#xff1a; veimagex-mcp。本文介绍如何在Cherry Studio 和VSCode平台集成 veimagex-mcp。 什么是MCP MCP&#xff08;Model Context Protocol&…

Tomcat与纯 Java Socket 实现远程通信的区别

Servlet 容器​​&#xff08;如 Tomcat&#xff09; 是一个管理 Servlet 生命周期的运行环境&#xff0c;主要功能包括&#xff1a; ​​协议解析​​&#xff1a;自动处理 HTTP 请求/响应的底层协议&#xff08;如报文头解析、状态码生成&#xff09;&#xff1b; ​​线程…

为什么企业建站或独立站选用WordPress

与大多数组织相比&#xff0c;企业业务更需要保持可扩展和可靠的网络存在&#xff0c;以保持竞争力。为此&#xff0c;许多大型企业的 IT 领导者历来寻求昂贵的网络解决方案&#xff0c;这些方案需要签订专有支持合同来保证质量。不过&#xff0c;还有另一种方法。WordPress问世…

镜头内常见的马达类型(私人笔记)

① 螺杆式马达 驱动来源&#xff1a;机身内马达。镜头尾部有一个接收“螺杆”的接口&#xff0c;通过机械传动带动镜头对焦组。缺点&#xff1a;慢、吵、不能用于无机身马达的相机。✅ 典型镜头&#xff1a;尼康 AF、AF-D 系列&#xff1b;美能达老镜头。尼康传统的AF镜头通过…

从代码学习深度学习 - 语义分割和数据集 PyTorch版

文章目录 前言什么是语义分割?图像分割和实例分割Pascal VOC2012 语义分割数据集Pascal VOC2012 语义分割数据集介绍基本信息语义分割部分特点数据格式评价指标应用价值数据集获取使用提示辅助工具代码 (`utils_for_huitu.py`)读取数据预处理数据自定义语义分割数据集类读取数…

4G物联网模块实现废气处理全流程数据可视化监控配置

一、项目背景 随着工业化进程的加速&#xff0c;工业废气的排放对环境造成了严重影响&#xff0c;废气处理厂应运而生。然而&#xff0c;废气处理厂中的设备众多且分散&#xff0c;传统的人工巡检和数据记录方式效率低下&#xff0c;难以及时发现问题。为了实现对废气处理设备…

电商平台如何做好DDoS 攻防战?

一、新型 DDoS 攻击技术演进分析 1.1 电商平台面临的四类攻击范式 graph LR A[DDoS攻击] --> B{网络层} A --> C{应用层} B --> D[CLDAP反射攻击<br>峰值达3.5Tbps] B --> E[QUIC协议洪水攻击] C --> F[API CC攻击<br>精准打击抢购接口] C -->…

【计算机视觉】OpenCV实战项目:Athlete-Pose-Detection 运动员姿态检测系统:基于OpenCV的实时运动分析技术

运动员姿态检测系统&#xff1a;基于OpenCV的实时运动分析技术 1. 项目概述1.1 技术背景1.2 项目特点 2. 技术架构与算法原理2.1 系统架构2.2 核心算法2.3 模型选择 3. 项目部署与运行指南3.1 环境准备硬件要求软件依赖 3.2 项目配置3.3 运行项目基本运行模式高级参数 4. 常见问…

为什么要选择七彩喜数字康养平台?加盟后有何优势?

一&#xff0e;七彩喜数字康养平台 1.技术领先性 七彩喜依托“端-网-云-脑”四层技术架构&#xff0c;整合毫米波雷达、AI算法引擎、区块链等前沿技术&#xff0c;解决传统养老的隐私泄露、设备孤岛等痛点。 比如非接触式健康监测系统通过毫米波雷达实现跌倒检测准确率&#…

【计算机视觉】OpenCV实战项目:基于OpenCV的车牌识别系统深度解析

基于OpenCV的车牌识别系统深度解析 1. 项目概述2. 技术原理与算法设计2.1 图像预处理1) 自适应光照补偿2) 边缘增强 2.2 车牌定位1) 颜色空间筛选2) 形态学操作3) 轮廓分析 2.3 字符分割1) 投影分析2) 连通域筛选 2.4 字符识别 3. 实战部署指南3.1 环境配置3.2 项目代码解析 4.…

鸿蒙接入flutter环境变量配置windows-命令行或者手动配置-到项目的创建-运行demo项目

鸿蒙接入flutter环境变量配置 参考官网 下载flutter git clone https://gitcode.com/openharmony-sig/flutter_flutter.git git checkout -b dev origin/dev # 国内镜像 export PUB_HOSTED_URLhttps://pub.flutter-io.cn export FLUTTER_STORAGE_BASE_URLhttps://storage.fl…

Flink CDC—实时数据集成框架

Flink CDC 是一个基于流的数据集成工具&#xff0c;旨在为用户提供一套功能更加全面的编程接口&#xff08;API&#xff09;&#xff0c;它基于数据库日志的 CDC&#xff08;变更数据捕获&#xff09;技术实现了统一的增量和全量数据读取。 该工具使得用户能够以 YAML 配置文件…

微调ModernBERT为大型语言模型打造高效“过滤器”

ModernBERT&#xff08;2024 年 12 月&#xff09;是最近发布的小型语言模型&#xff0c;由 Answer.AI、LightOn 和 HuggingFace 共同开发。它利用了现代优化技术&#xff0c;如用于 8,192 token 上下文窗口的 RoPE 和 GeGLU layers&#xff0c;在保持效率的同时提升性能。jina…

各大编程语言基本语法区别

1:语言特点 函数式语言和面向对象语言的区别:函数式用函数直接进行操作,面向对象用object.method()进行操作;如:len() <=> object.length() C 语言:1)C 语言可以像汇编语言一样对位、字节和地址进行操作;2)有函数原型;3)具有大量的数值类型;4)函数是C语言…

云计算中的虚拟化:成本节省、可扩展性与灾难恢复的完美结合

云计算中虚拟化的 4 大优势 1. 成本效益 从本质上讲&#xff0c;虚拟化最大限度地减少了硬件蔓延。团队可以将多个虚拟机整合到单个物理主机上&#xff0c;而不是为每个工作负载部署单独的服务器。这大大减少了前期硬件投资和持续维护。 结果如何&#xff1f;更低的功耗、更低…

【Java ee初阶】网络原理

TCP协议 1.确认应答 实现可靠传输的核心机制 2.超时重传 实现可靠传输的核心机制 3.连接管理 网络部分最高频的面试题 4.滑动窗口 提高传输效率的机制 5.流量控制 依据接收方的处理能力&#xff0c;限制发送方的发送速度。 6.拥塞控制 依据传输链路的处理能力&#xff0c…

awesome-digital-human本地部署及配置:打造高情绪价值互动指南

在数字化交互的浪潮中&#xff0c;awesome-digital-human-live2d项目为我们打开了本地数字人互动的大门。结合 dify 聊天 api&#xff0c;并借鉴 coze 夸夸机器人的设计思路&#xff0c;能为用户带来充满情绪价值的交互体验。本文将详细介绍其本地部署步骤、dify 配置方法及情绪…

第26节:卷积神经网络(CNN)-数据增强技术(PyTorch)

1. 引言 在深度学习领域,数据增强(Data Augmentation)是提升卷积神经网络(CNN)性能的关键技术之一。通过人为地扩展训练数据集,数据增强能够有效提高模型的泛化能力,防止过拟合,特别是在训练数据有限的情况下。本文将全面介绍PyTorch框架下的数据增强技术,包括基本原理、…

求助求助,重金酬谢

如图&#xff0c;我先在服务器上运行一个 dock 容器&#xff0c;然后用 nohup 命令把 auto_run.py 程序挂起&#xff0c;然后我查了一下是在 12 端口运行的&#xff0c;这时候我关闭命令窗口&#xff0c;我再重新打开运行 docker 容器就找不到挂起的进程了&#xff01;这是为什…