赞
踩
随着机器学习技术的不断发展,人工智能已经开始渗透到各个领域。其中,最引人注目的之一便是 AI 辅助编程工具。在这个领域里,Github Copilot 无疑是一颗闪耀的明星,它可以推荐代码片段、自动生成代码,并提供代码补全和建议等功能。Github Copilot 以插件的方式集成到IDA中,如果你的IDE找不到或无法安装这个插件,请升级软件版本。
目录
前年为应对项目中调用的一个接口限流问题,简单写了一个单机版的滑动窗口计数器。今天想让 Copilot 写一个,输入类名称后,它向我推荐的代码片段,竟然我和之前编写的一模一样。以下分别是以前写的代码片段(完整代码在文末),和 Copilot 推荐的代码片段。
更有趣的是,Copilot 可以不断地学习和改进。细心的读者可能已经发现,前面两幅图中的代码有一点差异,是因为我对自己的代码进行了优化,去掉了第27行的 if。Copilot 也注意到了这一点,并更新自己的模型数据,不久后当我让 Copilot 重新推荐这个代码,并且即使我对自己的代码撤销了该优化,Copilot 仍向我推荐优化后的代码。
最后的main()方法,Copilot 没参考我以前的代码,只根据上下文生成,相比我自己写的要简单些。
- import java.time.Duration;
- import java.time.LocalDateTime;
- import java.util.Arrays;
- import java.util.Random;
- import java.util.concurrent.LinkedBlockingQueue;
- import java.util.concurrent.ThreadPoolExecutor;
- import java.util.concurrent.TimeUnit;
- import java.util.concurrent.atomic.AtomicLong;
-
- /**
- * 滑动窗口计数器
- */
- public class SlidingWindow {
- //滑动窗口元素数组
- private final WindowElement[] windowElements;
- //窗口长度
- private final int windowSize;
- //窗口期
- private final long windowDuration;
- //窗口精度
- private final long windowAccuracy;
- //时间戳
- private long ctm;
-
- //滑动窗口元素
- private class WindowElement {
- public AtomicLong num = new AtomicLong(0);
- public long ts = 0;
- public long incrAndGet() {
- synchronized (this) {
- if (ts < ctm - windowDuration) {
- num.set(1);
- ts = ctm;
- return 1;
- }
- }
- return num.incrementAndGet();
- }
- }
-
- /**
- * 创建一个滑动窗口计数器
- * @param duration
- * @param accuracy
- */
- public SlidingWindow(Duration duration, Duration accuracy) {
- windowDuration = duration.toMillis();
- windowAccuracy = accuracy.toMillis();
- //窗口长度+1,确保窗口元素过期才会被覆盖
- windowSize = (int) Math.ceil(1.0 * duration.toMillis() / accuracy.toMillis()) + 1;
- windowElements = new WindowElement[windowSize];
- for (int i = 0; i < windowSize; i++) {
- windowElements[i] = new WindowElement();
- }
- }
-
- /**
- * 计数+1
- * @return
- */
- public long increment() {
- ctm = System.currentTimeMillis();
- int index = (int) ((ctm / windowAccuracy) % windowSize);
- return windowElements[index].incrAndGet();
- }
-
- /**
- * 计数+1并返回计数总和
- * @return
- */
- public long incrementAndGet() {
- long sum = increment();
- if (windowSize == 1) {
- return sum;
- } else {
- return Arrays.stream(windowElements).filter(e -> e.ts >= ctm - windowDuration).mapToLong(e -> e.num.get()).sum();
- }
- }
-
- /**
- * 返回窗口中所有计数总和
- * @return
- */
- public long getSum() {
- ctm = System.currentTimeMillis();
- return Arrays.stream(windowElements).filter(e -> e.ts >= ctm - windowDuration).mapToLong(e -> e.num.get()).sum();
- }
-
- public static void main(String[] args) {
- SlidingWindow window = new SlidingWindow(Duration.ofMillis(500), Duration.ofMillis(100));
- Random rand = new Random(System.currentTimeMillis());
-
- //创建一个线程,每50ms执行一次,输出当前窗口计数总和
- Thread thread = new Thread(() -> {
- while (true) {
- System.out.println(LocalDateTime.now() + " sum: " + window.getSum());
- try {
- Thread.sleep(50);
- } catch (InterruptedException e) {
- break;
- }
- }
- });
- thread.start();
-
- //创建5个线程,每个线程随机休眠0~100ms,随机执行+1操作
- ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
- for (int t = 0; t < 5; t++) {
- executor.execute(() -> {
- String threadName = Thread.currentThread().getName();
- for (int i = 0; i < 50; i++) {
- String out = LocalDateTime.now() + " [" + threadName + "]";
- if (rand.nextBoolean()) {
- window.increment();
- System.out.println(out + " +1");
- }
- try {
- Thread.sleep(rand.nextInt(100));
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- });
- }
-
- //关闭线程池
- executor.shutdown();
- //等待线程池中所有线程执行完毕
- try {
- executor.awaitTermination(1, TimeUnit.MINUTES);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- //通知线程thread退出
- thread.interrupt();
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。