当前位置: 首页 > article >正文

Java集合性能优化面试题

Java集合性能优化面试题

初始化优化

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

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: 如何避免频繁的扩容和收缩?

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: 如何优化集合的访问性能?

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: 如何优化并发场景下的集合性能?

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: 如何优化集合的内存使用?

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: 如何处理大规模集合数据?

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.kler.cn/a/564107.html

相关文章:

  • 【Linux】CentOS7停服之后配置yum镜像源
  • Ubuntu 下通过 Docker 部署 Nginx 服务器
  • Ubuntu指令(一)
  • 如何优化Redis性能:从理论到实践
  • 苹果折叠屏iPhone突破折痕难题 或将在2026年发布
  • git 常用功能
  • AI快速变现之路,AI视频创作
  • Nacos 服务挂掉时如何恢复配置并访问缓存
  • 机器学习数学基础:31.信度与重测
  • Unity:应用关闭时执行函数方法
  • 如何合理使用Python爬虫按关键字搜索VIP商品:代码示例与实践指南
  • 软件测试八股文,软件测试常见面试合集【附答案】
  • Linux 系统串口配置及权限设置详解
  • 供应链与生产制造L1-L4级高阶流程规划框架(53页PPT)
  • MySQL之Redo Log:确保数据持久性和崩溃恢复
  • 【算法】796. 子矩阵的和
  • PostgreSQL数据库之pg_dump使用
  • java每日精进 2.24 【MQ实际应用场景】
  • Vue 中的 computed 与 watch:深度剖析与实践应用
  • 本地大模型编程实战(22)用langchain实现基于SQL数据构建问答系统(1)