`

转献给那些向我这样对HTTP的“伪”熟悉者

    博客分类:
  • HTTP
阅读更多

——献给那些向我这样对HTTP熟悉者。

故事发生在10月份的一次面试经历中,本来我不想说出来丢人显眼,但是为了警醒自己和告诫后人,我决定写成博文发出来。因为在面试过程中,我讲在2009年写过QQ农场助手,在这期间深入学习了HTTP协议,而且在2010-05-18写了博文:HTTP协议及其POSTGET操作差异 & C#中如何使用POSTGET。面试官说既然我熟悉HTTP协议,就问HTTP采用keepalive模式,当客户端向服务器发生请求之后,客户端如何判断服务器的数据已经发生完成?

说实话,当时我懵了,一直没有关注过keepalive模式。我只知道:HTTP协议中客户端发送一个小请求,服务器响应以所期望的信息(例如一个html文件或一副gif图像)。服务器通常在发送回所请求的数据之后就关闭连接。这样客户端读数据时会返回EOF-1),就知道数据已经接收完全了。我就这样被面试官判了死刑!!!说我完全停留在表面,没有深入(当时真的很受打击,一直自认为技术还不错!)。我当时真的很想找各种借口:

  • 之前没有用到HTTPkeepalive模式,所以没有深入
  • 好久没有用HTTP协议,细节忘了
  • 实习的东西跟HTTP协议没有关系,用得少了就忘了
  • 。。。。。。

觉得各种解释都是那么苍白无力!我再次感叹书到用时方恨少,也感叹一个人的时间是多么的有限(曾一度想成为一个IT专业全才),根本没有精力面面俱到,而且当没有真正使用一个东西的时候,往往会忽略掉很多细节。朋友如果你也答不上来,请认真细看下文,不要怀着浮躁了的心,说不定下次就有人问你这个问题。

1、什么是Keep-Alive模式?

我们知道HTTP协议采用请求-应答模式,当使用普通模式,即非KeepAlive模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP协议为无连接的协议);当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。

<!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/> </v:shapetype><v:shape id="图片_x0020_1" o:spid="_x0000_i1025" type="#_x0000_t75" alt="File:HTTP persistent connection.svg" style='width:337.5pt;height:210pt; visibility:visible;mso-wrap-style:square'> <v:imagedata src="file:///C:\DOCUME~1\10070198\LOCALS~1\Temp\msohtmlclip1\01\clip_image001.png" o:title="HTTP persistent connection"/> </v:shape><![endif]--><!--[if !vml]-->File:HTTP persistent connection.svg<!--[endif]-->

http 1.0中默认是关闭的,需要在http头加入"Connection: Keep-Alive",才能启用Keep-Alivehttp 1.1中默认启用Keep-Alive,如果加入"Connection: close ",才关闭。目前大部分浏览器都是用http1.1协议,也就是说默认都会发起Keep-Alive的连接请求了,所以是否能完成一个完整的Keep-Alive连接就看服务器设置情况。

2、启用Keep-Alive的优点

从上面的分析来看,启用Keep-Alive模式肯定更高效,性能更高。因为避免了建立/释放连接的开销。下面是RFC 2616上的总结:

  1.  
    1. By opening and closing fewer TCP connections, CPU time is saved in routers and hosts (clients, servers, proxies, gateways, tunnels, or caches), and memory used for TCP protocol control blocks can be saved in hosts.
    2. HTTP requests and responses can be pipelined on a connection. Pipelining allows a client to make multiple requests without waiting for each response, allowing a single TCP connection to be used much more efficiently, with much lower elapsed time.
    3. Network congestion is reduced by reducing the number of packets caused by TCP opens, and by allowing TCP sufficient time to determine the congestion state of the network.
    4. Latency on subsequent requests is reduced since there is no time spent in TCP's connection opening handshake.
    5. HTTP can evolve more gracefully, since errors can be reported without the penalty of closing the TCP connection. Clients using     future versions of HTTP might optimistically try a new feature, but if communicating with an older server, retry with old   semantics after an error is reported.

RFC 2616P47)还指出:单用户客户端与任何服务器或代理之间的连接数不应该超过2个。一个代理与其它服务器或代码之间应该使用超过2 * N的活跃并发连接。这是为了提高HTTP响应时间,避免拥塞(冗余的连接并不能代码执行性能的提升)。

3、回到我们的问题(即如何判断消息内容/长度的大小?)

Keep-Alive模式,客户端如何判断请求所得到的响应数据已经接收完成(或者说如何知道服务器已经发生完了数据)?我们已经知道了,Keep-Alive模式发送玩数据HTTP服务器不会自动断开连接,所有不能再使用返回EOF-1)来判断(当然你一定要这样使用也没有办法,可以想象那效率是何等的低)!下面我介绍两种来判断方法。

3.1、使用消息首部字段Conent-Length

故名思意,Conent-Length表示实体内容长度,客户端(服务器)可以根据这个值来判断数据是否接收完成。但是如果消息中没有Conent-Length,那该如何来判断呢?又在什么情况下会没有Conent-Length呢?请继续往下看……

3.2、使用消息首部字段Transfer-Encoding

当客户端向服务器请求一个静态页面或者一张图片时,服务器可以很清楚的知道内容大小,然后通过Content-length消息首部字段告诉客户端需要接收多少数据。但是如果是动态页面等时,服务器是不可能预先知道内容大小,这时就可以使用Transfer-Encodingchunk模式来传输数据了。即如果要一边产生数据,一边发给客户端,服务器就需要使用"Transfer-Encoding: chunked"这样的方式来代替Content-Length

chunk编码将数据分成一块一块的发生。Chunked编码将使用若干个Chunk串连而成,由一个标明长度为0chunk标示结束。每个Chunk分为头部和正文两部分,头部内容指定正文的字符总数(十六进制的数字)和数量单位(一般不写),正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF)隔开。在最后一个长度为0Chunk中的内容是称为footer的内容,是一些附加的Header信息(通常可以直接忽略)。

Chunk编码的格式如下:

Chunked-Body = *chunk 
                                    "0" CRLF
 
                                    footer
 
                                    CRLF 
 
chunk = chunk-size [ chunk-ext ] CRLF 
                  chunk-data CRLF

hex-no-zero = <HEX excluding "0">

chunk-size = hex-no-zero *HEX 
chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-value ] )
 
chunk-ext-name = token
 
chunk-ext-val = token | quoted-string
 
chunk-data = chunk-size(OCTET)

footer = *entity-header

Chunk编码由四部分组成:10至多个chunk2"0" CRLF3footer4CRLF.而每个chunk块由:chunk-sizechunk-ext(可选)、CRLFchunk-dataCRLF组成。

4、消息长度的总结

其实,上面2中方法都可以归纳为是如何判断http消息的大小、消息的数量。RFC 2616对消息的长度总结如下:一个消息的transfer-length(传输长度)是指消息中的message-body(消息体)的长度。当应用了transfer-coding(传输编码),每个消息中的message-body(消息体)的长度(transfer-length)由以下几种情况决定(优先级由高到低):

  • 任何不含有消息体的消息(如1XXX204304等响应消息和任何头(HEAD,首部)请求的响应消息),总是由一个空行(CLRF)结束。
  • 如果出现了Transfer-Encoding头字段并且值为非“identity”,那么transfer-length“chunked” 传输编码定义,除非消息由于关闭连接而终止。
  • 如果出现了Content-Length头字段,它的值表示entity-length(实体长度)和transfer-length(传输长度)。如果这两个长度的大小不一样(i.e.设置了Transfer-Encoding头字段),那么将不能发送Content-Length头字段。并且如果同时收到了Transfer-Encoding字段和Content-Length头字段,那么必须忽略Content-Length字段。
  • 如果消息使用媒体类型“multipart/byteranges”,并且transfer-length 没有另外指定,那么这种自定界(self-delimiting)媒体类型定义transfer-length 。除非发送者知道接收者能够解析该类型,否则不能使用该类型。
  • 由服务器关闭连接确定消息长度。(注意:关闭连接不能用于确定请求消息的结束,因为服务器不能再发响应消息给客户端了。)

为了兼容HTTP/1.0应用程序,HTTP/1.1的请求消息体中必须包含一个合法的Content-Length头字段,除非知道服务器兼容HTTP/1.1。一个请求包含消息体,并且Content-Length字段没有给定,如果不能判断消息的长度,服务器应该用用400 (bad request) 来响应;或者服务器坚持希望收到一个合法的Content-Length字段,用 411 (length required)来响应。

所有HTTP/1.1的接收者应用程序必须接受“chunked” transfer-coding (传输编码),因此当不能事先知道消息的长度,允许使用这种机制来传输消息。消息不应该够同时包含 Content-Length头字段和non-identity transfer-coding。如果一个消息同时包含non-identity transfer-codingContent-Length ,必须忽略Content-Length

5HTTP头字段总结

最后我总结下HTTP协议的头部字段。

  • 1 Accept:告诉WEB服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type
  • 2 Accept-Charset浏览器申明自己接收的字符集 
    Accept-Encoding
    浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzipdeflate 
    Accept-Language
    :浏览器申明自己接收的语言 
    语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5gb2312gbk等等。
  • 3 Accept-RangesWEB服务器表明自己是否接受获取其某个实体的一部分(比如文件的一部分)的请求。bytes:表示接受,none:表示不接受。
  • 4 Age:当代理服务器用自己缓存的实体去响应请求时,用该头部表明该实体从产生到现在经过多长时间了。
  • 5 Authorization:当客户端接收到来自WEB服务器的 WWW-Authenticate 响应时,用该头部来回应自己的身份验证信息给WEB服务器。
  • 6 Cache-Control:请求:no-cache(不要缓存的实体,要求现在从WEB服务器去取) 
    max-age
    :(只接受 Age 值小于 max-age 值,并且没有过期的对象) 
    max-stale
    :(可以接受过去的对象,但是过期时间必须小于 max-stale 值) 
    min-fresh
    :(接受其新鲜生命期大于其当前 Age min-fresh 值之和的缓存对象) 
    响应:public(可以用 Cached 内容回应任何用户) 
    private
    (只能用缓存内容回应先前请求该内容的那个用户) 
    no-cache
    (可以缓存,但是只有在跟WEB服务器验证了其有效后,才能返回给客户端) 
    max-age
    :(本响应包含的对象的过期时间) 
    ALL: no-store
    (不允许缓存)
  • 7 Connection:请求:close(告诉WEB服务器或者代理服务器,在完成本次请求的响应后,断开连接,不要等待本次连接的后续请求了)。 
    keepalive
    (告诉WEB服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求)。 
    响应:close(连接已经关闭)。 
    keepalive
    (连接保持着,在等待本次连接的后续请求)。 
    Keep-Alive
    :如果浏览器请求保持连接,则该头部表明希望 WEB 服务器保持连接多长时间(秒)。例如:Keep-Alive300
  • 8 Content-EncodingWEB服务器表明自己使用了什么压缩方法(gzipdeflate)压缩响应中的对象。例如:Content-Encodinggzip
  • 9Content-LanguageWEB 服务器告诉浏览器自己响应的对象的语言。
  • 10Content-Length WEB 服务器告诉浏览器自己响应的对象的长度。例如:Content-Length: 26012
  • 11Content-Range WEB 服务器表明该响应包含的部分对象为整个对象的哪个部分。例如:Content-Range: bytes 21010-47021/47022
  • 12Content-Type WEB 服务器告诉浏览器自己响应的对象的类型。例如:Content-Typeapplication/xml
  • 13ETag:就是一个对象(比如URL)的标志值,就一个对象而言,比如一个 html 文件,如果被修改了,其 Etag 也会别修改,所以ETag 的作用跟 Last-Modified 的作用差不多,主要供 WEB 服务器判断一个对象是否改变了。比如前一次请求某个 html 文件时,获得了其 ETag,当这次又请求这个文件时,浏览器就会把先前获得的 ETag 值发送给WEB 服务器,然后 WEB 服务器会把这个 ETag 跟该文件的当前 ETag 进行对比,然后就知道这个文件有没有改变了。
  • 14 ExpiredWEB服务器表明该实体将在什么时候过期,对于过期了的对象,只有在跟WEB服务器验证了其有效性后,才能用来响应客户请求。是 HTTP/1.0 的头部。例如:ExpiresSat, 23 May 2009 10:02:12 GMT
  • 15 Host:客户端指定自己想访问的WEB服务器的域名/IP 地址和端口号。例如:Hostrss.sina.com.cn
  • 16 If-Match:如果对象的 ETag 没有改变,其实也就意味著对象没有改变,才执行请求的动作。
  • 17 If-None-Match:如果对象的 ETag 改变了,其实也就意味著对象也改变了,才执行请求的动作。
  • 18 If-Modified-Since:如果请求的对象在该头部指定的时间之后修改了,才执行请求的动作(比如返回对象),否则返回代码304,告诉浏览器该对象没有修改。例如:If-Modified-SinceThu, 10 Apr 2008 09:14:42 GMT
  • 19 If-Unmodified-Since:如果请求的对象在该头部指定的时间之后没修改过,才执行请求的动作(比如返回对象)。
  • 20 If-Range:浏览器告诉 WEB 服务器,如果我请求的对象没有改变,就把我缺少的部分给我,如果对象改变了,就把整个对象给我。浏览器通过发送请求对象的 ETag 或者自己所知道的最后修改时间给 WEB 服务器,让其判断对象是否改变了。总是跟 Range 头部一起使用。
  • 21 Last-ModifiedWEB 服务器认为对象的最后修改时间,比如文件的最后修改时间,动态页面的最后产生时间等等。例如:Last-ModifiedTue, 06 May 2008 02:42:43 GMT
  • 22 LocationWEB 服务器告诉浏览器,试图访问的对象已经被移到别的位置了,到该头部指定的位置去取。例如:Locationhttp://i0.sinaimg.cn/dy/deco/2008/0528/sinahome_0803_ws_005_text_0.gif
  • 23 Pramga:主要使用 Pramga: no-cache,相当于 Cache-Control no-cache。例如:Pragmano-cache
  • 24 Proxy-Authenticate代理服务器响应浏览器,要求其提供代理身份验证信息。Proxy-Authorization:浏览器响应代理服务器的身份验证请求,提供自己的身份信息。
  • 25 Range:浏览器(比如 Flashget 多线程下载时)告诉 WEB 服务器自己想取对象的哪部分。例如:Range: bytes=1173546-
  • 26 Referer:浏览器向 WEB 服务器表明自己是从哪个网页/URL 获得/点击当前请求中的网址/URL。例如:Refererhttp://www.sina.com/
  • 27 Server: WEB 服务器表明自己是什么软件及版本等信息。例如:ServerApache/2.0.61 (Unix)
  • 28 User-Agent: 浏览器表明自己的身份(是哪种浏览器)。例如:User-AgentMozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.14) Gecko/20080404 Firefox/20014
  • 29 Transfer-Encoding: WEB 服务器表明自己对本响应消息体(不是消息体里面的对象)作了怎样的编码,比如是否分块(chunked)。例如:Transfer-Encoding: chunked
  • 30 Vary: WEB服务器用该头部的内容告诉 Cache 服务器,在什么条件下才能用本响应所返回的对象响应后续的请求。假如源WEB服务器在接到第一个请求消息时,其响应消息的头部为:Content-Encoding: gzip; Vary: Content-Encoding那么 Cache 服务器会分析后续请求消息的头部,检查其 Accept-Encoding,是否跟先前响应的 Vary 头部值一致,即是否使用相同的内容编码方法,这样就可以防止 Cache 服务器用自己 Cache 里面压缩后的实体响应给不具备解压能力的浏览器。例如:VaryAccept-Encoding
  • 31 Via列出从客户端到 OCS 或者相反方向的响应经过了哪些代理服务器,他们用什么协议(和版本)发送的请求。当客户端请求到达第一个代理服务器时,该服务器会在自己发出的请求里面添加 Via 头部,并填上自己的相关信息,当下一个代理服务器收到第一个代理服务器的请求时,会在自己发出的请求里面复制前一个代理服务器的请求的Via 头部,并把自己的相关信息加到后面,以此类推,当 OCS 收到最后一个代理服务器的请求时,检查 Via 头部,就知道该请求所经过的路由。例如:Via1.0 236.D0707195.sina.com.cn:80 (squid/2.6.STABLE13)

=============================================================================== 
HTTP
请求消息头部实例: 
Host
rss.sina.com.cn 
User-Agent
Mozilla/50 (Windows; U; Windows NT 51; zh-CN; rv:18114) Gecko/20080404 Firefox/20014 
Accept
text/xml,application/xml,application/xhtml+xml,text/html;q=09,text/plain;q=08,image/png,*/*;q=05 
Accept-Language
zh-cn,zh;q=05 
Accept-Encoding
gzip,deflate 
Accept-Charset
gb2312,utf-8;q=07,*;q=07 
Keep-Alive
300 
Connection
keep-alive 
Cookie
userId=C5bYpXrimdmsiQmsBPnE1Vn8ZQmdWSm3WRlEB3vRwTnRtW &lt;-- Cookie 
If-Modified-Since
Sun, 01 Jun 2008 12:05:30 GMT 
Cache-Control
max-age=0 
HTTP
响应消息头部实例: 
Status
OK - 200 &lt;-- 响应状态码,表示 web 服务器处理的结果。 
Date
Sun, 01 Jun 2008 12:35:47 GMT 
Server
Apache/2061 (Unix) 
Last-Modified
Sun, 01 Jun 2008 12:35:30 GMT 
Accept-Ranges
bytes 
Content-Length
18616 
Cache-Control
max-age=120 
Expires
Sun, 01 Jun 2008 12:37:47 GMT 
Content-Type
application/xml 
Age
2 
X-Cache
HIT from 236-41D07071951sinacomcn &lt;-- 反向代理服务器使用的 HTTP 头部 
Via
1.0 236-41.D07071951.sina.com.cn:80 (squid/2.6.STABLE13) 
Connection
close

 

  • HTTP.7z (44.8 KB)
  • 下载次数: 0
分享到:
评论

相关推荐

    伪距单点定位 GPS课程设计实验论文.doc(关于单点定位)

    这是我提交给老师的作品,最后90分左右,由于之前没有接触过,所以在这里给后面的接触这的人提供一份模板。 然后实验一到三的源码从新上传到资源区域 一共三个实验,分别完成了如下要求: 实验一 RINEX文件读写 1、...

    汇编语言伪操作,表达式和程序框架的实验

    【汇编语言伪操作,表达式和程序框架的...这个实验旨在让学习者熟悉汇编语言中的伪操作、表达式和程序框架,并通过实际操作加深对这些概念的理解。通过调试和分析程序执行,学生能更好地掌握汇编语言编程的基础技能。

    跟我一起写makefile.pdf

    ### 跟我一起写Makefile #### 第一部分:概述 **Makefile**是一种脚本文件,用于自动化软件构建过程中的编译与链接任务。它主要用于Unix和类Unix系统(如Linux),但在其他操作系统上也有相应的实现。对于不熟悉...

    多多淘宝客7.4最新版.rar

    耐心查看此说明(文字版看不懂的新手对着里面的图文教程,旺旺上问我,我表白不比这文字教程。图文教程更相信,更直观的了) 1.用帝国数据库还原系统还原数据库(有人一看就问:“老兄,怎么是帝国的啊 ,答,这个是...

    Basic4android库分析器兼智能提示文本汉化工具

    以后有空,我偶尔会熟悉一下这款软件的工作环境,因为至今我仍对这款软件的工作环境不熟悉。 目前有少数一部人就是在用B4A给人编写商业软件,如果这些人能制作大量的B4A教学视频,那么B4A在中国的普及还将大大加快...

    C++MFC教程

    这样做的目的主要是增加对语言的熟悉程度,同时也训练自己的思维和熟悉一些在编程中常犯的错误。更重要的是理解并能运用C++的各种特性,这些在以后的开发中都会有很大的帮助,特别是利用MFC进行开发的朋友对C++一定...

    实验1:熟悉常用的Linux操作和Hadoop操作.docx.zip

    使用`chmod`命令可以修改文件或目录的权限,例如`chmod 755 file.txt`将给所有者赋予读、写、执行权限,给其他用户赋予只读和执行权限。 3. **文本编辑器**:`vi/vim`和`nano`是常见的Linux文本编辑器,学习如何在...

    汇编语言程序格式简明教程(PPT)

    《汇编语言程序格式简明教程》PPT为我们揭示了汇编语言编程的...通过这个教程,学习者将能够构建有效的汇编语言程序,实现对计算机硬件的直接控制,这对于嵌入式系统开发、系统级编程和性能优化等领域具有重要意义。

    c#学习笔记.txt

    另外他对我上一集中说Microsoft越来越不要脸也极为生气,因为相比之下,Sun也不怎么样,微软已经将C#提交设在日内瓦的ECMA(European Computer Manufacturers' Association,国际标准化机构欧洲电子计算机工业会)并...

    CSS3 The Missing Manual 3rd Edition

    标签选择器(Tag Selectors)、类选择器(Class Selectors)、ID选择器(ID Selectors)以及伪类和伪元素选择器的使用,使得开发者可以精确控制网页上的元素样式。 5. 盒模型:CSS中的盒模型是布局网页的基石。它...

    非常著名的perl学习手札(初学者有福了)

    ### 非常著名的Perl学习手札(初学者有福了) #### 1. 关于Perl5 **1.1 Perl的历史** Perl是由Larry Wall在1987年开发的一种高级编程语言,最初的设计目的是为了简化文本处理任务,后来发展成为一种功能强大的...

    中科大软院高级图像处理期末回忆版

    这是因为人眼对颜色的敏感度高于灰度,通过伪彩色可以增强视觉效果,便于医生识别图像特征。 图像去噪是图像处理中的重要环节。对于含有噪声的图像,应考虑保留图像特征的同时去除噪声,常见的方法如中值滤波、高斯...

    人教版五年级上册语文期末考试卷8.doc

    1. 汉字拼音:题目中给出了几个汉字的拼音,如"qíqū"对应"崎岖","chóuchú"对应"踌躇","cíxiáng"对应"慈祥"等,这些都是小学语文学习的基础内容,要求学生能根据拼音正确写出汉字。 2. 字义理解:在填表部分...

    2021-2022计算机二级等级考试试题及答案No.17464.docx

    1. **软件设计阶段的任务**:软件设计阶段的任务主要包括软件总体设计、算法设计和数据库设计等,但不包括制定软件确认测试计划,后者属于软件测试阶段的工作。 - **知识点**:明确软件设计阶段的主要任务。 ### ...

    linux学习笔记适合初学者参考

    ### Linux学习笔记知识点详解 #### 一、启动与引导配置 - **`which`命令**:用于查找系统中可执行文件的位置。...通过以上内容的学习,初学者可以建立起对Linux的基本理解和操作能力,为后续深入学习打下坚实的基础。

    微生物增殖

    从给定的文件信息来看,标题“微生物增殖”与描述和内容似乎并不直接相关,而是涉及到了一个C++编程的题目。...在实际的编程竞赛中,这样的题目不仅考验参赛者的逻辑思维能力,还考察他们对编程语言掌握的深度和广度。

    如何用ChatGPT写代码.zip

    9. **框架和库的使用**:如果你对某个框架或库不熟悉,如React、Django或TensorFlow,ChatGPT可以解释其核心概念,并给出入门示例。 10. **最佳实践**:ChatGPT还能分享编程的最佳实践,帮助你编写更优雅、可维护的...

Global site tag (gtag.js) - Google Analytics