算法题目记录

发布于:2025-07-05 ⋅ 阅读:(22) ⋅ 点赞:(0)

题目一:线程安全的链表

描述:

实现一个线程安全的链表类 ThreadSafeLinkedList,支持以下操作:

  1. add(T element) - 在链表末尾添加元素。
  2. remove(T element) - 移除链表中的指定元素。
  3. contains(T element) - 检查链表中是否包含指定元素。
    要求:
    • 使用 Java 内置的同步机制实现线程安全。
    • 不能使用 Java 内置的同步容器类(如 Collections.synchronizedList 或 CopyOnWriteArrayList)。

实现

package threadsafelist;

import java.util.Objects;

/**
 * 实现一个线程安全的链表类 threadsafelist.ThreadSafeLinkedList,支持以下操作:
 * 1.	add(T element) - 在链表末尾添加元素。
 * 2.	remove(T element) - 移除链表中的指定元素。
 * 3.	contains(T element) - 检查链表中是否包含指定元素。
 * @param <T>
 */
public class ThreadSafeLinkedList<T> {
    private static class Node<T> {
        T value;
        Node<T> next;

        Node(T value) {
            this.value = value;
        }
    }

    private final Node<T> head;
    private final Node<T> tail;

    public ThreadSafeLinkedList() {
        head = new Node<>(null);
        tail = new Node<>(null);
        head.next = tail;
    }

    public synchronized void add(T element) {
        Node<T> newNode = new Node<>(element);
        Node<T> current = head;
        while (current.next != tail) {
            current = current.next;
        }
        current.next = newNode;
        newNode.next = tail;
    }

    public synchronized boolean remove(T element) {
        Node<T> prev = head;
        Node<T> current = head.next;
        while (current != tail) {
            if (Objects.equals(element, current.value)) {
                prev.next = current.next;
                return true;
            }
            prev = current;
            current = current.next;
        }
        return false;
    }

    public synchronized boolean contains(T element) {
        Node<T> current = head.next;
        while (current != tail) {
            if (Objects.equals(element, current.value)) {
                return true;
            }
            current = current.next;
        }
        return false;
    }
}

测试代码

import threadsafelist.ThreadSafeLinkedList;

public class Main {
    public static void main(String[] args) {
        ThreadSafeLinkedList<String> list = new ThreadSafeLinkedList<>();

        // 线程1添加元素
        new Thread(() -> {
            list.add("A");
            list.add("B");
        }).start();

        // 线程2检查元素
        new Thread(() -> {
            System.out.println(list.contains("A")); // 可能输出true或false
        }).start();
    }


}

执行结果

“true”

题目二:自定义注解与反射

描述:

编写一个自定义注解 @LogExecutionTime,并实现一个注解处理器,当标记有该注解的方法被调用时,记录方法的执行时间并输出。
要求:

  1. 创建 @LogExecutionTime 注解。
  2. 编写一个代理类或使用 AOP(如 Spring AOP)来拦截方法调用,记录并输出方法执行时间。
  3. 提供一个示例类和方法,展示注解的实际应用效果。
  4. 需要考虑跨线程透传问题

实现

功能代码如下:

package anotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}

package anotation;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class PerformanceHandler implements InvocationHandler {
    private final Object target;
    private static final ConcurrentMap<String, Long> methodStats = new ConcurrentHashMap<>();
    public PerformanceHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //获取当前时间
        long start = System.currentTimeMillis();
        try {
            return method.invoke(target, args);
        } finally {
            long end = System.currentTimeMillis();
            //计算执行时间
            long executionTime = end - start;

            // 获取方法签名
            String methodSignature = method.getDeclaringClass().getName() + "." + method.getName();

            // 记录当前方法执行时间
            methodStats.put(methodSignature, executionTime);

            // 输出执行时间(支持跨线程)
            System.out.printf("[%s] Method %s executed in %d ms%n", // ms 而不是 ns
                    Thread.currentThread().getName(),
                    methodSignature,
                    executionTime);
        }

    }

    public static Map<String, Long> getMethodStats() {
        return new HashMap<>(methodStats);
    }
}

测试代码如下:

package anotation;

import java.lang.reflect.Proxy;

public class ProxyFactory {
    public static <T> T createProxy(Class<T> interfaceClass, T target) {
        Object proxy = Proxy.newProxyInstance(
                interfaceClass.getClassLoader(),
                new Class<?>[]{interfaceClass},
                new PerformanceHandler(target)
        );

        // 运行时类型检查
        if (interfaceClass.isInstance(proxy)) {
            return interfaceClass.cast(proxy);
        }

        throw new ClassCastException("Generated proxy does not implement interface: " + interfaceClass.getName());
    }
}

package anotation;

public interface ExampleService {
    void processData();
    String fetchData(String key);
}
package anotation;

public class ExampleServiceImpl implements ExampleService{
    @Override
    @LogExecutionTime
    public void processData() {
        try {
            Thread.sleep(500); // 模拟处理耗时
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    @Override
    @LogExecutionTime
    public String fetchData(String key) {
        try {
            Thread.sleep(200); // 模拟网络请求
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return "Data for " + key;
    }
}

package anotation;

public class Main {

    public static void main(String[] args) throws InterruptedException {
        ExampleService service = ProxyFactory.createProxy(ExampleService.class, new ExampleServiceImpl());

        // 主线程调用
        service.processData();

        // 多线程调用
        Thread thread1 = new Thread(() -> service.fetchData("key1"));
        Thread thread2 = new Thread(() -> service.fetchData("key2"));

        thread1.start();
        thread2.start();

        thread1.join();
        thread2.join();

        // 查看统计数据
        System.out.println("\nMethod execution statistics:");
        PerformanceHandler.getMethodStats().forEach((k, v) ->
                System.out.printf("Method %s last time: %d ms%n", k, v));
    }
}

执行结果:

[main] Method anotation.ExampleService.processData executed in 504 ms
[Thread-2] Method anotation.ExampleService.fetchData executed in 213 ms
[Thread-1] Method anotation.ExampleService.fetchData executed in 213 ms
Method execution statistics:
Method anotation.ExampleService.processData last time: 504 ms
Method anotation.ExampleService.fetchData last time: 213 ms

题目三:简化的消息队列

描述

实现一个简化的消息队列类 SimpleMessageQueue,支持以下操作:

  1. send(T message) - 发送消息。
  2. receive() - 接收消息,若队列为空,阻塞直到有消息可接收。
    要求:
    • 使用 java.util.concurrent 包中的工具类来实现。
    • 需要保证 send 和 receive 操作的线程安全。
    • 提供单元测试,验证消息队列的正确性。

实现

功能代码

package simplemessagequeue;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class SimpleMessageQueue<T> {
    private final BlockingQueue<T> queue = new LinkedBlockingQueue<>();

    // 发送消息
    public void send(T message) {
        try {
            queue.put(message);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("Send interrupted", e);
        }
    }

    // 接收消息,若队列为空则阻塞
    public T receive() {
        try {
            return queue.take();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("Receive interrupted", e);
        }
    }
} 

测试代码

package simplemessagequeue;

public class SimpleMessageQueueTest {
    public static void main(String[] args) throws InterruptedException {
        SimpleMessageQueue<String> queue = new SimpleMessageQueue<>();

        // 测试单线程收发
        queue.send("hello");
        assert "hello".equals(queue.receive());

        // 测试多线程收发
        Thread sender = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                queue.send("msg" + i);
            }
        });

        Thread receiver = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                String msg = queue.receive();
                System.out.println("Received: " + msg);
            }
        });

        sender.start();
        receiver.start();
        sender.join();
        receiver.join();

        System.out.println("All tests passed.");
    }
} 

运行结果

Received: hello
Received: msg0
Received: msg1
Received: msg2
Received: msg3
All tests passed.