- 创始人
- Roy Fielding
- 外文名
- Representational State Transfer
- 应用场景
- 适用于移动互联网厂商作为业务使能接口的场景
- 所属领域
- 计算机科学技术
- 中文名
- RESTful
- 实 质
- 一种网络应用程序的设计风格和开发方式
-
RESTful
2020-04-23 17:37:04RESTful理解RESTful架构RESTful API 设计指南 理解RESTful架构 http://www.ruanyifeng.com/blog/2011/09/restful.html RESTful API 设计指南 http://www.ruanyifeng.com/blog/2014/05/restful_api.html ...RESTful
理解RESTful架构
http://www.ruanyifeng.com/blog/2011/09/restful.html
RESTful API 设计指南
-
restful
2020-02-27 11:39:02restful架构风格 研究软件和网络的交叉点 表现层状态转换 设计规范-> 专属域名 /http(s)协议/ 要求路径为名词复数 格式传输为json djangorestful框架 序列化 serializer/Modelserilizer/... -
Restful
2018-05-24 17:38:02现在貌似流行了起来,甚至出现过:RESTful API是目前比较成熟的一套互联网应用程序的API设计理论,作为前端设备与后端进行通信的架构,有必要好好熟悉一下。几个概念对比既然说到来了Rest,不妨说说相关的几个概念:...前言
REST这个词,是Roy Thomas Fielding在他2000年的博士论文中提出的。现在貌似流行了起来,甚至出现过:RESTful API是目前比较成熟的一套互联网应用程序的API设计理论,作为前端设备与后端进行通信的架构,有必要好好熟悉一下。
几个概念对比
既然说到来了Rest,不妨说说相关的几个概念: REST、RESTFUL、SOAP、RPC、RESTFUL Web API;
REST
概念
- Representational State Transfer
- REST 是一种软件架构设计风格
- Fielding在他2000年的博士论文中提出的
约束条件
- C/S模型,通过统一接口通讯
- 层次化,可与多个服务器通讯
- 无状态,服务器不保存客户状态,发送请求时需包含足够信息
- Cache,C/S之间可使用缓存
- 唯一资源标识来标识资源
- 传递消息的自身描述
- 返回资源的自身描述
- 可选的超媒体即应用状态引擎(HATEOAS)
解释
REST可解释为:表现层状态转化,从一下三个方面讲述
资源(Resources)
解读
- REST的名称"中,省略了主语
- 表现层"其实指的是"资源"的"表现层
- 资源就是网络上的一个实体
- 也是网络上的一个具体信息
- 可以用一个URI(统一资源定位符)指向它
体现
- 一段文本
- 一张图片
- 一首歌曲
- 一种服务
表现层(Representation)
概念
- 把"资源"具体呈现出来的形式,叫做它的"表现层"
- 在HTTP请求的头信息中用Accept和Content-Type字段指定
体现
- 文本可以用txt格式表现
- 图片可以用JPG格式表现
状态转化(State Transfer)
概念
- 客户端想要操作服务器
- 通过某种手段,让服务器端发生"状态转化"
体现
- GET(GET用来获取资源)
- POST(用来新建(更新)资源)
- PUT(用来更新资源)
- DELETE(用来删除资源)
RESTFUL
- 满足 REST 约束条件的就称为 RESTFUL
- 每一个URI代表一种资源
- 客户端和服务器之间,传递这种资源的某种表现层
- 客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"
SOAP
概念
- Simple Object Access Protocol
- SOAP 是简单对象访问协议
- 是基于xml以及多种协议(http smtp mime)
- 使用ws-security来进行安全控制
构建模块
- 必需的 Envelope 元素
- 可选的 Header 元素,包含头部信息
- 必需的 Body 元素,包含所有的调用和响应信息
- 可选的 Fault 元素,提供有关在处理此消息所发生错误的信息
RPC
概念
- Remote Procedure Call
- 通过网络远程调用服务端
- RPC 是远程过程调用
- 可指定协议(http,tcp,udp)和传输数据格式(json,xml,二进制)
发展历程
- 早期的 RPC
- XML-RPC,SOAP,WebService
- PHPRPC
- Hessian
- JSON-RPC
- Microsoft WCF,WebAPI
- ZeroC Ice,Thrift,GRPC
- Hprose
RESTFUL Web API
- 使用HTTP并遵循REST原则的Web服务
- URI 可以完成资源定位
- GET、POST、OPTION等方法可以完成资源操作
RESTful API 设计指南
一、协议
HTTPs协议
二、域名
应该尽量将API部署在专用域名之下
三、版本(Versioning)
应该将API的版本号放入URL
参考: https://api.example.com/v1/四、路径(Endpoint)
概念
- 路径又称"终点"(endpoint)
- 表示API的具体网址
- 每个网址代表一种资源(resource)
- 网址中不能有动词,只能有名词
示例
https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees五、HTTP动词
操作
- GET(SELECT):从服务器取出资源(一项或多项)
- POST(CREATE):在服务器新建一个资源
- PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)
- PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)
- DELETE(DELETE):从服务器删除资源
- HEAD:获取资源的元数据
- OPTIONS:获取信息
示例
- GET /zoos:列出所有动物园
- POST /zoos:新建一个动物园
- GET /zoos/ID:获取某个指定动物园的信息
- PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
- PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
- DELETE /zoos/ID:删除某个动物园
- GET /zoos/ID/animals:列出某个指定动物园的所有动物
- DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物
六、过滤信息(Filtering)
概念
- 如果记录数量很多,服务器不可能都将它们返回给用户
- API应该提供参数,过滤返回结果
常见参数
- ?limit=10:指定返回记录的数量
- ?offset=10:指定返回记录的开始位置
- ?page=2&per_page=100:指定第几页,以及每页的记录数
- ?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
- ?animal_type_id=1:指定筛选条件
七、状态码(Status Codes)
服务器向用户返回的状态码和提示信息
常见状态码
- 200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)
- 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
- 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
- 204 NO CONTENT - [DELETE]:用户删除数据成功
- 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
- 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
八、错误处理(Error handling)
九、返回结果
- GET /collection:返回资源对象的列表(数组)
- GET /collection/resource:返回单个资源对象
- POST /collection:返回新生成的资源对象
- PUT /collection/resource:返回完整的资源对象
- PATCH /collection/resource:返回完整的资源对象
- DELETE /collection/resource:返回一个空文档
10、身份认证应该使用OAuth 2.0框架
11、服务器返回的数据格式,应该尽量使用JSON,避免使用XML
-
面试官:你连RESTful都不知道我怎么敢要你?
2019-11-06 00:33:54干货,2019 RESTful最贱实践效率工具前文传送门
-
12款好用的Visual Studio插件,最后一款良心推荐
面试官:了解RESTful吗?
我:听说过。
面试官:那什么是RESTful?
我:就是用起来很规范,挺好的
面试官:是RESTful挺好的,还是自我感觉挺好的
我:都挺好的。
面试官:… 把门关上。
我:… 要干嘛?先关上再说。
面试官:我说出去把门关上。
我:what ?,夺门而去
文章目录
01 前言
回归正题,看过很多RESTful相关的文章总结,参齐不齐,结合工作中的使用,非常有必要归纳一下关于RESTful架构方式了,RESTful只是一种架构方式的约束,给出一种约定的标准,完全严格遵守RESTful标准并不是很多,也没有必要。但是在实际运用中,有RESTful标准可以参考,是十分有必要的。
实际上在工作中对api接口规范、命名规则、返回值、授权验证等进行一定的约束,一般的项目api只要易测试、足够安全、风格一致可读性强、没有歧义调用方便我觉得已经足够了,接口是给开发人员看的,也不是给普通用户去调用。
02 RESTful的来源
REST:Representational State Transfer(表象层状态转变),如果没听说过REST,你一定以为是rest这个单词,刚开始我也是这样认为的,后来发现是这三个单词的缩写,即使知道了这三个单词理解起来仍然非常晦涩难懂。如何理解RESTful架构,最好的办法就是深刻理解消化Representational State Transfer这三个单词到底意味着什么。
1.每一个URI代表一种资源;
2.客户端和服务器之间,传递这种资源的某种表现层;
3.客户端通过四个HTTP动词(get、post、put、delete),对服务器端资源进行操作,实现”表现层状态转化”。是由美国计算机科学家Roy Fielding(百度百科没有介绍,真是尴尬了)。Adobe首席科学家、Http协议的首要作者之一、Apache项目联合创始人。
03 RESTful6大原则
REST之父Roy Fielding在论文中阐述REST架构的6大原则。
1. C-S架构
数据的存储在Server端,Client端只需使用就行。两端彻底分离的好处使client端代码的可移植性变强,Server端的拓展性变强。两端单独开发,互不干扰。
2. 无状态
http请求本身就是无状态的,基于C-S架构,客户端的每一次请求带有充分的信息能够让服务端识别。请求所需的一些信息都包含在URL的查询参数、header、body,服务端能够根据请求的各种参数,无需保存客户端的状态,将响应正确返回给客户端。无状态的特征大大提高的服务端的健壮性和可拓展性。
当然这总无状态性的约束也是有缺点的,客户端的每一次请求都必须带上相同重复的信息确定自己的身份和状态(这也是必须的),造成传输数据的冗余性,但这种确定对于性能和使用来说,几乎是忽略不计的。
3.统一的接口
这个才是REST架构的核心,统一的接口对于RESTful服务非常重要。客户端只需要关注实现接口就可以,接口的可读性加强,使用人员方便调用。
4.一致的数据格式
服务端返回的数据格式要么是XML,要么是Json(获取数据),或者直接返回状态码,有兴趣的可以看看博客园的开放平台的操作数据的api,post、put、patch都是返回的一个状态码 。
自我描述的信息,每项数据应该是可以自我描述的,方便代码去处理和解析其中的内容。比如通过HTTP返回的数据里面有 [MIME type ]信息,我们从MIME type里面可以知道数据的具体格式,是图片,视频还是JSON,客户端通过body内容、查询串参数、请求头和URI(资源名称)来传送状态。服务端通过body内容,响应码和响应头传送状态给客户端。这项技术被称为超媒体(或超文本链接)。
除了上述内容外,HATEOS也意味着,必要的时候链接也可被包含在返回的body(或头部)中,以提供URI来检索对象本身或关联对象。下文将对此进行更详细的阐述。
如请求一条微博信息,服务端响应信息应该包含这条微博相关的其他URL,客户端可以进一步利用这些URL发起请求获取感兴趣的信息,再如分页可以从第一页的返回数据中获取下一页的URT也是基于这个原理。
4.系统分层
客户端通常无法表明自己是直接还是间接与端服务器进行连接,分层时同样要考虑安全策略。
5.可缓存
在万维网上,客户端可以缓存页面的响应内容。因此响应都应隐式或显式的定义为可缓存的,若不可缓存则要避免客户端在多次请求后用旧数据或脏数据来响应。管理得当的缓存会部分地或完全地除去客户端和服务端之间的交互,进一步改善性能和延展性。
6.按需编码、可定制代码(可选)
服务端可选择临时给客户端下发一些功能代码让客户端来执行,从而定制和扩展客户端的某些功能。比如服务端可以返回一些 Javascript 代码让客户端执行,去实现某些特定的功能。
提示:REST架构中的设计准则中,只有按需编码为可选项。如果某个服务违反了其他任意一项准则,严格意思上不能称之为RESTful风格。03 RESTful的7个最佳实践
1. 版本
如github开放平台
https://developer.github.com/v3/
就是将版本放在url,简洁明了,这个只有用了才知道,一般的项目加版本v1,v2,v3?好吧,这个加版本估计只有大公司大项目才会去使用,说出来不怕尴尬,我真没用过。有的会将版本号放在header里面,但是不如url直接了当。https://example.com/api/v1/
2.参数命名规范
query parameter可以采用驼峰命名法,也可以采用下划线命名的方式,推荐采用下划线命名的方式,据说后者比前者的识别度要高,可能是用的人多了吧,因人而异,因团队规范而异吧。
https://example.com/api/users/today_login 获取今天登陆的用户 https://example.com/api/users/today_login&sort=login_desc 获取今天登陆的用户、登陆时间降序排列
3.url命名规范
API 命名应该采用约定俗成的方式,保持简洁明了。在RESTful架构中,每个url代表一种资源所以url中不能有动词,只能有名词,并且名词中也应该使用复数。实现者应使用相应的Http动词GET、POST、PUT、PATCH、DELETE、HEAD来操作这些资源即可
不规范的的url,冗余没有意义,形式不固定,不同的开发者还需要了解文档才能调用。
https://example.com/api/getallUsers GET 获取所有用户 https://example.com/api/getuser/1 GET 获取标识为1用户信息 https://example.com/api/user/delete/1 GET/POST 删除标识为1用户信息 https://example.com/api/updateUser/1 POST 更新标识为1用户信息 https://example.com/api/User/add POST 添加新的用户
规范后的RESTful风格的url,形式固定,可读性强,根据users名词和http动词就可以操作这些资源
https://example.com/api/users GET 获取所有用户信息 https://example.com/api/users/1 GET 获取标识为1用户信息 https://example.com/api/users/1 DELETE 删除标识为1用户信息 https://example.com/api/users/1 Patch 更新标识为1用户部分信息,包含在body中 https://example.com/api/users POST 添加新的用户
4. 统一返回数据格式
对于合法的请求应该统一返回数据格式,这里演示的是json
- code——包含一个整数类型的HTTP响应状态码。
- status——包含文本:”success”,”fail”或”error”。HTTP状态响应码在500-599之间为”fail”,在400-499之间为”error”,其它均为”success”(例如:响应状态码为1XX、2XX和3XX)。这个根据实际情况其实是可要可不要的。
- message——当状态值为”fail”和”error”时有效,用于显示错误信息。参照国际化(il8n)标准,它可以包含信息号或者编码,可以只包含其中一个,或者同时包含并用分隔符隔开。
- data——包含响应的body。当状态值为”fail”或”error”时,data仅包含错误原因或异常名称、或者null也是可以的
返回成功的响应json格式
{ "code": 200, "message": "success", "data": { "userName": "123456", "age": 16, "address": "beijing" } }
返回失败的响应json格式
{ "code": 401, "message": "error message", "data": null }
下面这个ApiResult的泛型类是在项目中用到的,拓展性强,使用方便。返回值使用统一的 ApiResult 或 ApiResult
错误返回 使用 ApiResult.Error 进行返回; 成功返回,要求使用 ApiResult.Ok 进行返回public class ApiResult: ApiResult { public new static ApiResult<T> Error(string message) { return new ApiResult<T> { Code = 1, Message = message, }; } [JsonProperty("data")] public T Data { get; set; } } public class ApiResult { public static ApiResult Error(string message) { return new ApiResult { Code = 1, Message = message, }; } public static ApiResult<T> Ok<T>(T data) { return new ApiResult<T>() { Code = 0, Message = "", Data = data }; } /// <summary> /// 0 是 正常 1 是有错误 /// </summary> [JsonProperty("code")] public int Code { get; set; } [JsonProperty("msg")] public string Message { get; set; } [JsonIgnore] public bool IsSuccess => Code == 0; }
5. http状态码
在之前开发的xamarin android博客园客户端的时候,patch、delete、post操作时body响应里面没有任何信息,仅仅只有http status code。HTTP状态码本身就有足够的含义,根据http status code就可以知道删除、添加、修改等是否成功。(ps:有点linux设计的味道哦,没有返回消息就是最好的消息,表示已经成功了)服务段向用户返回这些状态码并不是一个强制性的约束。简单点说你可以指定这些状态,但是不是强制的。常用HTTP状态码对照表
HTTP状态码也是有规律的- 1**请求未成功
- 2**请求成功、表示成功处理了请求的状态代码。
- 3**请求被重定向、表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
- 4** 请求错误这些状态代码表示请求可能出错,妨碍了服务器的处理。
- 5**(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
6. 合理使用query parameter
在请求数据时,客户端经常会对数据进行过滤和分页等要求,而这些参数推荐采用HTTP Query Parameter的方式实现
比如设计一个最近登陆的所有用户 https://example.com/api/users?recently_login_day=3
搜索用户,并按照注册时间降序 https://example.com/api/users?recently_login_day=3
搜索用户,并按照注册时间升序、活跃度降序 https://example.com/api/users?q=key&sort=create_title_asc,liveness_desc
关于分页,看看博客园开放平台分页获取精华区博文列表 https://api.cnblogs.com/api/blogposts/@picked?pageIndex={pageIndex}&pageSize={pageSize} 返回示例: [ { “Id”: 1, “Title”: “sample string 2”, “Url”: “sample string 3”, “Description”: “sample string 4”, “Author”: “sample string 5”, “BlogApp”: “sample string 6”, “Avatar”: “sample string 7”, “PostDate”: “2017-06-25T20:13:38.892135+08:00”, “ViewCount”: 9, “CommentCount”: 10, “DiggCount”: 11 }, { “Id”: 1, “Title”: “sample string 2”, “Url”: “sample string 3”, “Description”: “sample string 4”, “Author”: “sample string 5”, “BlogApp”: “sample string 6”, “Avatar”: “sample string 7”, “PostDate”: “2017-06-25T20:13:38.892135+08:00”, “ViewCount”: 9, “CommentCount”: 10, “DiggCount”: 11 } ]
7. 多表、多参数连接查询如何设计URL
这是一个比较头痛的问题,在做单个实体的查询比较容易和规范操作,但是在实际的API并不是这么简单而已,这其中常常会设计到多表连接、多条件筛选、排序等。
比如我想查询一个获取在6月份的订单中大于500元的且用户地址是北京,用户年龄在22岁到40岁、购买金额降序排列的订单列表https://example.com/api/orders?order_month=6&order_amount_greater=500&address_city=北京&sort=order_amount_desc&age_min=22&age_max=40
从这个URL上看,参数众多、调用起来还得一个一个仔细对着,而且API本身非常不容易维护,命名看起来不是很容易,不能太长,也不能太随意。
在.net WebAPI总我们可以使用属性路由,属性路由就是讲路由附加到特定的控制器或操作方法上装饰Controll及其使用[Route]属性定义路由的方法称为属性路由。
这种好处就是可以精准地控制URL,而不是基于约定的路由,简直就是为这种多表查询量身定制似的的。 从webapi 2开发,现在是RESTful API开发中最推荐的路由类型。
我们可以在Controll中标记Route[Route(“api/orders/{address}/{month}”)]
Action中的查询参数就只有金额、排序、年龄。减少了查询参数、API的可读性和可维护行增强了。
https://example.com/api/orders/beijing/6?order_amount_greater=500&sort=order_amount_desc&age_min=22&age_max=40
这种属性路由比如在博客园开放的API也有这方面的应用,如获取个人博客随笔列表
请求方式:GET 请求地址:https://api.cnblogs.com/api/blogs/{blogApp}/posts?pageIndex={pageIndex} (ps:blogApp:博客名)
作者信息:
【文章信息】:
作者-张林
原文链接-https://blog.csdn.net/kebi007/article/details/102927209
【原创公众号】:dotNet全栈开发。
【简介】:CSDN 博客专家, xamarin跨平台开发者,博客园app开发者(ps:虽然下载量还行10万+,并没有什么大用)这是一个坚持原创的技术公众号,每天坚持推送各种 dotNet 基础/进阶文章,编程技巧,爬虫实战,面试经验,xamarin开发系列不定期分享各类资源。
【福利】:送你新人大礼包一份,关注微信公众号,后台回复:“CSDN” 即可获取!
版权声明:本文为CSDN博主「dotNet全栈开发」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
————————————————
版权声明:本文为CSDN博主「dotnet全栈开发」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kebi007/article/details/103655685 -
RestFul
2020-08-15 10:28:00「深度学习福利」大神带你进阶工程师,立即查看>>> ... -
restful风格
2018-08-24 11:55:19概念 一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。... -
RESTful学习
2019-10-04 12:45:09RESTful -
REST,以及RESTful的讲解
2018-04-21 18:59:081.传统下的API接口 http是目前在互联网上... ... 如果说你要删除一个数据,以往的做法通常是 delete/{id} 如果你要更新一个数据,可能是Post数据放Body,然后方法是 update/{id}, 或者是artichle/{id}?meth... -
RESTful API接口设计标准及规范;
2019-01-12 11:42:10RESTful发展背景及简介 网络应用程序,分为前端和后端两个部分。当前的发展趋势,就是前端设备层出不穷(手机、平板、桌面电脑、其他专用设备…)。因此,必须有一种统一的机制,方便不同的前端设备与后端进行通信。... -
restful规范
2020-09-28 22:54:32客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作: GET用来获取资源, POST用来新建资源(也可以用于更新资源), PUT用来更新资源, ... restful规范就4个操作 ... -
RESTful API
2019-09-24 15:25:51RESTful API -
RESTful WebService
2016-03-26 05:24:46RESTful WebService是比基于SOAP消息的WebService简单的多的一种轻量级Web服务,RESTful WebService是没有状态的,发布和调用都非常的轻松容易。 下面写一个最简单的Hello World例子,以便对RESTful WebService有... -
Restful架构
2020-03-20 17:44:22参考资料: 理解RESTful架构 RESTful API 设计指南 RESTful 接口实现简明指南 RESTful接口详解 RESTFUL接口 -
RestFul API 案例
2018-07-31 20:25:56RestFul API 案例 新手入门帮助 包括RestFul 和RestFul Api的介绍 也包括案例代码 -
RESTFul API
2018-03-13 17:32:05定义:URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作。RESTful API 设计指南RESTful 架构详解《HTTP协议:菜鸟入门系列》如何给老婆解释什么是RESTful -
Go 语言编程 — go-restful RESTful 框架
2020-08-16 17:00:37从应用程序开发的角度来看,RESTful API 的本质是一个 Web Application,而 RESTful API 框架就是实现这个 Web Application 所封装的一些列工具库,使开发者可以忽略底层实现的复杂度,专注以自 -
restFul_Demo
2017-07-19 11:17:09restFulDemo
-
android笔试面试和实战课程
-
【数据分析-随到随学】Hadoop数据分析
-
【学习笔记】卡尔曼滤波超详细推导和理解举例(以RoboMaster目标预测为例)
-
kubernetes-dashboard.yaml
-
Dubbo.pptx
-
数据类型转换、运算符、方法入门
-
视频流分片编码的无人机视频传输方法
-
一维链状镉有机膦酸配合物的合成、结构和荧光性质研究
-
2010-2020年暨南大学824环境保护概论考研真题
-
dom4j 复制节点及其子节点
-
光纤环偏振耦合分布及绕环光纤拍长测试技术
-
2010-2020年暨南大学820数字电子技术考研真题
-
Laravel-API实践教程
-
2010-2020年暨南大学815环境学概论考研真题
-
Laya 2.0 开发3D小游戏 入门教学
-
Instantaneous frequency analysis of broadband LFM signals by photonics-assisted equivalent frequency sampling
-
微信小程序之颜值测试项目(测颜值)【项目实战】
-
具有非罗兰圆结构的太阳极紫外正入射宽波段成像光谱仪光学设计
-
算法导论二(排序和顺序统计量)——编程大牛的必经之路
-
第1章 Java入门基础及环境搭建【java编程进阶】