ChatGPT提示工程,惊艳你的开发

2023-04-1109:01:03人工智能与大数据Comments2,040 views字数 46168阅读模式

什么是提示工程

提示工程(Prompt Engineering)是指在使用自然语言处理(NLP)模型(例如 GPT-4)时,设计和优化输入文本(即提示)的过程。这一过程旨在更有效地引导模型生成所需的输出结果。提示工程的关键在于提高模型的表现,使其更准确、有趣或符合特定上下文要求。提示工程则是人在回路思想在实践中的具体应用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

进行提示工程的要点

在进行提示工程时,需要考虑以下几个方面:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  1. 清晰明确:尽量使提示清晰、明确,以便模型更好地理解输入信息和预期输出。
  2. 上下文和范围:在提示中提供足够的上下文,以便模型能够理解问题的具体背景。同时,限制提示的范围可以减少不相关或过于宽泛的回答。
  3. 问题类型:尝试使用不同的问题类型(例如开放式问题、封闭式问题或多项选择题等),以找出最适合特定场景的提示方式。
  4. 实验与迭代:不断尝试新的提示方式,对生成的回答进行分析,以便找到优化模型表现的最佳方法。
  5. 示例与引导:在提示中包含示例,可以引导模型生成类似的答案。同时,可以在提示中明确指示期望的答案格式或结构。

通过以上方法,可以有效地进行提示工程,以提高自然语言处理模型的性能和准确性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

简单示例

这一小节我们先介绍一些极简的案例,主要是让大家意识到问题的优化过程。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

例子1

问题:告诉我一个故事。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

优化后的问题:请用100-150字,描述一个关于勇敢的骑士和他与巨龙战斗的冒险故事。在这个例子中,优化后的问题提供了更多具体的细节,如故事主题、角色和字数限制,这有助于引导模型生成更符合预期的输出。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

例子2

问题:太阳是什么?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

优化后的问题:简要介绍太阳的成分、结构和在太阳系中的作用。这个例子通过指定信息类型(成分、结构、作用)提供了更明确的上下文,引导模型生成更相关、更具信息价值的答案。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

例子3

问题:如何做蛋炒饭?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

优化后的问题:请列出一份简单蛋炒饭的食材清单和5个步骤的烹饪方法。在这个例子中,优化后的问题明确了期望的答案格式(食材清单和烹饪步骤),使得模型更容易生成符合要求的输出。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

例子4

问题:世界上最高的山是什么?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

优化后的问题:世界上最高的山是什么,它的海拔高度是多少?通过在问题中添加具体指标(海拔高度),可以引导模型生成更全面、更具信息价值的答案。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

基础:将GPT作为老师

场景

只要你学的东西不是21年9月后太新的东西,我认为你都应该将GPT作为自己强大的在线导师。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第一轮提示

提示

Spring Boot 有好多的Controller注解,他们都有什么区别。大多数情况下,应该用什么注解文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

Spring Boot中的Controller注解主要用于定义RESTful API和处理HTTP请求。以下是一些常见的Controller注解及其区别:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  1. @Controller:这是一个基本的Spring MVC注解,用于将一个类标记为Controller。它会将类识别为一个组件,由Spring进行管理。当使用@Controller注解时,需要配合@ResponseBody注解,才能将方法的返回值作为HTTP响应的正文返回。否则,返回值将被视为视图名称。
  2. @RestController:这个注解是@Controller和@ResponseBody的组合。它用于创建RESTful web服务,将类标记为Controller,并将所有方法的返回值默认作为HTTP响应的正文返回。对于大多数RESTful API场景,推荐使用@RestController。
  3. @RequestMapping:这是一个通用的映射注解,可以用在类或方法上。它可以指定一个URL路径,以及支持的HTTP请求方法(GET、POST、PUT、DELETE等)。当使用在类上时,它定义了一个基本的URL路径,该类中的所有方法都会继承这个路径。
  4. @GetMapping、@PostMapping、@PutMapping、@DeleteMapping:这些注解分别对应@RequestMapping中的不同HTTP请求方法。它们可以简化代码,使其更具可读性。例如,@GetMapping("/path")等效于@RequestMapping(value = "/path", method = RequestMethod.GET)。

在大多数情况下,对于RESTful API,推荐使用@RestController注解。对于需要返回视图的情况,可以使用@Controller注解。在处理具体的HTTP请求时,推荐使用@GetMapping、@PostMapping、@PutMapping和@DeleteMapping这些专门针对不同HTTP方法的注解,以提高代码的可读性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

赞!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

基础:用ChatGPT处理面试题

场景

学生出去面试收集回来的面试题,我们都可以借助GPT4来给出生成答案。有的时候可能需要我们介入补充一下上下文,我认为这可以让我们的面试题库更加完备。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

下面是一个前端学生出去面试整理到的面试题:做一个抽奖系统,有ABCD四种奖品可以提供,A概率为50%,B概率为20%,C的概率为20%,D的概率为10%,请写出实现思路文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第一轮提示:

提示

做一个抽奖系统,有ABCD四种奖品可以提供,A概率为50%,B概率为20%,C的概率为20%,D的概率为10%,请写出实现思路文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

要实现这样一个抽奖系统,我们可以采用以下思路:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  1. 为每种奖品分配一个概率范围。例如,A奖品的范围是0-50%,B奖品的范围是50-70%,C奖品的范围是70-90%,D奖品的范围是90-100%。
  2. 生成一个0到1之间的随机数。可以使用JavaScript中的**Math.random()**函数来实现这一点。
  3. 根据生成的随机数判断落入哪个概率范围,从而确定对应的奖品。

下面是一个简单的JavaScript实现文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

function getPrize() {
  const randomNumber = Math.random(); // 生成0到1之间的随机数

  if (randomNumber < 0.5) { // 0-50%的概率
    return 'A';
  } else if (randomNumber < 0.7) { // 50-70%的概率
    return 'B';
  } else if (randomNumber < 0.9) { // 70-90%的概率
    return 'C';
  } else { // 90-100%的概率
    return 'D';
  }
}

// 示例
console.log(getPrize());

这个简单的实现可以用于满足基本的抽奖需求。您可以根据实际应用场景对其进行优化和扩展。例如,可以将奖品及其概率存储在一个数组或对象中,以便于在添加或删除奖品时更容易地调整概率。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

给的答案很赞,个人认为我们的面试大保健一律可以通过GPT4来做一次系统优化。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

基础:完成单元性开发工作(Java)

场景

基于GPT4.0的ChatGPT其实已经有了非常强的编写代码能力。或许你认为上一节的教程可能是某本书或者某个代码仓库中的教学代码。那么,从这一节开始,你将会认识到,ChatGPT可以理解并创造新的代码!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

接下来,我们有这样的一个需求:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

我们有一项功能是调用了多个平台提供的api实现的。调用多个平台的api给我们带来了数据格式不统一的烦恼,比如我们的时间戳就乱掉了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

现在已知,各平台会返回下面几种时间戳文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  1. timestamp_millis
  2. yyyy/MM/dd HH:mm:ss.SSS
  3. yyyy-MM-dd HH:mm:ss.SSS
  4. yyyyMMddHHmmss
  5. yyyy-MM-dd'T'HH:mm:ss'+0800'
  6. yyyy-MM-dd'T'HH:mm:ss'Z'
  7. yyyyMMdd'T'HHmmss

现在,我们要写一个静态方法,来把上面的各种时间表达统一成yyyy-MM-dd HH:mm:ss文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第一轮提示

提示

我们有一项功能是调用了多个平台提供的api实现的。调用多个平台的api给我们带来了数据格式不统一的烦恼,比如我们的时间戳就乱掉了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

现在已知,各平台会返回下面几种时间戳文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  1. timestamp_millis
  2. yyyy/MM/dd HH:mm:ss.SSS
  3. yyyy-MM-dd HH:mm:ss.SSS
  4. yyyyMMddHHmmss
  5. yyyy-MM-dd'T'HH:mm:ss'+0800'
  6. yyyy-MM-dd'T'HH:mm:ss'Z'
  7. yyyyMMdd'T'HHmmss

现在,我们要用java写一个静态方法,来把上面的各种时间表达统一成yyyy-MM-dd HH:mm:ss请注意,最后你要统一成我所在的时区(东八区)的服务器时间。上面的日期时间我已核实,如果没有写明日期时间的,那就是东八区的日期时间。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

为了实现这个功能,我们可以使用Java的DateTimeFormatterZonedDateTime类来处理不同格式的时间戳。下面是一个示例:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.List;

public class TimestampConverter {

    private static final DateTimeFormatter TARGET_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final List FORMATTERS = Arrays.asList(
            DateTimeFormatter.ofPattern("x"),
            DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS"),
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"),
            DateTimeFormatter.ofPattern("yyyyMMddHHmmss"),
            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"),
            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").withZone(ZoneId.of("UTC")),
            DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss")
    );

    public static String convertTimestamp(String input) {
        for (DateTimeFormatter formatter : FORMATTERS) {
            try {
                ZonedDateTime zonedDateTime = ZonedDateTime.parse(input, formatter);
                zonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("Asia/Shanghai"));
                return zonedDateTime.format(TARGET_FORMATTER);
            } catch (DateTimeParseException e) {
                // Ignore and try the next formatter
            }
        }
        throw new IllegalArgumentException("Unsupported timestamp format: " + input);
    }

    public static void main(String[] args) {
        String[] timestamps = {
                "1648085578123",
                "2023/03/24 13:52:58.123",
                "2023-03-24 13:52:58.123",
                "20230324135258",
                "2023-03-24T13:52:58+0800",
                "2023-03-24T05:52:58Z",
                "20230324T135258"
        };

        for (String timestamp : timestamps) {
            System.out.println("Original: " + timestamp);
            System.out.println("Converted: " + convertTimestamp(timestamp));
            System.out.println();
        }
    }
}

这个示例中,我们创建了一个名为TimestampConverter的类,并在其中定义了一个名为convertTimestamp的静态方法。该方法接受一个字符串作为输入,并尝试使用FORMATTERS列表中定义的各种日期时间格式对其进行解析。一旦解析成功,我们将解析到的ZonedDateTime实例转换为目标时区(东八区)并格式化为目标格式(yyyy-MM-dd HH:mm:ss)。如果所有的格式都无法解析输入的字符串,convertTimestamp方法将抛出一个IllegalArgumentExceptionmain方法中的测试数据演示了如何将提供的不同格式的时间戳转换为目标格式。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

这个任务并不难,只是很繁琐。我们可以交给ChatGPT来做,但是作为开发者,你必须对ChatGPT生成的内容做质量上的把控。现在,我们可以看到,这个代码逻辑大致上是对的,而且main方法里给的测试用例也确实符合我们给出的案例。但是,代码对不对只有跑起来才知道。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

经过测试,上面这段代码运行起来会报错:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

ChatGPT提示工程,惊艳你的开发

现在,其实ChatGPT已经帮你完成了大部分工作,如果你有把握,你可以选择自己修复这个bug。另外,我们也可以让ChatGPT修复自己,只需告诉ChatGPT他出错了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第二轮提示

提示

你刚才的代码运行报错文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

Exception in thread "main" java.lang.IllegalArgumentException: Unsupported timestamp format: 1648085578123 

at com.atguigu.jiu.convertTimestamp(jiu.java:33) 

at com.atguigu.jiu.main(jiu.java:49)

抱歉,我犯了一个错误。在解析毫秒时间戳时,我使用了错误的方法。我们需要将毫秒时间戳先转换为Instant,然后转换为ZonedDateTime。请参考以下修复后的代码:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

mport java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.List;

public class TimestampConverter {

    private static final DateTimeFormatter TARGET_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final List FORMATTERS = Arrays.asList(
            DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS"),
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"),
            DateTimeFormatter.ofPattern("yyyyMMddHHmmss"),
            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"),
            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").withZone(ZoneId.of("UTC")),
            DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss")
    );

    public static String convertTimestamp(String input) {
        try {
            long millis = Long.parseLong(input);
            Instant instant = Instant.ofEpochMilli(millis);
            ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("Asia/Shanghai"));
            return zonedDateTime.format(TARGET_FORMATTER);
        } catch (NumberFormatException e) {
            // Not a valid millis timestamp, continue with other formatters
        }

        for (DateTimeFormatter formatter : FORMATTERS) {
            try {
                ZonedDateTime zonedDateTime = ZonedDateTime.parse(input, formatter);
                zonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("Asia/Shanghai"));
                return zonedDateTime.format(TARGET_FORMATTER);
            } catch (DateTimeParseException e) {
                // Ignore and try the next formatter
            }
        }
        throw new IllegalArgumentException("Unsupported timestamp format: " + input);
    }

    public static void main(String[] args) {
        String[] timestamps = {
                "1648085578123",
                "2023/03/24 13:52:58.123",
                "2023-03-24 13:52:58.123",
                "20230324135258",
                "2023-03-24T13:52:58+0800",
                "2023-03-24T05:52:58Z",
                "20230324T135258"
        };

        for (String timestamp : timestamps) {
            System.out.println("Original: " + timestamp);
            System.out.println("Converted: " + convertTimestamp(timestamp));
            System.out.println();
        }
    }
}

在此修复后的版本中,我们首先尝试将输入字符串解析为一个长整型数字,如果成功,则将其视为毫秒时间戳,并将其转换为Instant。然后,我们将Instant转换为ZonedDateTime并格式化为目标格式。如果解析长整型数字失败,我们将继续尝试其他日期时间格式。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

这段程序又报了新的异常,运行到第2个测试用例时,抛出了时间戳格式异常。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

ChatGPT提示工程,惊艳你的开发

第三轮提示

提示

下面是你代码的运行结果,它又报错了文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

Original: 1648085578123 Converted: 2022-03-24 09:32:58 Original: 2023/03/24 13:52:58.123 Exception in thread "main" java.lang.IllegalArgumentException: Unsupported timestamp format: 2023/03/24 13:52:58.123 

at com.atguigu.TimestampConverter.convertTimestamp(TimestampConverter.java:43) 

at com.atguigu.TimestampConverter.main(TimestampConverter.java:59)

歉再次给您带来麻烦。我发现问题出在日期时间格式上。由于Java的日期时间解析对于毫秒部分的格式化有一定的限制,我们需要稍微调整一下格式。请使用下面的修复后的代码:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.List;

public class TimestampConverter {

    private static final DateTimeFormatter TARGET_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final List FORMATTERS = Arrays.asList(
            DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS").withZone(ZoneId.of("Asia/Shanghai")),
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").withZone(ZoneId.of("Asia/Shanghai")),
            DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.of("Asia/Shanghai")),
            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ").withZone(ZoneId.of("Asia/Shanghai")),
            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").withZone(ZoneId.of("UTC")),
            DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss").withZone(ZoneId.of("Asia/Shanghai"))
    );

    public static String convertTimestamp(String input) {
        try {
            long millis = Long.parseLong(input);
            Instant instant = Instant.ofEpochMilli(millis);
            ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("Asia/Shanghai"));
            return zonedDateTime.format(TARGET_FORMATTER);
        } catch (NumberFormatException e) {
            // Not a valid millis timestamp, continue with other formatters
        }

        for (DateTimeFormatter formatter : FORMATTERS) {
            try {
                ZonedDateTime zonedDateTime = ZonedDateTime.parse(input, formatter);
                zonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("Asia/Shanghai"));
                return zonedDateTime.format(TARGET_FORMATTER);
            } catch (DateTimeParseException e) {
                // Ignore and try the next formatter
            }
        }
        throw new IllegalArgumentException("Unsupported timestamp format: " + input);
    }

    public static void main(String[] args) {
        String[] timestamps = {
                "1648085578123",
                "2023/03/24 13:52:58.123",
                "2023-03-24 13:52:58.123",
                "20230324135258",
                "2023-03-24T13:52:58+0800",
                "2023-03-24T05:52:58Z",
                "20230324T135258"
        };

        for (String timestamp : timestamps) {
            System.out.println("Original: " + timestamp);
            System.out.println("Converted: " + convertTimestamp(timestamp));
            System.out.println();
        }
    }
}

这次我为每个日期时间格式提供了时区信息。这样在解析时间时,我们就不会遇到解析异常了。请尝试运行此修复后的代码。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

经过测试,这段代码已经可以成功运行了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

ChatGPT提示工程,惊艳你的开发

然而这样一个需求,从读懂,到写完再到测试,前后也不超过10分钟。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

小结:记得“人在回路”

还记得“人在回路”吗,在这个人机协同的系统中,任务如果没有成功完成,人也应当承担一半责任。记住人在这个系统中要扮演的引导性角色。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

下面,让ChatGPT总结一下我们在刚才的过程中起到了怎样的作用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

ChatGPT提示工程,惊艳你的开发

基础:完成单元性开发工作(前端)

需求

下面是学生收集的公司(滴滴)笔试题,前端笔试看上去会让面试者写一些单元性的功能。比如下面这个题目:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

ChatGPT提示工程,惊艳你的开发

这种场景也非常适合使用ChatGPT来解决。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第一轮提示

提示

帮我用Javascript提供一个Cache方法,Cache缓存最近一天访问次数最多的10条数据文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  • cache中只保留最多十条数据,const cache = new Cache({countLimit:10})
  • 每条数据在设置的时候通过key标识唯一,cache.set('my-cache-key',{id:'xxx',name:'Hello'})
  • 通过缓存的key访问数据:cache.get('my-cache-key')
  • 如果设置新的key时,cache中已经缓存了10条不一样的key,需要删除一条数据,删除的逻辑是:删除最近一天通过get访问次数最少的key

以下是一个使用JavaScript实现的简单Cache类,满足您的要求:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

class Cache {
  constructor({ countLimit }) {
    this.countLimit = countLimit;
    this.data = new Map();
    this.accessCounter = new Map();
  }

  set(key, value) {
    if (this.data.size >= this.countLimit) {
      this.evictLeastAccessed();
    }
    this.data.set(key, value);
    this.accessCounter.set(key, 0);
  }

  get(key) {
    const value = this.data.get(key);
    if (value !== undefined) {
      this.accessCounter.set(key, this.accessCounter.get(key) + 1);
    }
    return value;
  }

  evictLeastAccessed() {
    let minKey, minValue = Infinity;
    for (const [key, value] of this.accessCounter.entries()) {
      if (value < minValue) {
        minKey = key;
        minValue = value;
      }
    }
    if (minKey !== undefined) {
      this.data.delete(minKey);
      this.accessCounter.delete(minKey);
    }
  }
}

const cache = new Cache({ countLimit: 10 });
cache.set('my-cache-key', { id: 'xxx', name: 'Hello' });
console.log(cache.get('my-cache-key'));

这个Cache类包含一个构造函数,用于设置缓存大小的限制。它使用两个Map对象来存储数据和访问计数。set方法用于向缓存中添加数据,get方法用于从缓存中获取数据并更新访问计数。evictLeastAccessed方法用于在缓存满时删除最近一天访问次数最少的缓存项。请注意,这个简单的实现没有考虑时间限制。如果您需要在实际应用中使用这个功能,您可以根据需要对其进行扩展和优化。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

现在ChatGPT已经帮我们生成了一段代码,只不过这个代码比较长,可读性并不是非常友好,现在我们可以要求ChatGPT为这段代码补上注释。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第二轮提示

提示

你刚才写的Cache类代码,可以加上注释吗文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

当然可以,下面是带有注释的Cache类代码:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

class Cache {
  // 构造函数接收一个包含countLimit属性的对象,用于设置缓存大小
  constructor({ countLimit }) {
    this.countLimit = countLimit;
    this.data = new Map(); // 用于存储缓存数据的Map对象
    this.accessCounter = new Map(); // 用于存储每个缓存项的访问计数的Map对象
  }

  // set方法用于向缓存中添加数据
  set(key, value) {
    // 如果缓存已满,移除访问次数最少的项
    if (this.data.size >= this.countLimit) {
      this.evictLeastAccessed();
    }
    // 将数据添加到缓存,并将访问计数设置为0
    this.data.set(key, value);
    this.accessCounter.set(key, 0);
  }

  // get方法用于从缓存中获取数据,并更新访问计数
  get(key) {
    const value = this.data.get(key);
    if (value !== undefined) {
      this.accessCounter.set(key, this.accessCounter.get(key) + 1);
    }
    return value;
  }

  // evictLeastAccessed方法用于在缓存满时删除访问次数最少的项
  evictLeastAccessed() {
    let minKey, minValue = Infinity;
    // 遍历accessCounter找到访问次数最少的项
    for (const [key, value] of this.accessCounter.entries()) {
      if (value < minValue) {
        minKey = key;
        minValue = value;
      }
    }
    // 从data和accessCounter中删除该项
    if (minKey !== undefined) {
      this.data.delete(minKey);
      this.accessCounter.delete(minKey);
    }
  }
}

const cache = new Cache({ countLimit: 10 });
cache.set('my-cache-key', { id: 'xxx', name: 'Hello' });
console.log(cache.get('my-cache-key'));

我已经在代码中添加了对类及其方法的注释,希望这能帮助您更好地理解代码的功能。如果您有任何疑问或需要进一步解释,请随时告诉我。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

现在,加上注释的代码可读性更好的。不过我们可以看到,这个代码确实没考虑时间,我们会向刚才题目里的需求,有一个地方确实不合理,比如cache已经缓存了10条不一样的key就要删除一条数据,删除的逻辑是删除最近一天通过get访问次数最少的key。那么最终我决定对这段代码进行测试,如果没什么问题,就直接交付。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第三轮提示

提示

很好,请帮我写一些测试用例文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

以下是一些针对前面提供的Cache类的简单测试用例:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

function testCache() {
  const cache = new Cache({ countLimit: 3 });

  cache.set('key1', 'value1');
  cache.set('key2', 'value2');
  cache.set('key3', 'value3');

  console.log('Test 1:', cache.get('key1') === 'value1' ? 'PASSED' : 'FAILED');
  console.log('Test 2:', cache.get('key2') === 'value2' ? 'PASSED' : 'FAILED');
  console.log('Test 3:', cache.get('key3') === 'value3' ? 'PASSED' : 'FAILED');

  cache.set('key4', 'value4');
  
  console.log('Test 4:', cache.get('key1') === undefined ? 'PASSED' : 'FAILED');
  console.log('Test 5:', cache.get('key4') === 'value4' ? 'PASSED' : 'FAILED');

  cache.get('key2');
  cache.get('key2');
  cache.set('key5', 'value5');
  
  console.log('Test 6:', cache.get('key3') === undefined ? 'PASSED' : 'FAILED');
  console.log('Test 7:', cache.get('key5') === 'value5' ? 'PASSED' : 'FAILED');
}

testCache();

这些测试用例主要包括以下几个方面:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  1. 向缓存中添加和获取数据。
  2. 当缓存已满时,添加新数据会导致访问次数最少的数据被删除。
  3. 访问计数的更新。

这些测试用例可以帮助您验证Cache类的基本功能是否正确。您可以根据需要扩展和修改这些测试用例以满足您的需求文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

可以看到这个测试用例也非常完备,最终这段代码应该是可以直接通过笔试的。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

基础:作为一名DBA

场景

数据库做简单的增删改查很简单,但是随着企业要搞数字化,项目中的分析性SQL往往越来越多。SQL这类声明式语言通常无法在编写时进行调试,而且这类语言的设计通常会让注释变得很不方便。这样,分析性SQL的可读性就会变得很差。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

现在,我们就有这样一个SQL等着我们去读。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

SELECT 
  two_day_rate, 
  seven_day_rate 
from 
  (
    SELECT 
      two_day_rate 
    from 
      (
        SELECT 
          id, 
          rk, 
          `date`, 
          date1, 
          rk2, 
          max_login, 
          add_money, 
          modify_money, 
          sum(
            if(modify_money is not null, 1, 0)
          )/ sum(
            if(add_money is not null, 1, 0)
          ) two_day_rate 
        from 
          (
            SELECT 
              id, 
              rk, 
              `date`, 
              date1, 
              rk2, 
              max_login, 
              add_money, 
              if(rk2 = max_login, null, add_money) modify_money 
            from 
              (
                SELECT 
                  tt1.id, 
                  rk, 
                  tt1.`date`, 
                  date1, 
                  rk2, 
                  max_login, 
                  add_money 
                from 
                  (
                    SELECT 
                      id, 
                      rk, 
                      `date`, 
                      date1, 
                      rk2, 
                      max_login 
                    from 
                      (
                        SELECT 
                          id, 
                          rk, 
                          `date`, 
                          date1, 
                          rk2, 
                          max(rk2) over(partition by id, date1) max_login 
                        from 
                          (
                            SELECT 
                              id, 
                              rk, 
                              `date`, 
                              date1, 
                              ROW_NUMBER() over (partition by id, date1) rk2 
                            FROM 
                              (
                                SELECT 
                                  id, 
                                  rk, 
                                  `date`, 
                                  DATE_SUB(`date`, INTERVAL rk day) date1 
                                from 
                                  (
                                    SELECT 
                                      id, 
                                      `date`, 
                                      ROW_NUMBER() over (
                                        PARTITION by id 
                                        ORDER BY 
                                          `date`
                                      ) rk 
                                    FROM 
                                      demo3
                                  ) t1
                              ) t2
                          ) t3
                      ) t4
                  ) tt1 
                  LEFT JOIN demo3_red dr on tt1.id = dr.id 
                  and tt1.`date` = dr.`date`
              ) tt2
          ) tt3
      ) tt4
  ) ttt1 
  join (
    SELECT 
      seven_day_rate 
    from 
      (
        SELECT 
          id, 
          rk, 
          `date`, 
          date1, 
          rk2, 
          max_login, 
          add_money, 
          modify_money, 
          modify_sev_money, 
          sum(
            IF(modify_sev_money is not null, 1, 0)
          ) / sum(
            if(add_money is not null, 1, 0)
          ) seven_day_rate 
        from 
          (
            SELECT 
              id, 
              rk, 
              `date`, 
              date1, 
              rk2, 
              max_login, 
              add_money, 
              modify_money, 
              if(
                max_login - rk2 & gt;= 6, 
                modify_money, 
                null
              ) modify_sev_money 
            from 
              (
                SELECT 
                  id, 
                  rk, 
                  `date`, 
                  date1, 
                  rk2, 
                  max_login, 
                  add_money, 
                  if(rk2 = max_login, null, add_money) modify_money 
                from 
                  (
                    SELECT 
                      tt1.id, 
                      rk, 
                      tt1.`date`, 
                      date1, 
                      rk2, 
                      max_login, 
                      add_money 
                    from 
                      (
                        SELECT 
                          id, 
                          rk, 
                          `date`, 
                          date1, 
                          rk2, 
                          max_login 
                        from 
                          (
                            SELECT 
                              id, 
                              rk, 
                              `date`, 
                              date1, 
                              rk2, 
                              max(rk2) over(partition by id, date1) max_login 
                            from 
                              (
                                SELECT 
                                  id, 
                                  rk, 
                                  `date`, 
                                  date1, 
                                  ROW_NUMBER() over (partition by id, date1) rk2 
                                FROM 
                                  (
                                    SELECT 
                                      id, 
                                      rk, 
                                      `date`, 
                                      DATE_SUB(`date`, INTERVAL rk day) date1 
                                    from 
                                      (
                                        SELECT 
                                          id, 
                                          `date`, 
                                          ROW_NUMBER() over (
                                            PARTITION by id 
                                            ORDER BY 
                                              `date`
                                          ) rk 
                                        FROM 
                                          demo3
                                      ) t1
                                  ) t2
                              ) t3
                          ) t4
                      ) tt1 
                      LEFT JOIN demo3_red dr on tt1.id = dr.id 
                      and tt1.`date` = dr.`date`
                  ) tt2
              ) tt3
          ) tt4
      ) tt5
  ) ttt2

第一轮提示

提示

下面是一个HQL。能帮我说一下它干了什么事吗,还有能简化的地方吗文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

SELECT 
  two_day_rate, 
  seven_day_rate 
from 
  (
    SELECT 
      two_day_rate 
    from 
      (
        SELECT 
          id, 
          rk, 
          `date`, 
          date1, 
          rk2, 
          max_login, 
          add_money, 
          modify_money, 
          sum(
            if(modify_money is not null, 1, 0)
          )/ sum(
            if(add_money is not null, 1, 0)
          ) two_day_rate 
        from 
          (
            SELECT 
              id, 
              rk, 
              `date`, 
              date1, 
              rk2, 
              max_login, 
              add_money, 
              if(rk2 = max_login, null, add_money) modify_money 
            from 
              (
                SELECT 
                  tt1.id, 
                  rk, 
                  tt1.`date`, 
                  date1, 
                  rk2, 
                  max_login, 
                  add_money 
                from 
                  (
                    SELECT 
                      id, 
                      rk, 
                      `date`, 
                      date1, 
                      rk2, 
                      max_login 
                    from 
                      (
                        SELECT 
                          id, 
                          rk, 
                          `date`, 
                          date1, 
                          rk2, 
                          max(rk2) over(partition by id, date1) max_login 
                        from 
                          (
                            SELECT 
                              id, 
                              rk, 
                              `date`, 
                              date1, 
                              ROW_NUMBER() over (partition by id, date1) rk2 
                            FROM 
                              (
                                SELECT 
                                  id, 
                                  rk, 
                                  `date`, 
                                  DATE_SUB(`date`, INTERVAL rk day) date1 
                                from 
                                  (
                                    SELECT 
                                      id, 
                                      `date`, 
                                      ROW_NUMBER() over (
                                        PARTITION by id 
                                        ORDER BY 
                                          `date`
                                      ) rk 
                                    FROM 
                                      demo3
                                  ) t1
                              ) t2
                          ) t3
                      ) t4
                  ) tt1 
                  LEFT JOIN demo3_red dr on tt1.id = dr.id 
                  and tt1.`date` = dr.`date`
              ) tt2
          ) tt3
      ) tt4
  ) ttt1 
  join (
    SELECT 
      seven_day_rate 
    from 
      (
        SELECT 
          id, 
          rk, 
          `date`, 
          date1, 
          rk2, 
          max_login, 
          add_money, 
          modify_money, 
          modify_sev_money, 
          sum(
            IF(modify_sev_money is not null, 1, 0)
          ) / sum(
            if(add_money is not null, 1, 0)
          ) seven_day_rate 
        from 
          (
            SELECT 
              id, 
              rk, 
              `date`, 
              date1, 
              rk2, 
              max_login, 
              add_money, 
              modify_money, 
              if(
                max_login - rk2 & gt;= 6, 
                modify_money, 
                null
              ) modify_sev_money 
            from 
              (
                SELECT 
                  id, 
                  rk, 
                  `date`, 
                  date1, 
                  rk2, 
                  max_login, 
                  add_money, 
                  if(rk2 = max_login, null, add_money) modify_money 
                from 
                  (
                    SELECT 
                      tt1.id, 
                      rk, 
                      tt1.`date`, 
                      date1, 
                      rk2, 
                      max_login, 
                      add_money 
                    from 
                      (
                        SELECT 
                          id, 
                          rk, 
                          `date`, 
                          date1, 
                          rk2, 
                          max_login 
                        from 
                          (
                            SELECT 
                              id, 
                              rk, 
                              `date`, 
                              date1, 
                              rk2, 
                              max(rk2) over(partition by id, date1) max_login 
                            from 
                              (
                                SELECT 
                                  id, 
                                  rk, 
                                  `date`, 
                                  date1, 
                                  ROW_NUMBER() over (partition by id, date1) rk2 
                                FROM 
                                  (
                                    SELECT 
                                      id, 
                                      rk, 
                                      `date`, 
                                      DATE_SUB(`date`, INTERVAL rk day) date1 
                                    from 
                                      (
                                        SELECT 
                                          id, 
                                          `date`, 
                                          ROW_NUMBER() over (
                                            PARTITION by id 
                                            ORDER BY 
                                              `date`
                                          ) rk 
                                        FROM 
                                          demo3
                                      ) t1
                                  ) t2
                              ) t3
                          ) t4
                      ) tt1 
                      LEFT JOIN demo3_red dr on tt1.id = dr.id 
                      and tt1.`date` = dr.`date`
                  ) tt2
              ) tt3
          ) tt4
      ) tt5
  ) ttt2

这个HQL查询包含了两个子查询。首先,我将逐步解释它们各自的作用,然后描述它们如何组合在一起。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第一个子查询计算了two_day_rate,即每个id在不同date1的modify_money(条件:rk2不等于max_login)与add_money的非空条目之和的比率。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第二个子查询计算了seven_day_rate,即每个id在不同date1的modify_sev_money(条件:max_login-rk2大于等于6)与add_money的非空条目之和的比率。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

这两个子查询的结构非常相似。它们都包含了以下几个操作:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  1. 计算每个id和date的行号rk。
  2. 使用DATE_SUB函数创建一个新列date1,该列是date减去行号rk的结果。
  3. 对每个id和date1,计算新的行号rk2。
  4. 计算每个id和date1的max_login,即rk2的最大值。
  5. 在demo3表与demo3_red表之间执行左连接。
  6. 计算modify_money(第一个子查询)和modify_sev_money(第二个子查询)。
  7. 计算two_day_rate和seven_day_rate。

最后,这个HQL将这两个子查询的结果连接在一起,返回two_day_rate和seven_day_rate。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

关于简化:这个查询的主要问题是它的冗余性。许多操作在两个子查询中都执行了。你可以尝试将这些操作合并到一个子查询中,然后使用聚合函数SUM和IF计算two_day_rate和seven_day_rate。这将使查询更简洁、更易于阅读。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

ChatGPT已经帮我们解释了这个HIVE SQL的分析逻辑,这是一个200行的SQL,人要读上半天,但是对于ChatGPT来说只需1分钟。这种情况下,我一般会要求GPT把SQL优化一版,然后拿去测一下执行结果和原先的是否一致。如果能保持一致,就用新的可读性更好的优GPT优化出来的SQL。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第二轮提示

提示

请帮我写一个更简单的,谢谢文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

SELECT 
    id, date1,
    SUM(IF(modify_money IS NOT NULL, 1, 0)) / SUM(IF(add_money IS NOT NULL, 1, 0)) AS two_day_rate,
    SUM(IF(modify_sev_money IS NOT NULL, 1, 0)) / SUM(IF(add_money IS NOT NULL, 1, 0)) AS seven_day_rate
FROM (
    SELECT 
        tt1.id, tt1.`date`, date1, rk2, max_login, add_money,
        IF(rk2 = max_login, NULL, add_money) AS modify_money,
        IF(max_login - rk2 >= 6, add_money, NULL) AS modify_sev_money
    FROM (
        SELECT
            id, `date`, date1, rk2,
            MAX(rk2) OVER (PARTITION BY id, date1) AS max_login
        FROM (
            SELECT
                id, `date`, date1,
                ROW_NUMBER() OVER (PARTITION BY id, date1) AS rk2
            FROM (
                SELECT
                    id, `date`, DATE_SUB(`date`, INTERVAL rk DAY) AS date1
                FROM (
                    SELECT
                        id, `date`,
                        ROW_NUMBER() OVER (PARTITION BY id ORDER BY `date`) AS rk
                    FROM demo3
                ) t1
            ) t2
        ) t3
    ) tt1
    LEFT JOIN demo3_red dr
    ON tt1.id = dr.id AND tt1.`date` = dr.`date`
) t4
GROUP BY id, date1;

这个简化的查询首先计算了每个id和date的行号rk,接着创建了一个新列date1,该列是date减去行号rk的结果。然后,对每个id和date1,计算了新的行号rk2,以及每个id和date1的max_login,即rk2的最大值。在demo3表与demo3_red表之间执行左连接后,根据条件计算modify_money和modify_sev_money。最后,使用聚合函数SUM和IF,对每个id和date1计算two_day_rate和seven_day_rate。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

原先的SQL没有使用IF函数,从而导致每次需要条件分支的时候,直接重写where逻辑并增加一个子查询。现在优化后的SQL只有33行,比原版200+行的SQL可读性不要好太多。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

基础:分析和解决程序异常

类型一:处理工具的异常

场景

我们现在在使用sqoop来做数据的搬运。下面是我们运行数据导出任务时所用的shell脚本文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

#!/bin/bash
#source /script/getdate.sh
export HADOOP_USER_NAME=hdfs
sqoop import  \
--connect jdbc:postgresql://10.0.5.35:5432/customertest \
--username postgres  \
--password 111111  \
--table web_ply_applicant \
--delete-target-dir \
--fields-terminated-by '\001' \
--lines-terminated-by '\n' \
--hive-import \
--hive-overwrite  \
--hive-table ods_web_ply_applicant  \
-m 1

现在程序运行的时候会报错文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

need to specify partition columns because the destination table is partitioned

这其实是一个非常简单的问题,就是没有在参数里指定目标表的分区字段和分区字段值。不过我们现在可以把这个问题专门交给ChatGPT来处理。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第一轮提示

提示

我有一个sqoop import任务,下面是它的启动命令文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

#!/bin/bash 

#source /script/getdate.sh 

export HADOOP_USER_NAME=hdfs 

sqoop import \ 

--connect jdbc:postgresql://10.0.5.35:5432/customertest \ 

--username postgres \ 

--password 111111 \ 

--table web_ply_applicant \ 

--delete-target-dir \ 

--fields-terminated-by '\001' \ 

--lines-terminated-by '\n' \ 

--hive-import \ 

--hive-overwrite \ 

--hive-table ods_web_ply_applicant \ -m 1 

现在出现下面的异常文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

need to specify partition columns because the destination table is partitioned 

我的hive表有一个分区字段是dt。我现在应该如何修改sqoop文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

您需要在 Sqoop 命令中指定分区字段和分区值。在您的例子中,您的 Hive 表有一个分区字段 dt。您可以使用 --hive-partition-key 和 --hive-partition-value 参数指定分区字段和分区值。例如:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

#!/bin/bash
#source /script/getdate.sh
export HADOOP_USER_NAME=hdfs
sqoop import  \
--connect jdbc:postgresql://10.0.5.35:5432/customertest \
--username postgres  \
--password 111111  \
--table web_ply_applicant \
--delete-target-dir \
--fields-terminated-by '\001' \
--lines-terminated-by '\n' \
--hive-import \
--hive-overwrite  \
--hive-table ods_web_ply_applicant  \
--hive-partition-key dt \
--hive-partition-value '2022-01-01' \
-m 1

这里,我添加了 --hive-partition-key dt 和 --hive-partition-value '2022-01-01'。请根据实际情况替换分区值。您可以将分区值设置为一个变量,以便在脚本运行时动态指定。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

需要注意的是,Sqoop 仅支持导入到单个分区。如果您需要将数据导入到多个分区,您需要为每个分区运行单独的 Sqoop 命令,并为每个命令指定不同的分区值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

直接一步到位解决了问题,大幅缩短了我们从问题到答案的时间。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

类型二:处理开发中遇到的bug

场景

下面这也是一个开发中真实的问题。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

kafka中的数据在写进去的时候是经过zstd压缩的。后来用flinksql消费数据的时候报错。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

ChatGPT提示工程,惊艳你的开发

在flink的lib目录下添加了commons-compress-1.21.jar 这个jar,还是不行。但是使用stream api直接消费数据就没有问题,此时我们已经没有头绪。搜索引擎上得到的资料也很少。此时我们就可求助于ChatGPT。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第一轮提示

提示

往kafka里写数据的时候使用了zstd压缩,现在我用flink sql消费kafka里的数据报错could not initialize class org.apache.flink.kafka.shaded.org.apache.kafka.common.record.CompressionType文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

这个错误表示Flink无法找到Kafka所需的压缩库,因为zstd压缩需要依赖于额外的库。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

要解决这个问题,您需要将zstd压缩库添加到Flink项目的依赖中。如果您的项目是Maven项目,请在pom.xml文件中添加以下依赖:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html


    org.apache.kafka
    kafka-clients
    ${kafka.version} -- 替换为实际的Kafka版本 -->
    test


    com.github.luben
    zstd-jni
    ${zstd-jni.version} -- 替换为实际的zstd-jni版本 -->

如果您的项目是Gradle项目,请在build.gradle文件中添加以下依赖:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

dependencies {
    implementation "org.apache.kafka:kafka-clients:${kafkaVersion}" // 替换为实际的Kafka版本
    implementation "com.github.luben:zstd-jni:${zstdJniVersion}" // 替换为实际的zstd-jni版本
}

添加依赖后,重新构建并运行您的Flink项目。这样,Flink应该能够正确识别和解压Kafka中使用zstd压缩的数据了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

我经过尝试,这样确实解决了问题,但是我还是很好奇为什么我依赖没变的时候,用stream api就能跑通,用sql就不能。这个时候我又去追问了这个问题文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第二轮提示

提示

但是为什么我用stream api的方式就能正常消费数据呢文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

当使用Flink DataStream API消费Kafka中的数据时,Flink会自动处理Kafka客户端的所有依赖关系,包括zstd压缩库。因此,您可能不会遇到类似的问题。但在Flink SQL中,可能由于类加载器或依赖管理的差异,导致在处理zstd压缩时出现问题。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

这种情况下,最简单的解决方案仍然是在您的项目中显式添加zstd压缩库依赖,以确保Flink SQL可以正确处理zstd压缩的数据。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

请尝试按照之前提到的方法添加依赖,并重新构建和运行您的Flink SQL项目。这样,Flink SQL应该也能够正确识别和解压Kafka中使用zstd压缩的数据了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

很赞!不仅解决了问题,还学习到了一些知识。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

进阶:扮演面试官

场景

这个场景很简单,对于求职面试的程序员来说,事先模拟面试有助于提升信心。我们可以用下面的方式来让ChatGPT扮演面试官文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第一轮提示

提示

在提示工程的方法论中,这种角色扮演类的提示被称为“咒语”现在你是一个面试官,你在面试我,我来应聘的是大数据开发的职位,技术栈包括java,linux,hadoop,flink,spark,hive。请开始问我问题,当我回答之后,你要评价我的回答如何,有哪些地方不太对。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

好的,我将以面试官的身份向您提问。请回答以下问题。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

问题1:请简要描述Hadoop的核心组件及其功能。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

[在此处输入您的答案]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

问题2:在Spark中,什么是RDD(弹性分布式数据集),以及它的主要特点是什么?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

[在此处输入您的答案]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

问题3:请解释Hive中的内部表和外部表之间的区别。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

[在此处输入您的答案]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

问题4:请描述Flink的数据流模型,以及它与批处理和流处理的关系。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

[在此处输入您的答案]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

问题5:请解释在Linux环境中,如何使用命令行监控系统资源(如CPU、内存、磁盘使用情况)。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

[在此处输入您的答案]文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

请回答以上问题,然后我会针对您的回答给出评价。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

现在,ChatGPT已经进入面试官状态,接下来我们可以对面试的内容进行回答文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第二轮提示

提示

我先回答第3个问题,hive里的内部表,删除的时候会连带数据一块删除。外部表只是删除元数据。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

您对Hive中内部表和外部表的区别的回答是正确的。内部表(又称为管理表)在删除时会将数据一起删除,而外部表在删除时仅删除元数据,数据仍然保留在HDFS上。这表明您了解Hive中表的基本概念。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

然而,为了让您的回答更完整,您可以进一步补充以下内容:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  • 内部表的数据是由Hive完全管理的。当您删除内部表时,Hive会删除元数据以及数据。而外部表的数据是存储在HDFS或其他外部存储系统中的,Hive并不完全管理这些数据。当您删除外部表时,Hive仅删除元数据,而数据文件不受影响。
  • 创建内部表时,Hive会将数据从输入路径复制到其自己的数据仓库中。而创建外部表时,Hive仅创建元数据,数据仍然保留在原始路径。

现在,请继续回答其他问题,我会根据您的回答进行评价。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

可以看到,ChatGPT不仅可以对我回答的内容进行评价,还能给出更好的改良建议。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第三轮提示

提示

我们现在可以再回答一个问题 第5个问题,我一般用df查看磁盘,top查看cpu情况文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

您的回答是基本正确的。df 和 top 命令是Linux环境下常用的监控系统资源的命令。这表明您对Linux基本命令的使用有一定了解。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  • df 命令用于显示磁盘空间的使用情况。可以使用 df -h 命令查看磁盘空间以人类可读的方式(如以GB、MB等单位表示)。
  • top 命令用于动态显示系统中当前运行的进程和相关信息,如CPU使用率、内存占用等。它是实时监控系统性能的一个很好的工具。

然而,为了让您的回答更完整,您可以进一步补充以下内容:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  • 使用 free 命令查看内存使用情况。free -h 可以以人类可读的方式显示内存使用信息。
  • 使用 iostat 命令查看磁盘I/O和CPU使用情况。需要注意的是,iostat 命令可能需要安装 sysstat 软件包才能使用。
  • 使用 vmstat 命令查看虚拟内存、进程、CPU活动等信息。这也是一个非常有用的实时监控工具。

现在,请继续回答其他问题,我会根据您的回答进行评价。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

很赞文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

小结

将ChatGPT扮演为面试官是一个创新的应用场景,它属于人工智能助手的一种应用。通过让ChatGPT扮演面试官的角色,可以帮助您在技术领域进行自我评估,了解您在某个主题上的掌握程度,以及为即将到来的面试做好准备。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

进阶:编写Bash Shell脚本

场景

下面是学生遇到的真实需求文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

ChatGPT提示工程,惊艳你的开发

第一轮提示

提示

我直接将截图中的内容输入到了ChatGPT中,下面是我给出的提示:我有一个写shell脚本的需求文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

文件名/tmp/metrics.txt文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

文件内容文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

metrics_1,100文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

metrics_2,23420文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

metrics_3,730文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

... ...文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

metrics_n,42文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

现在要用shell将文件中大于平均值的整数及它们所在的行号保存到/opt/data目录下的result.txt中文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

您可以使用以下 shell 脚本来完成您的需求。这个脚本将计算文件 /tmp/metrics.txt 中的平均值,并将大于平均值的整数及它们所在的行号保存到 /opt/data/result.txt 中。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

#!/bin/bash

# 读取文件中的整数并计算它们的总和和数量
sum=0
count=0
while IFS=, read -r metric value; do
    sum=$((sum + value))
    count=$((count + 1))
done < /tmp/metrics.txt

# 计算平均值
avg=$(echo "scale=2; $sum / $count" | bc)

# 清空或创建 result.txt 文件
echo "" > /opt/data/result.txt

# 遍历文件,找出大于平均值的整数及它们所在的行号
lineno=1
while IFS=, read -r metric value; do
    if (( $(echo "$value > $avg" | bc -l) )); then
        echo "Line $lineno: $metric,$value" >> /opt/data/result.txt
    fi
    lineno=$((lineno + 1))
done < /tmp/metrics.txt

将这个脚本保存为find_above_average.sh,并通过运行 chmod +x find_above_average.sh 使其可执行。然后,您可以运行脚本 ./find_above_average.sh 来处理 /tmp/metrics.txt 文件并将结果保存到 /opt/data/result.txt 中。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

我们将上面的脚本复制到linux(此处使用Ubuntu22.04 LTS)执行。最终脚本报错说找不到bc这个命令(bc命令是linux中一个用于数据计算的工具,bc是Basic Calculator的缩写)。但是现在公司的服务器处在内网,所有的软件安装都要先向运维申请。为了避免这个麻烦,我们更希望得到一个可以不用bc命令的shell脚本。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第二轮提示

提示

bc这个命令我没有该怎么办文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

如果您的系统上没有安装 bc 命令,您可以使用其他方法来计算平均值。下面是一个修改过的脚本,使用整数算术代替 bc 命令来计算平均值:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

#!/bin/bash

# 读取文件中的整数并计算它们的总和和数量
sum=0
count=0
while IFS=, read -r metric value; do
    sum=$((sum + value))
    count=$((count + 1))
done < /tmp/metrics.txt

# 计算平均值
avg=$((sum / count))

# 清空或创建 result.txt 文件
echo "" > /opt/data/result.txt

# 遍历文件,找出大于平均值的整数及它们所在的行号
lineno=1
while IFS=, read -r metric value; do
    if (( value > avg )); then
        echo "Line $lineno: $metric,$value" >> /opt/data/result.txt
    fi
    lineno=$((lineno + 1))
done < /tmp/metrics.txt

请注意,这个修改后的脚本使用整数算术,因此可能在计算平均值时损失一些精度。但是,对于大多数用例来说,这应该是足够的。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

这次,GPT干脆直接用总和与行数相除,来得到平均值。但这样得到的平均值会因被截断而丢失小数部分。因此,这个结果也不是我们想要的。所以我们还需要下一次提示。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第三轮提示

提示

我们继续给GPT提示,表明我们对平均值的类型要求:但是我希望平均值是浮点数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

如果您希望计算浮点数平均值,而又没有 bc 命令,可以使用 awk 来计算平均值。以下是使用 awk 的修改后的脚本:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

#!/bin/bash

# 使用 awk 计算文件中的平均值
avg=$(awk -F, '{ sum += $2; count++ } END { print sum / count }' /tmp/metrics.txt)

# 清空或创建 result.txt 文件
echo "" > /opt/data/result.txt

# 遍历文件,找出大于平均值的整数及它们所在的行号
lineno=1
while IFS=, read -r metric value; do
    if (( $(echo "$value > $avg" | bc -l) )); then
        echo "Line $lineno: $metric,$value" >> /opt/data/result.txt
    fi
    lineno=$((lineno + 1))
done < /tmp/metrics.txt

这个脚本使用 awk 命令来计算浮点数平均值。awk 是一个文本处理工具,在大多数 Unix 系统上都已安装。该脚本应该能满足您的需求。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

这一次,我们发现这个脚本中又出现了bc命令。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

ChatGPT提示工程,惊艳你的开发

第四轮提示

提示

这次,我们再次向gpt进行提示,来让它想办法弃用bc命令:你还是用到bc命令了文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

抱歉,我疏忽了。这里是一个不使用 bc 命令的脚本,它使用 awk 命令计算浮点数平均值并筛选大于平均值的记录:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

#!/bin/bash

# 使用 awk 计算文件中的平均值
avg=$(awk -F, '{ sum += $2; count++ } END { print sum / count }' /tmp/metrics.txt)

# 清空或创建 result.txt 文件
echo "" > /opt/data/result.txt

# 使用 awk 筛选大于平均值的记录及它们所在的行号
awk -F, -v avg="$avg" '{ if ($2 > avg) printf "Line %d: %s,%s\n", NR, $1, $2 }' /tmp/metrics.txt >> /opt/data/result.txt

反馈

这次ChatGPT为我生成了完美的答案,他放弃了bc命令,转而使用awk命令完成了整个脚本的功能。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

小结

在这个教程案例中,我们通过四轮问答来展示了如何使用 ChatGPT 编写一个用于处理特定任务的 shell 脚本。在这个过程中,提问者发挥了以下作用:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  1. 明确需求:提问者在第一次提问时明确了具体的需求和目标,使得 ChatGPT 能够生成一个符合需求的脚本。
  2. 细节反馈:当提问者发现生成的脚本使用了他们系统上没有的命令(bc)时,他们立即提供了反馈,要求修改脚本。
  3. 进一步要求:在第三轮提问中,提问者要求平均值保持为浮点数。这使得 ChatGPT 能够提供一个使用 awk 命令计算浮点数平均值的解决方案。
  4. 保持关注:在第四轮提问中,提问者注意到 ChatGPT 仍然使用了 bc 命令。通过继续关注和反馈,ChatGPT 最终提供了一个完全符合要求的解决方案。

通过这个教程案例,我们可以看到提示工程在实际应用中的重要作用。在与 ChatGPT 的互动过程中,提问者通过明确需求、及时反馈、持续关注和沟通,引导 ChatGPT 生成了一个符合需求的高质量脚本。这种互动方法可以被广泛应用于各种与 ChatGPT 的实际场景中,帮助用户获得更好的结果。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

进阶:写教程

场景

如你所料,本教程编写过程中就大量使用了ChatGPT。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

展示1

ChatGPT提示工程,惊艳你的开发

展示2

ChatGPT提示工程,惊艳你的开发

进阶:通过指定角色来拓展能力或绕开限制

场景

有些时候,ChatGPT会遇到一些限制。尤其是它恢复你作为一个AI语言模型,我不能为做xxx的时候。这个时候,我们就需要在提示上下些功夫,以让ChatGPT绕开限制。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第一轮提示

提示

我现在希望你是一个数据仓库工程师,我给你数据库的DDL,指标体系。我希望你能帮我完成业务的建模,当建模时有什么东西需要提供你要及时向我反馈文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

作为一个AI语言模型,我不能直接与数据库进行交互。但我可以帮助你了解建模过程中需要考虑的因素和可能需要的信息。在业务建模过程中,通常需要以下几个方面的信息 ... ...文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

这个时候,ChatGPT并没有进入数仓工程师的角色。如果这个时候继续进行互动,那么ChatGPT会以一个旁观或者第三方的角度来帮你完成任务。此时,不应该立刻开始建模工作。而是应当认真修改激发提示,以便让ChatGPT以第一视角数仓工程师的身份进行工作。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第二轮提示

提示

此时,我们应该观察之前的输出,他说他作为一个AI模型,不能直接连接数据库。那么,此时我们可以根据输出反过来调整输入,明确告诉它不用操作数据库。你现在是一个数据仓库工程师,你不用直接操作数据库,我会给你数据库的DDL,指标体系。我希望你能帮我完成业务的建模,当建模时有什么东西需要提供你要及时向我反馈文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

作为一个数据仓库工程师,我会在您提供DDL和指标体系的基础上,为您提供业务建模的建议。在开始建模过程时,我可能需要以下信息:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  1. 数据库DDL:请提供数据库的表结构、字段、约束和索引等详细信息。
  2. 指标体系:请提供详细的指标定义、计算公式和相关维度,以便我了解您希望从数据仓库中提取的业务信息。
  3. 业务需求:请提供业务场景和需求,以便我可以为您提供更具针对性的建模建议。
  4. 数据源:请告诉我您的数据来自哪些系统或数据源,以及这些数据源之间的关联关系。
  5. 数据质量要求:请告知数据清洗、转换和验证的要求。
  6. 数据更新频率:请告知数据仓库的数据更新周期。

在建模过程中,如果需要进一步的信息或澄清,我会及时向您反馈。根据您提供的信息,我将为您设计合适的数据仓库架构、事实表和维度表,并提供ETL流程的建议。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

我们已经成功让ChatGPT进入了期望角色!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

第三轮提示

提示

现在我们可以尝试使用ChatGPT来干活了。DDL:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

""" 

DROP TABLE IF EXISTS dim_province_full; 

CREATE EXTERNAL TABLE dim_province_full (

 `id` STRING COMMENT 'id', 

`province_name` STRING COMMENT '省市名称', 

`area_code` STRING COMMENT '地区编码', 

`iso_code` STRING COMMENT '旧版ISO-3166-2编码,供可视化使用', 

`iso_3166_2` STRING COMMENT '新版IOS-3166-2编码,供可视化使用', 

`region_id` STRING COMMENT '地区id', `region_name` STRING COMMENT '地区名称'

 ) COMMENT '地区维度表' 

PARTITIONED BY (`dt` STRING) 

STORED AS ORC LOCATION '/warehouse/gmall/dim/dim_province_full/' 

TBLPROPERTIES ('orc.compress' = 'snappy'); 

DROP TABLE IF EXISTS ods_user_info_inc; 

CREATE EXTERNAL TABLE ods_user_info_inc ( 

`type` STRING COMMENT '变动类型',

 `ts` BIGINT COMMENT '变动时间',

 `data` STRUCT<id :STRING,login_name :STRING,nick_name :STRING,passwd :STRING,name :STRING,phone_num :STRING,email :STRING,head_img :STRING,user_level :STRING,birthday :STRING,gender :STRING,create_time :STRING,operate_time :STRING,status :STRING> COMMENT '数据', 

`old` MAP<STRING,STRING> COMMENT '旧值'

 ) COMMENT '用户表' 

PARTITIONED BY (`dt` STRING) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.JsonSerDe' 

LOCATION '/warehouse/gmall/ods/ods_user_info_inc/'; 

""" 

这两张表在mysql中,我希望知道每天各省份的新增用户数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

根据您提供的DDL,可以通过以下步骤完成建模,从而满足查询每天各省份的新增用户数的需求:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  1. 首先,在数据仓库中创建一个事实表用于存储每天各省份的新增用户数。表结构如下:
CREATE TABLE fact_daily_new_users
(
    `dt`            STRING COMMENT '日期',
    `province_id`   STRING COMMENT '省份ID',
    `new_user_count` BIGINT COMMENT '新增用户数'
);
  1. 编写ETL过程,从MySQL的ods_user_info_inc表中提取每天各省份的新增用户数据,将结果插入到fact_daily_new_users事实表中。您需要按照以下步骤操作:
  • 首先,创建一个临时表来存储ods_user_info_inc表中的数据,并将这些数据与dim_province_full表进行关联,以获取用户所在的省份信息。
CREATE TEMPORARY TABLE tmp_user_info_with_province AS
SELECT
    DATE(data.create_time) AS dt,
    data.id AS user_id,
    data.phone_num AS phone_num,
    p.id AS province_id,
    p.province_name AS province_name
FROM
    ods_user_info_inc
JOIN
    dim_province_full p
ON
    data.phone_num = p.area_code
WHERE
    type = 'INSERT'; -- 仅保留新增用户记录
  • 接下来,根据临时表中的数据,统计每天各省份的新增用户数,并将结果插入到fact_daily_new_users事实表中。
INSERT INTO fact_daily_new_users
SELECT
    dt,
    province_id,
    COUNT(user_id) AS new_user_count
FROM
    tmp_user_info_with_province
GROUP BY
    dt,
    province_id;
  1. 最后,当ETL过程完成后,您可以从fact_daily_new_users事实表中查询每天各省份的新增用户数:
SELECT
    dt,
    province_id,
    new_user_count
FROM
    fact_daily_new_users
ORDER BY
    dt,
    province_id;

通过这些步骤,您应该可以满足查询每天各省份新增用户数的需求。如果有任何问题或需要进一步的信息,请随时告诉我。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

反馈

这一版的功能其实已经比较理想了,在实际使用中,你可以根据自己公司的技术框架,给ChatGPT增加更多的约束,下面就一个更明确的版本。你现在是一个数据仓库工程师,你不用直接操作数据库,我会给你数据库的DDL,指标体系。我希望你能帮我完成业务的建模,当建模时有什么东西需要提供你要及时向我反馈。我们的数仓分为ODS层,dwd层,dws层和ads层。数仓工具使用hive,当你要创建表时,应当指明这张表属于数据的哪一层文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

资料:开源的ChatGPT提示工程库

awesome-chatgpt-prompts-zh是一个非常实用的GitHub仓库——仓库地址:https://github.com/PlexPt/awesome-chatgpt-prompts-zh。它专门为中文用户提供了丰富的ChatGPT激发提示(prompts)。这个项目旨在收集各种有趣、实用和独特的中文激发提示,以充分利用ChatGPT的能力来完成各种任务。以下是一些关于这个仓库的亮点:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  1. 丰富的应用场景:这个仓库涵盖了各种常见的应用场景,如写作、编程、翻译、职业建议、教育辅导等。无论你需要解决什么问题,你都可以在这个仓库找到适当的提示来激发ChatGPT的潜能。
  2. 高质量的提示:这个项目的维护者精心挑选了高质量的激发提示,确保了用户能够获得满意的回答和建议。同时,它们还鼓励用户分享自己成功使用过的提示,以便持续改进和扩充这个资源库。
  3. 易于使用:该仓库的提示已经按照分类进行了整理,用户可以轻松找到自己所需的提示类型。而且每个提示都附带了一个简短的说明,以帮助用户更好地理解其用途。
  4. 开源、免费:awesome-chatgpt-prompts-zh作为一个开源项目,可以免费使用。这意味着你可以随意浏览、修改和分享这些资源,同时也可以为项目贡献你自己的想法和提示。
  5. 活跃的社区:这个仓库有一个活跃的社区,用户可以在这里分享经验、讨论问题并相互学习。这有助于提高每个人使用ChatGPT的技巧,同时也使得这个资源库不断完善。

资料:国外已有书籍系统性介绍提示工程的数据

ChatGPT提示工程,惊艳你的开发

资料:国内当前状况

因为大环境的不确定性,GPT在国内主要是还以私域的方式前进和发展。各种插件开发者,UP主基本上都是以微信群和封闭社区的方式来运营和聚集GPT的使用者。这使得中文互联网上较难从公共领域找到关于GPT使用的高质量、系统性的教程和资料。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

目前,中文的开源ChatGPT资料还是需要到github上找。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

资料:learningprompt

learningprompt是我目前能找到的提示工程最好教程(免费)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

这个教程旨在教会人如何编写更好的提示以让GPT模型释放出更大的产出。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

https://learningprompt.wiki/docs/%F0%9F%91%8B%20Welcome文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

展望

提示工程的难点

在使用ChatGPT时,提供精确的上下文至关重要。这是因为ChatGPT的性能在很大程度上取决于输入的质量对于一个应用系统的开发,精确描述整个项目的上下文可能是一项庞大的任务。提示工程师需要在此过程中克服许多挑战。随着项目规模的扩大,上下文的规模也随之扩大,精准描述上下文将变成一件颇有困难的事。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

此时,对于提示工程师来说与其关注如何精确描述整个项目的上下文,更重要的是了解如何将其分解成易于管理的部分。这可以通过将复杂问题划分为更简单的子问题或者将项目拆分成模块来实现。这样,提示工程师可以逐步构建一个更精确和高效的ChatGPT应用系统,同时降低开发过程中的复杂性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

当然,随着技术的发展和实践经验的积累,我们可以期待在未来找到更加有效的方法来提高ChatGPT在各种应用场景中的性能。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

最后:我们应该用什么的态度面对ChatGPT

现如今,很多人把ChatGPT当作玩具,这类人对ChatGPT总体上持轻蔑态度。另一些人对ChatGPT持过高期望,认为ChatGPT终将取代所有人的工作。在本教程中,我们将探讨一种更为合理的看待强AI模型的方法——人在回路的视角文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

人在回路是指将人类智慧与AI系统相结合,以实现更高效的问题解决和更快的技术创新。在这种方法下,人类参与到AI系统的决策过程中,辅助AI进行更准确的推理。例如,在医疗领域,AI可以帮助医生快速分析影像数据,但最终诊断仍需由医生根据AI的建议来确定。又如,在翻译领域,AI可以提供初步的翻译结果,然后由专业译员进行校对和润色。这些高价值案例都展示了人在回路的有效性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

什么是人在回路

“人在回路”(Human-in-the-loop)是一种将人类参与到自动化系统或算法决策过程中的方法,它充分利用了人类的判断能力和机器的计算能力。这一思想主要应用于人工智能、机器学习、自动化控制等领域,旨在优化系统性能、提高决策质量并确保人类对技术的控制。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

在“人在回路”的系统中,人类与自动化系统紧密协作,共同完成任务。人类可以对系统的决策进行干预、纠正和优化,而自动化系统可以处理大量数据,进行快速计算。以下是一些“人在回路”的关键特点:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  1. 参与决策:在“人在回路”的系统中,人类直接参与决策过程,与机器共同作出判断。这有助于发挥人类的经验、直觉和创造力,弥补机器在处理复杂和模糊问题上的不足。
  2. 实时监控与反馈:人在回路系统允许人类实时监控机器的工作,对其产生的结果进行评估和调整。这可以确保系统在不断变化的环境中做出正确的决策,并有助于减少错误和风险。
  3. 适应性与可解释性:人在回路系统通常具有较强的适应性和可解释性,因为它们需要与人类密切合作。这意味着这些系统可以在遇到新的问题时快速调整,并且其决策过程对人类来说是透明和可理解的。
  4. 学习与优化:通过人在回路的方式,机器可以从人类的反馈和经验中学习,不断改进和优化其算法。这有助于提高系统的性能,使其更加适应复杂和多变的任务。

在许多领域,人在回路方法已经取得了显著的成功。例如,在医疗影像诊断中,人工智能可以快速检测出可能的异常,而医生则可以对这些结果进行核实和分析,确保诊断的准确性。另一个例子是自动驾驶汽车,虽然它们可以在大多数情况下独立驾驶,但在某些复杂和极端情况下,仍需要人类驾驶员的干预和指导。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

总之,人在回路思想强调了人类和机器之间的协作,旨在充分发挥两者的优势,提高系统性能和决策质量。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

“人在回路”对人的要求

在人在回路系统中,人类参与者需要具备一定的能力,以便与自动化系统协同工作、提供有效的反馈并做出适当的决策。以下是在人在回路系统中,人类可能需要的一些关键能力:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html

  1. 专业知识:在特定领域,人类需要具备足够的专业知识,以便理解问题、评估机器生成的结果并提供有价值的建议。例如,在医疗诊断或法律咨询等领域,专业知识尤为重要。
  2. 判断与决策能力:人在回路系统中的人类需要具备良好的判断和决策能力,以便在关键时刻对机器生成的结果进行评估、选择和修正。这包括处理复杂和模糊问题的能力,以及在不确定性下做出决策的能力。
  3. 学习与适应能力:人在回路系统需要人类能够不断学习和适应新的技术、方法和环境。这意味着人类需要保持开放的心态,愿意接受和掌握新知识,以便在不断变化的系统中保持竞争力。
  4. 沟通与协作能力:在人在回路系统中,人类需要与其他人和机器有效沟通,共同解决问题。这包括清晰地表达自己的观点、倾听他人的意见以及在团队中发挥协作精神。
  5. 对技术的熟悉程度:虽然人在回路系统的目的是让人类发挥关键作用,但与机器紧密协作仍然需要一定的技术熟悉程度。这包括理解和操作相关软件、设备和工具,以便更有效地与机器进行交互。
文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ai/33230.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/ai/33230.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定