Java集合应用案例面试题
缓存实现
Q1: 如何使用LinkedHashMap实现LRU缓存?
java">public class LRUCacheExample {public class LRUCache<K, V> extends LinkedHashMap<K, V> {private final int capacity;public LRUCache(int capacity) {super(capacity, 0.75f, true); this.capacity = capacity;}@Overrideprotected boolean removeEldestEntry(Map.Entry<K, V> eldest) {return size() > capacity;}}public class ConcurrentLRUCache<K, V> {private final LRUCache<K, V> cache;private final ReadWriteLock lock = new ReentrantReadWriteLock();public ConcurrentLRUCache(int capacity) {this.cache = new LRUCache<>(capacity);}public V get(K key) {lock.readLock().lock();try {return cache.get(key);} finally {lock.readLock().unlock();}}public V put(K key, V value) {lock.writeLock().lock();try {return cache.put(key, value);} finally {lock.writeLock().unlock();}}}public void demonstrateCache() {LRUCache<String, String> cache = new LRUCache<>(3);cache.put("1", "one"); cache.put("2", "two"); cache.put("3", "three"); cache.get("1"); cache.put("4", "four"); }
}
消息队列
Q2: 如何实现一个简单的消息队列系统?
java">public class MessageQueueExample {public class Message {private String id;private String content;private long timestamp;private int priority;}public class PriorityMessageQueue {private final PriorityBlockingQueue<Message> queue;public PriorityMessageQueue() {queue = new PriorityBlockingQueue<>(11, (m1, m2) -> Integer.compare(m2.priority, m1.priority));}public void send(Message message) {queue.offer(message);}public Message receive() throws InterruptedException {return queue.take();}}public class TopicMessageSystem {private final ConcurrentHashMap<String, BlockingQueue<Message>> topics;public TopicMessageSystem() {topics = new ConcurrentHashMap<>();}public void createTopic(String topic) {topics.putIfAbsent(topic, new LinkedBlockingQueue<>());}public void publish(String topic, Message message) {BlockingQueue<String> queue = topics.get(topic);if (queue != null) {queue.offer(message);}}public Message subscribe(String topic) throws InterruptedException {BlockingQueue<Message> queue = topics.get(topic);if (queue != null) {return queue.take();}return null;}}
}
数据处理
Q3: 如何使用集合框架处理大数据集?
java">public class DataProcessingExample {public class BatchProcessor<T> {private final List<T> data;private final int batchSize;public BatchProcessor(List<T> data, int batchSize) {this.data = data;this.batchSize = batchSize;}public void process(Consumer<List<T>> consumer) {for (int i = 0; i < data.size(); i += batchSize) {List<T> batch = data.subList(i, Math.min(i + batchSize, data.size()));consumer.accept(batch);}}}public class ParallelProcessor<T> {private final Collection<T> data;public ParallelProcessor(Collection<T> data) {this.data = data;}public <R> List<R> process(Function<T, R> mapper) {return data.parallelStream().map(mapper).collect(Collectors.toList());}public <R> List<R> processWithFilter(Predicate<T> filter, Function<T, R> mapper) {return data.parallelStream().filter(filter).map(mapper).collect(Collectors.toList());}}public void demonstrateProcessing() {List<Integer> numbers = new ArrayList<>();for (int i = 0; i < 1000000; i++) {numbers.add(i);}BatchProcessor<Integer> batchProcessor = new BatchProcessor<>(numbers, 1000);batchProcessor.process(batch -> {batch.forEach(System.out::println);});ParallelProcessor<Integer> parallelProcessor = new ParallelProcessor<>(numbers);List<Integer> result = parallelProcessor.processWithFilter(n -> n % 2 == 0, n -> n * 2 );}
}
数据结构
Q4: 如何实现常见的数据结构?
java">public class DataStructureExample {public class Stack<E> {private final Deque<E> deque = new ArrayDeque<>();public void push(E element) {deque.addFirst(element);}public E pop() {return deque.removeFirst();}public E peek() {return deque.peekFirst();}public boolean isEmpty() {return deque.isEmpty();}}public class Queue<E> {private final Deque<E> deque = new ArrayDeque<>();public void enqueue(E element) {deque.addLast(element);}public E dequeue() {return deque.removeFirst();}public E peek() {return deque.peekFirst();}public boolean isEmpty() {return deque.isEmpty();}}public class PriorityQueue<E> {private final java.util.PriorityQueue<E> queue;public PriorityQueue(Comparator<? super E> comparator) {this.queue = new java.util.PriorityQueue<>(comparator);}public void add(E element) {queue.offer(element);}public E remove() {return queue.poll();}public E peek() {return queue.peek();}}
}
实际应用
Q5: 如何在实际项目中应用集合框架?
java">public class RealWorldExample {public class ShoppingCart {private final Map<Product, Integer> items = new HashMap<>();public void addItem(Product product, int quantity) {items.merge(product, quantity, Integer::sum);}public void removeItem(Product product, int quantity) {items.computeIfPresent(product, (k, v) -> {int newQuantity = v - quantity;return newQuantity <= 0 ? null : newQuantity;});}public double getTotal() {return items.entrySet().stream().mapToDouble(e -> e.getKey().getPrice() * e.getValue()).sum();}}public class TaskScheduler {private final PriorityBlockingQueue<Task> taskQueue;private final ScheduledExecutorService executor;public TaskScheduler(int threadCount) {this.taskQueue = new PriorityBlockingQueue<>();this.executor = Executors.newScheduledThreadPool(threadCount);}public void scheduleTask(Task task) {taskQueue.offer(task);executor.schedule(() -> {Task nextTask = taskQueue.poll();if (nextTask != null) {executeTask(nextTask);}}, task.getDelay(), TimeUnit.MILLISECONDS);}private void executeTask(Task task) {}}public class CacheSystem<K, V> {private final ConcurrentHashMap<K, V> cache;private final ScheduledExecutorService cleaner;public CacheSystem(long cleanupInterval) {this.cache = new ConcurrentHashMap<>();this.cleaner = Executors.newSingleThreadScheduledExecutor();cleaner.scheduleAtFixedRate(this::cleanup,cleanupInterval,cleanupInterval,TimeUnit.MILLISECONDS);}public V get(K key) {return cache.get(key);}public void put(K key, V value) {cache.put(key, value);}private void cleanup() {}}
}
Q6: 如何处理高并发场景下的集合操作?
java">public class ConcurrentOperationExample {public class ConcurrentCounter {private final ConcurrentHashMap<String, AtomicLong> counters;public ConcurrentCounter() {this.counters = new ConcurrentHashMap<>();}public void increment(String key) {counters.computeIfAbsent(key, k -> new AtomicLong()).incrementAndGet();}public long getCount(String key) {AtomicLong counter = counters.get(key);return counter != null ? counter.get() : 0;}}public class RequestLimiter {private final ConcurrentHashMap<String, Deque<Long>> requests;private final int maxRequests;private final long timeWindow;public RequestLimiter(int maxRequests, long timeWindow) {this.requests = new ConcurrentHashMap<>();this.maxRequests = maxRequests;this.timeWindow = timeWindow;}public boolean isAllowed(String key) {long now = System.currentTimeMillis();Deque<Long> times = requests.computeIfAbsent(key, k -> new ConcurrentLinkedDeque<>());while (!times.isEmpty() && times.getFirst() < now - timeWindow) {times.removeFirst();}if (times.size() < maxRequests) {times.addLast(now);return true;}return false;}}public class ConcurrentCache<K, V> {private final ConcurrentHashMap<K, V> cache;private final int maxSize;public ConcurrentCache(int maxSize) {this.cache = new ConcurrentHashMap<>();this.maxSize = maxSize;}public V get(K key, Supplier<V> loader) {return cache.computeIfAbsent(key, k -> {if (cache.size() >= maxSize) {Iterator<Map.Entry<K, V>> it = cache.entrySet().iterator();if (it.hasNext()) {it.next();it.remove();}}return loader.get();});}}
}
面试关键点
- 理解集合框架在实际应用中的角色
- 掌握不同场景下的集合选择
- 了解并发集合的使用场景
- 熟悉数据处理的最佳实践
- 掌握自定义数据结构的实现
- 理解性能优化的方法
- 注意内存使用和垃圾回收
- 考虑线程安全和并发问题