AI零代码应用生成《第四期》总结!

总结一:

1.在AiCodeGeneratorService(名称自定义)接口中定义方法,添加@SystemMessage,后续会通过动态代理通过这些方法调用大模型

2.AiCodeGeneratorServiceFactory工厂类中,会向Bean容器中注入AiCodeGeneratorService类,需要传递class类、以及(非)流式大模型。

3.与大模型交互返回内容为String类型并且很冗杂,为了能够获取到我们需要的,可以使用结构化输出 => 使用对象封装(codedescription分开)=> 将代码存储到文件中!

4.存储文件的方法为CodeFileSaver,只需要封装后的结构体对象。流程为:生成文件路径目录 -> 生成唯一路径名 -> 写入到文件 -> 返回目录路径

5.但是这种处理方式等待的时间比较长 ->流式输出 。通过LangChain4j + Reactor因为流式输出无法直接配合结构化输出使用,所以只能接收数据,然后通过序列化处理数据,最后封装成对象结构,然后交给CodeFileSaver类来创建文件。

补充:流式输出就是额外多出了:获取所有响应内容 / 正则筛选各部分内容 (CodeParser类) 两部分。

设计模式应用

保存文件

使用模板设计模式。 原因:虽然保存 HTML单文件 和 多文件的方法不同。但是在整个保存文件的流程中有重复的方法,将重复的地方抽取出来,不同的地方各自实现!

1.校验输入 (可公共 / 可独自实现 ) validInput(T result) T泛型,由继承类提供类型。

2.构建文件的目录路径 (公共部分) buildUniqueDirPath()

3.保存文件 (独自实现) save(String basicFilePath , T result)

4.返回目录 (公共部分)

执行器类类似于门面类 -> CodeFileSaverExecutor,执行器接收codeResult ,codeGenType来执行不同的方法,我们只需要提供执行器中的接口即可!

解析Code

使用**策略设计模式。原因:流式输出不支持结构化输出,因此要对Flux类型的输出进行解析。但是 单HTML文件 和 多文件的解析方式有一点差别,并且不涉及多流程,**因此不适用模板设计模式。

1.解析单HTML文件的类 -> HtmlCodeParser -> parseCode(String code)

2.解析多文件的类 -> MultiFileCodeParser -> parseCode(String code)

3.解析的实现逻辑类似:使用正则表达式对我们的code进行匹配(定义了三种模式:HTML、CSS、JS),将解析到的code作为参数去构造HtmlCodeResult / MultiFileCodeResult类即可。

同样提供执行器类 -> CodeParserExecutor,接收 code 和 codeGenTypeEnum 。根据不同类型代码文件对应不同的解析逻辑。

门面类

之前是根据不同的codeGenTypeEnum类型,来调用对应不同的处理类。现在Parser类Saver类都有对应的executor了,因此只需要调用executor提供的方法即可!

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
如何呢
作者分享
腾讯云智Timeline
23
如何选择呢??先说一下我自身的一个情况,目前是大三学生,前端掌握vue、react框架,独立开发没什么问题,但是如果要用css美化页面可能会很吃力;然后后端就是Java开发。然后目前有两个选择。 第一个是游戏公司,base上海,开发内容:后端需要使用NodeJs写一些比较简单的接口,前端会用框架进行开发,可能还涉及到根据psd设计页面。和自己学的专业不太对口。 第二个是一个外包,base北京,开发内容和掌握的技术栈完全对口。薪资待遇会比第一个公司要好。 现在困扰我的点就是:选择第一个的话,公司比较有名气,可能会有点说服力,但是产出成果感觉不是太多;选择第二个的话,实习经历中可能不太亮眼,因为是一个外包公司,但是实习产出成果会更好。
4
分片上传、断点上传
7
今天学习了JVM的一些内容,还是有难度的,面试鸭上面没找到对象的创建过程,那就在这默写一下对象的创建过程,以及类的加载过程吧! 一、对象的创建过程 1.当我们遇到new关键字、反射、或者初始化父类等情况时,就要执行对象的创建过程,首先根据对象的全限定类名去常量池中寻找符号引用,然后需要检查这个符号引用代表的类有没有被加载过(类加载器会维护一个已经加载过的类),如果没有的话,就需要进行类的加载过程,如果有的话就可以直接获取到类的直接引用。(类的加载过程在下面写) 2.类加载检查(这一步可以确保我们的类已经被加载到方法区中了)完成之后,JVM就会在堆内存中给对象分配内存,一般是在Eden区域中。 2.1然后这里分配内存的方式有两种,一种是指针碰撞,另一种是空闲列表。可能从名字上我们看不出来这两种的区别是什么,但实际上这两种内存的分配方式是根据堆内存是否规整来决定的,堆内存是否规整和我们的垃圾回收算法有关系(标记复制/标记压缩->没有内存碎片,标记清除->由内存碎片)。 先说一下指针碰撞,应用场景是在内存规整的堆内存中,通过一个指针将数据区和空闲区分隔开,当需要给对象开辟一块内存时,只需要将指针在空闲区移该对象内存大小的距离即可。 再来说空闲列表,JVM会通过一个空闲列表来维护我们可用的内存,应用场景是在内存不规整的堆内存中,当需要给对象开辟一块内存时,需要查找足够大的一个内存块给对象分配内存 2.2 在分配内存的时候,可能还会遇到线程安全问题(可能会存在多个线程同时执行分配内存操作,并且分配到了相同地址的内存上面)。 遇到线程安全问题,应该如何解决呢?有两种办法,第一种就是通过+CAS锁,如果竞争失败就去自旋;第二种是通过TLAB,JVM会预先给每一个线程在Eden区域中分配一定的空间,如果创建的对象需要分配的内存不够之后,在通过cas锁去竞争。 3.内存分配完成之后,需要给对象实例上的属性赋初始值,直接在堆内存中该对象实例的属性上赋值即可。 4.给对象的对象头设置相关信息(JMM对象内存),对象内存模型包括对象头(Mark Word对象标记、类元信息(指针))、实例数据、对齐填充。需要给对象头中的对象标记设置相关的类信息、GC分代年龄等信息,也可以添加偏向锁状态等。 5.执行init方法,对于JVM来说,一个新的对象就已经创建了, 就可以去执行构造参数对该类的属性进行具体赋值了。 二、类的加载过程 类的加载过程(主要分为三个阶段,加载阶段、连接阶段、初始化阶段) 1.加载阶段,根据类的全限定类名,获取到对应的.class字节码文件,然后交给类加载器根据双亲委派机制去加载相应的类信息,并且把类的相关信息存储在方法区中,然后把Classs对象存储在堆内存中,作为访问入口。(在这个阶段还要对class字节码文件的格式进行校验) 2.连接阶段,这个阶段分为三部分,验证、准备、解析。连接阶段顾名思义就是将我们的class字节码文件和JVM运行时环境进行连接。 2.1 验证阶段,要对class字节码文件进行验证,比如说加载阶段中的文件格式的校验、还有元数据的校验(对字节码描述信息做语义分析,并且判断是否继承了xx父类,实现了xx接口)、对字节码的校验(通过对数据流和控制流分析,确保程序不会伤害虚拟机) 2.2 准备阶段,在这个阶段中,会给静态变量分配空间,然后赋默认的初始值(这里会更倾向于分配空间)。如果是被final修饰的static变量,在编译的阶段就已经分配好空间了。 2.3 解析阶段,解析阶段是将运行时常量池中的符号引用解析为直接引用。符号引用一般是通过全限定类名来代替某个对象的具体地址的,然后直接引用是通过指针或者句柄来指向对象在堆中的一个具体地址。比如说类A在加载的过程中,对类B有一个引用,但是只是符号引用,然后就会先让类B进行一个类加载,加载完成之后就可以获取到它在堆内存中存储的地址,然后直接引用即可。 3.初始化阶段,在这个阶段中就是对静态变量进行一个赋值,然后执行静态代码块。
6
OJ判题系统小总结
15
下载 APP