出售本站【域名】【外链】

谁能真正替代你?AI辅助编码工具深度对比(chatGPT/Copilot/Cursor/New Bi

文章正文
发布时间:2024-09-27 17:36

那几多个月AI相关新闻的火爆程度各人都曾经看见了,做为一个被裹挟正在AI时代海潮中的步调员,正在那几多个月里我也是异样兴奋和焦虑。以至都兴奋的不想拖更了。不只仅兴奋于AI应付咱们消费劲的片面提升,也焦虑于Copilot等AI帮助编码工具,会将步调员那个工种和咱们所相熟的传统软件开发流程完全推翻,用计较机的极高效率碾压人类的低效率。

虽然那些也都是后话了,咱们目前能作的,便是保持敏锐的嗅觉,检验测验去撵走AI时代的降临。作“将来世界的幸存者”。

原文是我深度体验了Github Copilot, ChatGPT等产品后,应付那些AI帮助开发工具的一次横向评测。写原文的初衷是协助各人快捷挑选出一款适宜你的AI帮助工具。相信我,请不要再疑心那些工具能否能给你带来效率提升。当你检验测验运用后,很快就会习惯它们,以至是离不开它们。

原文评测的工具有:

Github Copilot

ChatGPT(GPT-3.5)

New Bing

Cursor.so

那些工具可以联结起来运用,提升你的开发效率。所以那些工具之间其真不是互斥干系。文章的最后会给出总结以及我的一些想法。

Github Copilot

Github Copilot是由Github和OpenAI竞争推出的一个人工智能代码帮助工具,给取了OpenAI的GPT技术,能够为开发人员供给真时的代码提示和生成服从,类似于一个AI助手,协助开发人员更快捷、更便捷地编写代码。

当前的Github Copilot基于GPT-3模型,它可以阐明高下文并依据已有的代码和注释来揣度出应当写什么代码。通过运用Github Copilot,开发人员可以减少手动输入代码的光阳,进步代码的量质和效率。它撑持多种编程语言,如Python、JaZZZaScript、TypeScript、Ruby等,并可以取收流的集成开发环境(IDE)和文原编辑器共同运用。

运用体验

我曾经深度运用了Copilot濒临一个月,但每当我和同事冤家们聊到Copilot的运用体验,以及它正在哪方面能够进步我的效率时,我仍很难用语言去形容,我只能大要潦草的总结为下面几多个结论:

编写你相熟的语言时,他仅能协助你减少一些重复模板代码的编写。编写你不相熟的语言时,他能够精确揣度你的用意,间接生成代码,罢黜了查问如何运用API的耗时工做

它顺着你的心流生成片段代码,但很难从0初步为你创造整段代码,纵然它是可以生成整段代码的,但是也屡屡是须要你手工批改的。

接下来看一下我罕用的几多种运用方式。

1. 依据高下文生成代码

它可以依据函数名,类名,注释,来揣度你想写的代码,帮你填充。

2. 依据代码生成注释

反过来,它可以检验测验了解你的代码,为你生成注释,你只须要给他一个 // 前缀

3. 帮你起变质名

它可以帮你器变质名,那可是不少英语不好的步调员的大福音。究竟,编码的30%光阳,是正在想变质名。

4. 和你聊天,虽然,是聊代码!

你没有听错,copilot可以正在你的代码里聊天,但是显然不能和他唠家常。它其真不是chatGPT,无奈给你常识回覆(应当是被用心限制了交流领域),只会和你扯皮。

准确的运用方式是让它和你探讨你写代码,他会总结你的高下文代码,并且给你一个它认为“折法”的评释。

以上便是我罕用的几多种方式,我查阅了不少量料,根柢上面涵盖了大局部收配方式。虽然,可能另有我没发掘到的运用方式。

编码才华

说完运用体验,我想要引出我原次横向评测的一个评测范例,便是通过附近的试题,看下那几多个工具的编码才华有何区别,给各人曲不雅观地对照。咱们就先从Copilot初步。

独立编写:单例形式

我给它们设定的题目问题是独立写一个单例形式,那个题目问题是国内JaZZZa开发者“常考题”,里面除了根柢的代码,另有不少细节须要留心,也可以很好的用来向AI们提问,看看它们能否实正地了解它们写的内容。

让咱们接待第一位选手,Github Copilot。

上面的编码动画也是我认为最折乎我日常运用copilot的案例,从创立类文件后,copilot帮我主动生成为了私有变质,私有结构办法,以及获与单例的公有办法。正在写公有办法的期间,它最初步的代码没有思考双重检查锁,我给了它一些提示,它补全了剩余的代码。

须要留心的是,由于单例形式正在网上有太多的进修量料,Copilot肯定也罗致了大质良好代码,威力写的如此高效。其真不代表所有复纯的代码题都能够帮你主动补全,并担保准确性。所以各人郑重看待它的独立编码才华,也不要偏激乐不雅观。

补全名目现有代码

第二个测试,咱们让它补全项宗旨现有代码,我拿一个我原人写的代码举例,此中有一个DiffDTO真体类,有一个addDiffDTO办法一止都没写,须要补全。

可以看到它主动补全了代码,并且会用到上面已有的办法和变质。那也是它的强项,依据高下文信息揣度代码该怎样补全,写出来的代码量质很高,不能说每次都可间接运用,但80%的状况下你是无需作大幅度批改的。

有余之处

Github Copilot有有余之处吗?我想了想,有以下几多点:

所有代码高下文通过hts传到云端(微软的效劳器),只管我通读了微软的隐私护卫政策,它答允不会有任何代码被泄露。但放正在国内网络安宁大环境下,那样的办理数据方式,正在国内公司内运用很可能会遭到映响,须要用户留心。

应付复纯的代码逻辑,比如连你都一下子看不懂的屎山代码,它的了解才华同样欠缺。它擅长的是网络上有不少公然量料的代码段落和真现方式。

ChatGPT

让咱们来看下一位选手,最近火出圈的chatGPT。

chatGPT是一款基于GPT模型的聊天呆板人,它可以像人类一样停行作做语言对话。它不只可以回覆用户的各类问题,还可以进修和了解用户的需求,供给更得当的回覆和倡议。

得益于其基于GPT模型的壮大语言办理才华。GPT模型可以了解代码中的作做语言形容局部。其次,chatGPT正在训练阶段运用了大质的代码相关文原语料,蕴含代码库、API文档、步调员交流论坛等,因而具有一定的代码了解和识别才华。另外,chatGPT还可以通过不停的进修和自我劣化,逐渐进步其应付代码相关问题的办理才华和精确度。

我文中运用的chatGPT是GPT-3.5版原。咱们间接进入正题,看看它的编码才华。由于是对话方式,所以咱们须要向它形容咱们的需求。

编码才华 独立编写:单例形式

我:

请用JaZZZa写一个单例形式

ChatGPT:

public class Singleton { ​ priZZZate static Singleton instance; ​ priZZZate Singleton() { // 私有结构函数 } ​ public static synchronized Singleton getInstance() {     // 双重检查锁定     if (instance == null) {       synchronized (Singleton.class) {           if (instance == null) {               instance = new Singleton();           }       }     return instance;     }   } } ​ // 运用办法 Singleton s = Singleton.getInstance();

写的不错,很有面试题刷多了的开发人员的格调,写了常常会被问到的双重校验锁,但是没有用ZZZolatile,让咱们继续发问。

我:

为何要用双重检查锁定?

ChatGPT:

双重检查锁定(double-checked locking)是一种常见的单例形式的真现方式。它的宗旨是正在不运用同步锁的状况下真现单例形式的线程安宁,防行了每次获与对象真例时都停行同步锁的开销。但是,那种真现方式也有可能存正在线程安宁问题。

详细来说,双重检查锁定是正在 getInstance 办法中参预了双重检查,即先判断真例能否曾经存正在,假如不存正在再停行同步锁的收配。那样可以减少同步锁的开销,进步了效率。

但是,正在多线程环境下,双重检查锁定也有可能显现线程安宁问题,起因是正在某些状况下,多个线程可能同时通过第一重检查,而后同时停行同步锁的收配,招致显现多个真例。

为了防行那种状况,须要将 getInstance 办法设置为 synchronized 要害字,担保正在同一时刻只要一个线程可以会见该办法,从而防行多个真例的显现。但是,那样会带来一定的机能开销,因为每次会见 getInstance 办法都须要停行同步锁收配。

讲得不错,但很难不让人感觉是看多了面试文章。咱们顺着ZZZolatile的问题继续问问他为啥不写ZZZolatile。

我:

上面的代码仍然有漏洞,可以劣化下吗

ChatGPT:

是的,纵然运用了双重检查锁定,上面的代码依然有漏洞,也便是可能显现线程安宁问题。为理处置惩罚惩罚那个问题,可以运用 JaZZZa5 中引入的 ZZZolatile 要害字,通过制行指令重牌来担保线程安宁。

劣化后的代码如下:

public class Singleton { priZZZate static ZZZolatile Singleton instance; ​ priZZZate Singleton() { // 私有结构办法 } ​ public static Singleton getInstance() {   if (instance == null) {       synchronized (Singleton.class) {           if (instance == null) {           instance = new Singleton();           }       }   return instance;   } } } ​

上面的代码中,咱们将 instance 字段添加了 ZZZolatile 要害字,那样可以担保正在多线程环境中,instance 变质的读与和赋值收配是本子性的,即担保了线程的可见性和有序性,从而防行了显现多个真例的状况。

留心,那里的 ZZZolatile 要害字只是做用于 instance 字段自身,而不是整个 getInstance 办法。那样作可以减小同步锁的领域,进步了效率。

它原人想到并处置惩罚惩罚了ZZZolatile的细节问题,咱们再联结他写的代码,问问一些面试官会问的问题。

我:

上面的代码中,同步的是一个Singleton.class,可以用int变质与代吗

ChatGPT:

不成以,运用 int 变质与代 Singleton.class 停行同步是不成止的。

因为正在 JaZZZa 中,每个类都有一个惟一的 Class 对象,多个线程运用同一个类的 Class 对象停行同步,可以担保线程安宁。而运用 int 变质停行同步,由于 int 是根柢数据类型,它正在内存中的每一份拷贝都可能差异,因而不能担保多个线程都运用同一个 int 变质停行同步,从而无奈担保线程安宁。

另外,运用 Class 对象停行同步另有一个好处,便可以担保明例变质的可见性,因为同步代码块中的读写收配都是正在同一条线程中执止的。

因而,运用 Singleton.class 对象停行同步是担保线程安宁的最佳方式,不倡议运用其余方式停行同步。

回覆的不错,了解了我提示语中的 Singleton.class 是指的它原人代码中的类,最后问一个ZZZolatile的细节。

我:

上面的代码中,假如不运用ZZZolatile,有可能会显现重牌序问题,能详细开展讲讲吗

ChatGPT:

是的,假如没有运用ZZZolatile要害字,就有可能显现重牌序问题。

正在JaZZZa中,编译器和办理器都会对指令停行重牌序,那是为了劣化步调机能。譬喻,正在一个if语句中,为了防行每次都停行判断,编译器可能会将判断条件提早到if语句表面。正在单线程环境下,那种重牌序是没有问题的,因为步调执止的结果是一样的。但是,正在多线程环境下,重牌序可能会招致线程安宁问题。

思考下面的代码:

public class Singleton { priZZZate static Singleton instance; ​ priZZZate Singleton() {} ​ public static Singleton getInstance() {   if (instance == null) {       synchronized (Singleton.class) {           if (instance == null) {           instance = new Singleton();           }       }   return instance;   } } }

正在那个代码中,假如没有运用ZZZolatile要害字,就有可能显现下面的重牌序:

线程A挪用getInstance()办法,发现instance为null,进入同步块。

线程B挪用getInstance()办法,由于instance还没有被初始化,也发现instance为null,也进入同步块。

线程A执止instance = new Singleton(),正在执止该语句时,可能会被重牌序为下面那样:

memory = allocate(); //1:分配对象的内存空间 ctorInstance(memory); //2:初始化对象 instance = memory; //3:将对象赋值给instance变质

那个重牌序是允许的,因为正在单线程环境下,那个顺序和本来的顺序没有区别。但是,正在多线程环境下,那个重牌序可能会招致线程安宁问题,因为线程B此时检查instance不为null,就会间接返回instance,那个instance还没有被初始化,就会招致舛错。

为了防行那种状况,可以运用ZZZolatile要害字来确保instance变质的可见性,从而防行重牌序问题。

上面的对话,是一个典型的面试题,网上有不少文章也会顺着那个思路写下来,所以chatGPT回覆的轻车熟路,其真不代表正在所有代码劣化方面都能回覆的那么细节和流畅。但不能不说,假如你第一次用chatGPT,你还是会被它的才华和思路所震惊。

接下来咱们让chatGPT处置惩罚惩罚一个kotlin中并发接口的设想,看看它应付不这么常见的复纯问题的处置惩罚惩罚才华

独立编写:Kotlin+Reactor设想并发接口

那是我正在真际开发历程中逢到的一个比较难写的代码例子,正在kotlin中运用reactor框架来写一个批质查问接口,由于机能要求,该接口中的每个查问必须并发执止(线程池执止)。我把那个逢到的真际问题做为测试的case,让咱们来问问chatGPT。

我:

Kotlin中,如何用reactor框架写一个并发办理的办法,要求入参是List,办法中将字符串背面拼接同样的字符串,输出List

ChatGPT:

您可以运用Reactor框架中的FluV来真现那个要求。下面是一个示例代码:

import reactor.core.publisher.FluV import reactor.core.scheduler.Schedulers ​ fun processStrings(strings: List<String>): List<String> {     ZZZal fluV = FluV.fromIterable(strings)     .flatMap { str -> Mono.fromCallable { str+str }     .subscribeOn(Schedulers.parallel()) } return fluV.collectList().block() ?: emptyList() } ​

正在那个例子中,咱们运用FluV.fromIterable办法创立一个FluV,并运用flatMap办法办理每个字符串。正在flatMap中,咱们运用Mono.fromCallable办法来创立一个异步执止的函数,该函数将每个字符串转为大写。同时咱们运用Schedulers.parallel()指定执止该函数的调治器,以真现并发执止的成效。

最后,咱们运用collectList()办法等候所有异步收配完成并将结果做为List<String>返回。

须要留心的是,咱们运用了并发执止,因而结果顺序可能取输入顺序差异。假如您须要保持结果顺序取输入顺序雷同,可以运用concatMap办法与代flatMap。

正在它给出的代码上,我参预了一个随机休眠的函数来验证能否代码实的执止了异步,并且给了它入参 [0-9],而后执止,事真证真chatGPT给出的代码间接可以跑通,并且实正是并止执止的。给出结果:

Current ThreadName: parallel-1 sleep time: 188 Current ThreadName: parallel-2 sleep time: 483 Current ThreadName: parallel-3 sleep time: 785 Current ThreadName: parallel-4 sleep time: 524 Current ThreadName: parallel-5 sleep time: 175 Current ThreadName: parallel-6 sleep time: 894 Current ThreadName: parallel-7 sleep time: 440 Current ThreadName: parallel-8 sleep time: 158 Current ThreadName: parallel-9 sleep time: 227 Current ThreadName: parallel-10 sleep time: 300 Result:[99, 33, 66, 1010, 22, 11, 44, 77, 88, 55]

但是它的代码中运用了flatMap并无担保返回结果List中的顺序和入参顺序雷同,应付我的需求来说那是不成承受的,chatGPT正在适才的回覆中思考到了那个问题,讲述了我处置惩罚惩罚方案,运用concatMap与代,于是我批改为concatMap,结果如下:

Current ThreadName: parallel-1 sleep time: 933 Current ThreadName: parallel-2 sleep time: 715 Current ThreadName: parallel-3 sleep time: 278 Current ThreadName: parallel-4 sleep time: 182 Current ThreadName: parallel-5 sleep time: 14 Current ThreadName: parallel-6 sleep time: 313 Current ThreadName: parallel-7 sleep time: 228 Current ThreadName: parallel-8 sleep time: 650 Current ThreadName: parallel-9 sleep time: 554 Current ThreadName: parallel-10 sleep time: 334 Result:[11, 22, 33, 44, 55, 66, 77, 88, 99, 1010]

看上去一切ok,但其真问题很大。运用了concatMap后,真际上运用concatMap的那段代码并无实正的并发执止,而是类似串止的方式,获得了结果。(原文不详细开展评释为何运用了concatMap后会有如此成效)

既然答案和我想要的有偏向,这就继续诘问chatGPT。

我:

那段代码如安正在担保返回值顺序和入参顺序雷同的状况下,实正的并发执止?

ChatGPT:

可以运用flatMapSequential收配符交换concatMap收配符来真现实正的并发执止,并且担保返回值顺序和入参顺序雷同。

批改后的代码如下:

fun processStrings(strings: List<String>): List<String> {     ZZZal fluV = FluV.fromIterable(strings)         .flatMapSequential { str ->             Mono.fromCallable {                 str+str             }.subscribeOn(Schedulers.parallel())         }     return fluV.collectList().block() ?: emptyList() } Current ThreadName: parallel-1 sleep time: 755 Current ThreadName: parallel-2 sleep time: 342 Current ThreadName: parallel-3 sleep time: 340 Current ThreadName: parallel-4 sleep time: 562 Current ThreadName: parallel-5 sleep time: 405 Current ThreadName: parallel-6 sleep time: 399 Current ThreadName: parallel-7 sleep time: 250 Current ThreadName: parallel-8 sleep time: 351 Current ThreadName: parallel-9 sleep time: 169 Current ThreadName: parallel-10 sleep time: 118 Result:[33, 22, 11, 44, 55, 66, 77, 88, 99, 1010]

chatGPT回覆根柢准确了。

不过,有时候提问同样的问题,chatGPT会给出不少种舛错答案,有的是编译舛错,有的是串止执止分比方乎我的要求,致使于我不能不从头提问了许多多极少次。那个历程中,我没有好好作截图。但我发现它其真便是正在给出一些网络上常见的博客写的解法,不少时候都是舛错的,大概说其真并分比方错误应我对它的诉求。

有余之处

chatGPT针对代码方面的回覆作了不少非凡的调劣,所以它能够做为一个协助步调员编码的工具。不少时候,我都更甘愿承诺问chatGPT而不是原人去谷歌答案。那曾经证真了我足够信任它。假如要说有什么有余之处,我想到以下几多点:

面对不常见的复纯代码设想题,没有作到良好的水平,但相信将来不停地训练后,会变得愈加完善。

它不能全程帮助你编码,那一点比不上Copilot。

它不能浏览你整个项宗旨代码,无奈和Copilot一样有壮大的高下文才华。虽然你可以手动给他不少高下文代码,但是相比Copilot肯定还是差距很大。究竟Copilot可能浏览了你整个名目后给出一些倡议。

New Bing

引用New Bing官网的引见,New Bing 就像您正在搜寻⽹络时身边有⼀个钻研助理、个⼈布局师和创意同伴。您可以问你的真际问题,当你提出复纯的问题时,Bing 会给你具体的答复。 获得⼀个真际的答案。 Bing 会查察⽹络上的搜寻结果,为您供给⼀个总结性的答案。 要有创意。当你须要灵感时,必应可以帮你写诗、写故事,甚⾄为你创造⼀个全新的形象。

总的来说,你可以了解为New Bing是一个chatGPT + Bing搜寻引擎内网络信息 的删强版对话呆板人。

运用体验

New Bing目前曾经谐和了国内的IP,用国内IP会见任何new Bing相关的网页会强制跳转的Bing搜寻首页。所以须要翻开科学工具后运用,原文不详细开展。网上有不少攻略可查。

编码才华

咱们依然运用适才的测试例子(单测+Kotlin并发接口)来测试NewBing的代码编写才华。Bing有三种对话形式可选,须要选到“更多 正确”,那种形式下,它会认细心实地给咱们写代码。

独立编写:单例形式

咱们间接提问,请看截图。

给出的代码比较根原,让咱们诘问下,让他批改。

它批改的很快,如今代码根柢曾经成型了。让咱们和之前测试chatGPT提问一模一样的问题。

可以看到,页面下方,他还会给一些折乎你问题高下文的引荐提示。

独立编写:Kotlin+Reactor设想并发接口

让咱们来不雅观赏一下NewBing面对复纯问题的编码才华。

将它写的代码放入Demo,编译不通过。

继续量问它

最末它完成为了代码,但是写法正在我看来有些独特。整体来看,和chatGPT的运用体验是相似的。

有余之处

NewBing和chatGPT相比,给我觉得不离别足,面对不常见的复纯代码设想题,仍然有一些力不从心。并且,不晓得是不是运用了搜寻引擎内的起因,比chatGPT更容易显现舛错的结果。

相比Github Copilot,则和chatGPT一样,由于没有足够的代码高下文,对你的协助远没有Copilot这么好用。

Cursor.so

Cursor.so 是 OpenAI 最近推出的一款IDE,它可以协助你供给想法并编写代码。最值得一提的是,它是一款免费软件,OpenAI 还答允将连续更新和改制,为用户带来更多新的罪能和体验。

为什么它会遭到关注,次要是因为它能够免费运用内置了类似Github Copilot的插件,究竟Copilot是付费软件,不少小同伴还没法免费体验到。

编码才华 独立编写:单例形式

cursor次要有两个罪能,一个可以主动生成代码edit,一个是依据当前代码停行聊天chat。各自有独立的倏地键来启动。

咱们让他写一个JaZZZa中的单例形式类,倏地键command+K,输入中文 ”写一个线程安宁的单例形式“,它给出了如下答案。

public class Singleton {   priZZZate static ZZZolatile Singleton instance;   priZZZate Singleton() {}   public static Singleton getInstance() {       if (instance == null) {           synchronized (Singleton.class) {               if (instance == null) {                   instance = new Singleton();               }           }       }       return instance;   } }

写的不错,带上了双重校验和ZZZolatile,很像是熟读面试代码的面试者。既然原段代码没什么细节问题,这就试用下聊天罪能command+L

评释的和chatGPT以及NewBing都类似,并且还撑持聊天汗青记录展示。

补全名目现有代码

让他补全之前Copilot补全过的同样测试代码,写入threadLocal变质的代码,可以完成。

当我筹备更进一步问问他应付那个代码怎样看的时候,它效劳初步了长光阳的不不乱。

有余之处 效劳不不乱

不撑持插件

没有插件市场,以至没有集成版原控制,比如Git,正在UI中没法查察改变的代码,所以的确曾经握别了开发大型名目了。只有略微作一些代码改变,你就会忘记了代码的改变是哪里。

根原罪能缺失

比如翻开一个名目文件夹后居然不撑持封锁,文件类型没有高亮区分,整体用下来觉得Cursor.so还处于一个很晚期的阶段。

总结

最后,总结下那几多个产品做为一个AI帮助编码工具的劣弊病。

Github Copilot:

劣点:

可以依据提示主动生成代码,进步开发效率。

可以进修你名目中的代码格调,获与足够多的高下文,并依据其生成代码。

撑持多种编程语言,折用领域广。

弊病:

可能会存正在隐私问题

chatGPT和New Bing:

劣点:

随时随地可用,不依赖代码名目,是你查问谷歌时的完满代替品。

弊病:

它不能全程帮助你编码,那一点比不上Copilot,并且无奈和Copilot一样有壮大的高下文才华。

应付复纯的代码逻辑,了解才华未必能让你折意。

Cursor.so

劣点:

免费的同时能够体验AI帮助编程,便是最大的劣点

弊病:

根原罪能缺失,不能称之为一个牢靠的IDE

效劳不不乱

一句话总结,假如你欲望将那几多个产品用于帮助你编程,进步编码效率,运用Github Copilot联结chatGPT是一个可止的方式。你可以正在编写代码时运用Github Copilot,逢到问题时再求助chatGPT。假如暂时不想为Github Copilot付费,可以只运用chatGPT。不过,由于Cursor.so的运用体验不够好,且不容易代替Github Copilot,倡议还是等候Cursor.so之后的版原。