Java集合性能优化面试题

news/2025/2/26 7:40:23

Java集合性能优化面试题

初始化优化

Q1: 如何优化集合的初始化?

java">public class CollectionInitializationExample {
    // 1. 合理设置初始容量
    public void initializationOptimization() {
        // 不好的实践:使用默认容量
        List<String> badList = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            badList.add("item" + i);  // 可能多次扩容
        }
        
        // 好的实践:预设容量
        List<String> goodList = new ArrayList<>(10000);
        for (int i = 0; i < 10000; i++) {
            goodList.add("item" + i);  // 只需一次分配
        }
        
        // HashMap初始化优化
        int expectedSize = 10000;
        float loadFactor = 0.75f;
        int capacity = (int) (expectedSize / loadFactor) + 1;
        Map<String, String> map = new HashMap<>(capacity);
    }
    
    // 2. 批量初始化
    public void batchInitialization() {
        // 使用Arrays.asList
        List<String> list1 = Arrays.asList("A", "B", "C");
        
        // 使用List.of (Java 9+)
        List<String> list2 = List.of("A", "B", "C");
        
        // 使用Set.of (Java 9+)
        Set<String> set = Set.of("A", "B", "C");
        
        // 使用Map.of (Java 9+)
        Map<String, Integer> map = Map.of("A", 1, "B", 2, "C", 3);
    }
}

Q2: 如何避免频繁的扩容和收缩?

java">public class CollectionResizingExample {
    // 1. ArrayList扩容优化
    public void arrayListResizing() {
        // 不好的实践:频繁扩容
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            list.add(i);
        }
        
        // 好的实践:预估大小
        int expectedSize = 100000;
        List<Integer> optimizedList = new ArrayList<>(expectedSize);
        for (int i = 0; i < expectedSize; i++) {
            optimizedList.add(i);
        }
    }
    
    // 2. HashMap扩容优化
    public void hashMapResizing() {
        // 计算最佳初始容量
        public static int calculateHashMapCapacity(int expectedSize) {
            return (int) ((float) expectedSize / 0.75f + 1.0f);
        }
        
        // 应用示例
        int expectedSize = 10000;
        Map<String, String> map = new HashMap<>(calculateHashMapCapacity(expectedSize));
    }
    
    // 3. 避免收缩
    public void avoidShrinking() {
        List<String> list = new ArrayList<>(1000);
        // 填充数据
        for (int i = 0; i < 1000; i++) {
            list.add("item" + i);
        }
        
        // 不好的实践:频繁清空后重用
        list.clear();
        
        // 好的实践:重用已分配的空间
        for (int i = 0; i < list.size(); i++) {
            list.set(i, null);  // 清除引用但保持容量
        }
        list.clear();
    }
}

访问优化

Q3: 如何优化集合的访问性能?

java">public class CollectionAccessOptimization {
    // 1. 选择合适的集合类型
    public void collectionTypeSelection() {
        // 随机访问场景:使用ArrayList
        List<String> arrayList = new ArrayList<>();
        
        // 频繁插入删除场景:使用LinkedList
        List<String> linkedList = new LinkedList<>();
        
        // 需要唯一性和快速查找:使用HashSet
        Set<String> hashSet = new HashSet<>();
        
        // 需要排序:使用TreeSet
        Set<String> treeSet = new TreeSet<>();
    }
    
    // 2. 优化遍历方式
    public void iterationOptimization() {
        List<String> list = new ArrayList<>();
        int size = list.size();
        
        // 不好的实践:每次都调用size()
        for (int i = 0; i < list.size(); i++) {
            // 处理元素
        }
        
        // 好的实践:缓存size
        for (int i = 0; i < size; i++) {
            // 处理元素
        }
        
        // 更好的实践:使用增强for循环
        for (String item : list) {
            // 处理元素
        }
    }
    
    // 3. 使用批量操作
    public void batchOperations() {
        List<String> source = new ArrayList<>();
        List<String> target = new ArrayList<>();
        
        // 不好的实践:逐个添加
        for (String item : source) {
            target.add(item);
        }
        
        // 好的实践:批量添加
        target.addAll(source);
    }
}

并发优化

Q4: 如何优化并发场景下的集合性能?

java">public class ConcurrentCollectionOptimization {
    // 1. 选择合适的并发集合
    public void concurrentCollectionSelection() {
        // 高并发读取场景
        Map<String, String> concurrentMap = new ConcurrentHashMap<>();
        
        // 读多写少场景
        List<String> copyOnWriteList = new CopyOnWriteArrayList<>();
        
        // 生产者-消费者场景
        BlockingQueue<String> blockingQueue = new LinkedBlockingQueue<>();
        
        // 需要并发排序
        Map<String, String> skipListMap = new ConcurrentSkipListMap<>();
    }
    
    // 2. 分段锁优化
    public class CustomSegmentLockMap<K, V> {
        private static final int SEGMENTS = 16;
        private final Map<K, V>[] segments = new HashMap[SEGMENTS];
        private final Object[] locks = new Object[SEGMENTS];
        
        public CustomSegmentLockMap() {
            for (int i = 0; i < SEGMENTS; i++) {
                segments[i] = new HashMap<>();
                locks[i] = new Object();
            }
        }
        
        private int getSegment(K key) {
            return Math.abs(key.hashCode() % SEGMENTS);
        }
        
        public V put(K key, V value) {
            int segment = getSegment(key);
            synchronized (locks[segment]) {
                return segments[segment].put(key, value);
            }
        }
        
        public V get(K key) {
            int segment = getSegment(key);
            synchronized (locks[segment]) {
                return segments[segment].get(key);
            }
        }
    }
    
    // 3. 批量操作优化
    public void batchOperationOptimization() {
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
        
        // 不好的实践:逐个处理
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            if (entry.getValue() > 100) {
                map.put(entry.getKey(), entry.getValue() * 2);
            }
        }
        
        // 好的实践:使用原子操作
        map.forEach((key, value) -> {
            map.compute(key, (k, v) -> v > 100 ? v * 2 : v);
        });
    }
}

内存优化

Q5: 如何优化集合的内存使用?

java">public class CollectionMemoryOptimization {
    // 1. 及时释放不用的引用
    public void referenceManagement() {
        List<Object> list = new ArrayList<>();
        
        // 不好的实践:保留不用的引用
        for (int i = 0; i < 1000; i++) {
            list.add(new Object());
        }
        list.clear();  // 只清除了list,对象仍在内存中
        
        // 好的实践:手动清除引用
        for (int i = 0; i < list.size(); i++) {
            list.set(i, null);  // 清除对象引用
        }
        list.clear();
    }
    
    // 2. 使用紧凑的数据结构
    public void compactDataStructures() {
        // 不好的实践:使用包装类型
        List<Integer> integers = new ArrayList<>();
        
        // 好的实践:使用基本类型数组
        int[] primitiveArray = new int[1000];
        
        // 使用BitSet代替boolean数组
        BitSet bitSet = new BitSet(1000);
        bitSet.set(10);  // 设置第10位为true
        boolean isSet = bitSet.get(10);
    }
    
    // 3. 集合复用
    public class ObjectPool<T> {
        private final Queue<T> pool;
        private final Supplier<T> factory;
        
        public ObjectPool(Supplier<T> factory, int initialSize) {
            this.factory = factory;
            this.pool = new ConcurrentLinkedQueue<>();
            for (int i = 0; i < initialSize; i++) {
                pool.offer(factory.get());
            }
        }
        
        public T borrow() {
            T obj = pool.poll();
            return obj != null ? obj : factory.get();
        }
        
        public void release(T obj) {
            pool.offer(obj);
        }
    }
}

Q6: 如何处理大规模集合数据?

java">public class LargeCollectionHandling {
    // 1. 分批处理
    public void batchProcessing() {
        List<String> largeList = new ArrayList<>();
        int batchSize = 1000;
        
        for (int i = 0; i < largeList.size(); i += batchSize) {
            List<String> batch = largeList.subList(
                i, Math.min(i + batchSize, largeList.size())
            );
            processBatch(batch);
        }
    }
    
    // 2. 流式处理
    public void streamProcessing() {
        List<String> largeList = new ArrayList<>();
        
        // 并行流处理
        largeList.parallelStream()
                .filter(item -> item.length() > 5)
                .map(String::toUpperCase)
                .forEach(this::process);
    }
    
    // 3. 使用外部存储
    public class ExternalStorageList<E> {
        private File storageFile;
        private int size;
        
        public void add(E element) {
            // 写入文件
            try (ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream(storageFile, true))) {
                oos.writeObject(element);
                size++;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        
        public E get(int index) {
            // 从文件读取
            try (ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream(storageFile))) {
                for (int i = 0; i < index; i++) {
                    ois.readObject();
                }
                return (E) ois.readObject();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}

面试关键点

  1. 理解集合初始化的优化方法
  2. 掌握扩容机制的性能影响
  3. 了解不同访问方式的性能特点
  4. 熟悉并发集合的优化策略
  5. 掌握内存使用的优化方法
  6. 理解大规模数据处理方案
  7. 注意性能和内存的平衡
  8. 考虑实际应用场景的需求

http://www.niftyadmin.cn/n/5868318.html

相关文章

Java23种设计模式案例

目录 一、概述 二、创建型模式 (Creational Patterns) 单例模式 (Singleton Pattern) 工厂方法模式 (Factory Method Pattern) 抽象工厂模式 (Abstract Factory Pattern) 建造者模式 (Builder Pattern) 原型模式 (Prototype Pattern) 三、结构型模式 (Structu…

浏览器深度解析:打造极速、安全、个性化的上网新体验

在数字化时代,浏览器作为我们获取信息、娱乐休闲的重要工具,其性能与功能直接影响着我们的上网体验。今天,我将为大家介绍一款备受好评的浏览器——Yandex浏览器,并深入解析其独特功能与优势,帮助大家更好地了解并选择这款上网神器。 一、知名公司背书,开源项目融合 Yan…

@KafkaListener和KafkaTemplate自动装配原理分析

依赖项和配置信息参见另一篇博文KafkaListener的配置使用&#xff0c;这里主要借助源码分析KafkaListener和KafkaTemplate自动装配原理。 1、KafkaAutoConfiguration 源码分析 KafkaAutoConfiguration类自动装配生成了生产者客户端KafkaTemplate的bean和消费者基础ConsumerFa…

03、Hadoop3.x从入门到放弃,第三章:Windows测试环境搭建

Hadoop3.x从入门到放弃&#xff0c;第三章&#xff1a;Windows测试环境搭建 一、Windows测试环境搭建 预先安装好JDK环境&#xff0c;这里不在赘述。 1、下载Hadoop相关文件 Hadoop各版本安装包&#xff1a;https://archive.apache.org/dist/hadoop/common/ 【我选择的是ha…

上证50期权代码是什么?上证50股指期权数据从哪里可以找到?

说起期权代码&#xff0c;其实期权代码是期权合约的唯一标识&#xff0c;通过代码可以准确地识别不同的期权合约&#xff0c;所以在期权交易中&#xff0c;了解期权代码是至关重要的一环。 上证50期权代码结构 上证50ETF期权代码由17位字符组成&#xff0c;例如“10002500C240…

设计模式 简单汇总

设计模式是软件工程中广泛使用的一套解决方案&#xff0c;用于解决常见问题并提高代码的质量。它们分为创建型、结构型和行为型三类&#xff0c;共23种模式。以下是各类别及其常见模式的详细说明&#xff1a; 目录 创建型模式结构型模式行为型模式 创建型模式 这些模式关注对象…

DeepSeek点燃AI大模型战火:编程语言争霸,谁将问鼎“终极武器”王座?

DeepSeek点燃AI大模型战火&#xff1a;编程语言争霸&#xff0c;谁将问鼎“终极武器”王座&#xff1f; 一、DeepSeek&#xff1a;AI大模型竞赛的“导火索” 2023年&#xff0c;中国AI公司深度求索&#xff08;DeepSeek&#xff09;发布DeepSeek-R1大模型&#xff0c;凭借其超…

第七章:消息管理模块

目录 第一节&#xff1a;代码实现 1-1.消息持久化管理思想 1-2.MessageMapper类 1-3.QueueMessage类 1-4.MessageManager 第二节&#xff1a;单元测试 下期预告&#xff1a; 消息管理模块在mqserver下实现。 第一节&#xff1a;代码实现 消息管理首先需要消息类&#xff0c…