当前位置: 首页 > news >正文

43、RESTful API 保姆教程

RESTful API

目录

  1. RESTful API简介
  2. RESTful设计原则
  3. RESTful设计规范
  4. RESTful统一返回体
  5. JAX-RS
  6. JAX-RS与SpringBoot集成
  7. 构建Restful服务实践
  8. 总结

一、RESTful API 简介

REST(Representational State Transfer)是一种基于HTTP的web服务架构风格,RESTful API则是遵循REST原则的网络接口。RESTful API通过标准的HTTP方法(如GET、POST、PUT、DELETE)来操作服务器端资源,并以JSON或XML等格式传输数据。REST的特点包括无状态、缓存性和统一接口等。

1.Web开发的两种模式:

前后端不分离:

以前没有移动互联网时,我们做的大部分应用都是前后端不分的,比如jsp,或者thymeleaf等后端分离模板,在这种架构的应用中,数据基本上都是在后端渲染好返回给前端展示的,也就是后端需要控制前端的展示,前端与后端的耦合度很高。
这种应用模式比较适合纯网页应用,但是当后端对接App时,App可能并不需要后端返回一个HTML网页,而仅仅是数据本身,所以后端原本返回网页的接口不再适用于前端App应用,为了对接App后端还需再开发一套接口。这样前后端不分离就有局限性了。

前后端分离:

在前后端分离的应用模式中,后端仅返回前端所需的数据,不再渲染HTML页面,不再控制前端的效果。至于前端用户看到什么效果,从后端请求的数据如何加载到前端中,都由前端自己决定,网页有网页的处理方式,App有App的处理方式,但无论哪种前端,所需的数据基本相同,后端仅需开发一套逻辑对外提供数据即可。
在前后端分离的应用模式中 ,前端与后端的耦合度相对较低。
我们通常将后端开发的每个视图都称为一个接口,或者API,前端通过访问接口来对数据进行增删改查。

前面我们讲解了前后端不分离不分离模式,现在来讲解一下前后端分离模式怎么实现.

2.什么是API?

API:全称是 Application Programming Interface,应用程序编程接口。API是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。简单的说API 是一套协议,规定了我们与外界的沟通方式:如何发送请求和接收响应。
比如我们平时在QQ上可以看到天气信息,而这些天气信息不是腾讯公司用卫星监测到的,而是去调用气象局的天气信息的。但腾讯公司不需要也不能访问气象局的数据库和源码,而是通过调用气象局提供的一个公共函数来实现,我们只需要知道这个函数需要传递什么参数,以及返回什么样的数据就行,函数的内部结构我们并不需要知道。这个函数就是API。

3.什么是RESTful

为了在团队内部形成共识、防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的接口实现规范,
而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本。所以出现了接口服务架构,目前市面上大部分公司开发人员使用的接口服务架构主要有:restful、rpc。

REST:那Rest是什么呢,它是一种架构风格,就像气象局建立API时要遵守的一种规则,可以是Rest也可以是其它规则。这种规则是为web应用服务的,也就是用URL定位资源,用HTTP动词(GET,POST,DELETE,PUT)描述操作,用HTTP Status Code返回结果状态的这种client和server的交互方式。实现看Url就知道要什么,看http 方法就知道干什么,看http status code就知道结果如何。

RESTFul:RESTful是一种定义Web API接口的设计风格,尤其适用于前后端分离的应用模式中。RESTFul就是为了实现REST这种交互方式而制定的一套约束条件和规则,符合这些约束条件和原则的应用程序或设计就是RESTful。也就是REST本身不实用,实用的是如何设计 RESTful API(REST风格的网络接口)。这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源的访问接口,所以在定义接口时,客户端访问的URL路径就表示这种要操作的数据资源。

二、RESTful 设计原则与设计规范

1、REST的核心原则

  1. 资源导向(Resource-Oriented)
    • 将一切服务和数据视为资源(Resources)。
    • 资源通过URI(Uniform Resource Identifier)唯一标识。
    • 客户端通过URI访问资源。
  2. 客户端-服务器分离(Client-Server Separation)
    • 客户端和服务器分离,客户端负责用户界面和应用逻辑,服务器负责数据存储和计算。
    • 这种分离使得客户端和服务器可以独立演进。
  3. 无状态(Stateless)
    • 服务器不需要保存客户端的会话状态。
    • 每次请求必须包含所有必要的信息,服务器可以独立处理每个请求。
  4. 层次化接口(Layered System)
    • 系统可以分层,比如代理服务器、缓存服务器等。
    • 这种分层结构可以提高安全性和性能。
  5. 统一接口(Uniform Interface)
    • 使用统一的接口和协议(如HTTP)进行通信。
      -统一接口包括资源的表示(Representation)、资源的操作(HTTP方法)、资源的地址(URI)等。

2、RESTful设计原则

  1. 资源命名规则
    • URI命名使用单数或复数名词,例如:
      • 获取所有用户:GET /users
      • 获取特定用户:GET /users/123
    • 避免使用动词,动词由HTTP方法表示。
  2. 版本控制
    • 在URI中明确标明API版本,例如:
      • GET /v1/users
      • GET /api/v2/users
    • 避免在URL中使用查询参数(如?version=1)或自定义头部(如Accept: application/vnd.myapp.v1+json)。
  3. 使用标准HTTP方法
    • GET:获取资源(读操作)。
    • POST:创建资源(写操作)。
    • PUT:更新资源(替换操作)。
    • PATCH:部分更新资源。
    • DELETE:删除资源。
    • HEAD:获取资源的元信息(类似于GET,但不返回响应体)。
    • OPTIONS:获取支持的HTTP方法。
  4. 状态码(Status Code)
    • 使用标准的HTTP状态码,例如:
      • 200 OK:请求成功。
      • 201 Created:资源创建成功。
      • 400 Bad Request:请求格式错误。
      • 401 Unauthorized:未认证或权限不足。
      • 404 Not Found:资源不存在。
      • 500 Internal Server Error:服务器内部错误。
  5. 支持内容协商(Content Negotiation)
    • 通过Accept头部指定响应格式,例如:

相关文章:

43、RESTful API 保姆教程

RESTful API 目录 RESTful API简介RESTful设计原则RESTful设计规范RESTful统一返回体JAX-RSJAX-RS与SpringBoot集成构建Restful服务实践总结一、RESTful API 简介 REST(Representational State Transfer)是一种基于HTTP的web服务架构风格,RESTful API则是遵循REST原则的网…...

ASP.NET Core 性能优化:客户端响应缓存

文章目录 前言一、什么是缓存二、客户端缓存核心机制:HTTP缓存头1)使用[ResponseCache]属性(推荐)2)预定义缓存配置(CacheProfile)3)手动设置HTTP头4)缓存验证机制&#…...

算法导论(递归回溯)——递归

算法思路(21) 递归函数的含义: 创建一个递归函数,该函数接受两个链表的头结点作为输入,返回合并后的链表的头结点。 选择较小的节点: 在函数体内,首先比较两个链表的头结点的值,选择…...

从接口400ms到20ms,记录一次JVM、MySQL、Redis的混合双打

​​1. 场景:促销活动的崩溃​​ 接到报警短信,核心接口响应时间突破​​5秒​​,DB CPU飙到100%。 用Arthas抓取线上火焰图后发现: ---[ 4763ms ] com.example.service.OrderService.createOrder() |---[ 98% ] com.example.m…...

Excel通过VBA脚本去除重复数据行并保存

一、方法1:使用字典动态去重并保存 适用场景:需要灵活控制去重逻辑(如保留最后一次出现的重复项)时 Sub 动态去重保存到新表()Dim srcSheet As Worksheet, destSheet As WorksheetDim dict As Object, lastRow As Long, i As LongDim key A…...

Mysql表的操作(2)

1.去重 select distinct 列名 from 表名 2.查询时排序 select 列名 from 表名 order by 列名 asc/desc; 不影响数据库里面的数据 错误样例 : 但结果却有点出乎意料了~为什么会失败呢? 其实这是因为书写的形式不对,如果带了引号,…...

#Linux内存管理# 在ARM32系统中,页表是如何映射的?在ARM64系统中,页表又是如何映射的?

一、ARM32系统页表映射 1. 层级结构与地址划分 默认实现:采用两层映射(PGD→PTE),合并Linux标准三级模型中的PMD层。 虚拟地址解析(以4KB页为例): Bits[31:20]:一级页表(…...

prometheus整合jmx_exporter 使用jmx_exporter监控Kafka

docker-compose部署kafka集群;单节点单zk-CSDN博客 springboot整合kafka;docker部署kafka-CSDN博客 kafka使用SSL加密和认证--todo_ssl.truststore.location-CSDN博客 version: 3.8services:zookeeper1:image: zookeeper:3.9.1container_name: zook…...

深度学习实战:从零构建图像分类API(Flask/FastAPI版)

引言:AI时代的图像分类需求 在智能时代,图像分类技术已渗透到医疗影像分析、自动驾驶、工业质检等各个领域。作为开发者,掌握如何将深度学习模型封装为API服务,是实现技术落地的关键一步。本文将手把手教你使用Python生态中的Fla…...

Kafka实现延迟消息

Kafka 实现延迟消息 Kafka 本身不支持原生的延迟消息(不像 RocketMQ 内置了延迟队列),但可以通过多种方式来实现延迟消息。常见的方案如下: 1. 使用不同的 Topic 分区(最常见) 思路: 创建多…...

大数据(7.2)Kafka万亿级数据洪流下的架构优化实战:从参数调优到集群治理

目录 一、海量数据场景下的性能之殇1.1 互联网企业的数据增长曲线1.2 典型性能瓶颈分析 二、生产者端极致优化2.1 批量发送黄金法则2.1.1 分区选择算法对比 2.2 序列化性能突破 三、消费者端并发艺术3.1 多线程消费模式演进3.1.1 消费组Rebalance优化 3.2 位移管理高阶技巧 四、…...

要查看 FAISS 使用的 OpenMP 版本,需根据安装方式和系统环境采用不同方法。以下是具体步骤和原理分析:

要查看 FAISS 使用的 OpenMP 版本,需根据安装方式和系统环境采用不同方法。以下是具体步骤和原理分析: 方法 1:通过库文件名称直接查看(推荐) FAISS 的 OpenMP 版本通常直接体现在其依赖的动态链接库(DLL/…...

AI 大模型的标准化工具箱MCP (Model Context Protocol)

MCP简介 MCP (Model Context Protocol,模型上下文协议)定义了应用程序和 AI 模型之间交换上下文信息的方式。这使得开发者能够以一致的方式将各种数据源、工具和功能连接到 AI 模型(一个中间协议层),就像 …...

哈希表的封装

目录 引入 哈希表封装 修改哈希表参数 修改哈希表成员 修改%时使用的变量 修改读取时获得的变量 迭代器的实现 迭代器的定义 迭代器 迭代器*解引用 迭代器->成员访问 迭代器重载和! 封装迭代器 HashTable迭代器封装 非const版本 const版本 unordered_set迭…...

2025年认证杯数模竞赛赛题浅析-快速选题

赛题浅析 认证杯作为国内最早的数学建模论坛、唯一一个全部公开参赛论文的竞赛、国内最大的数学建模竞赛之一、唯一一个对非学生群里开放的数学建模竞赛、国内唯二的支持高中生参赛的大学生数模竞赛。在数模界一直被视为国赛之前较好的练手赛,本文将初步简略得介绍…...

【网络安全】Linux 常见命令

未经许可,不得转载。 文章目录 正文系统信息查看用户与权限管理进程管理网络配置与检测文件操作日志查看与分析权限审计与安全检测正文 在网络安全工作中,熟练掌握 Linux 系统中的常用命令,对于日常运维、日志分析、安全排查等工作至关重要。 以下为常用命令汇总,供参考。…...

电脑卡顿严重怎么办 电脑卡顿的处理指南

电脑突然卡顿比较严重,这是很多用户都曾经遇到过的问题,鼠标一直转圈圈,无法进行任何操作。电脑卡顿,电脑卡顿不仅会降低工作效率,还可能导致数据丢失,数据无法保存。很多用户解决电脑卡顿的方法就是直接一…...

山东大学软件学院创新项目实训开发日志(9)之测试前后端连接

在正式开始前后端功能开发前,在队友的帮助下,成功完成了前后端测试连接: 首先在后端编写一个测试相应程序: 然后在前端创建vue 并且在index.js中添加一下元素: 然后进行测试,测试成功: 后续可…...

H.264 NVMPI解码性能优化策略

H.264 NVMPI解码性能优化策略‌ ‌1. 硬件与驱动配置‌ ‌JetPack版本匹配‌:确保NVIDIA Jetson设备的JetPack SDK版本与CUDA驱动兼容,避免因驱动不匹配导致硬件解码性能下降‌8。‌显存分配优化‌:调整FFmpeg的-hwaccel_device参数指定GPU…...

汽车软件开发常用的需求管理工具汇总

目录 往期推荐 DOORS(IBM ) 行业应用企业: 应用背景: 主要特点: Polarion ALM(Siemens) 行业应用企业: 应用背景: 主要特点: Codebeamer ALM&#x…...

如何从零构建一个自己的 CentOS 基础镜像

如何从零构建一个自己的 CentOS 基础镜像 从零构建一个基于 CentOS 的基础镜像是一个很好的实践,可以帮助你理解 Docker 镜像的底层原理。以下是以 CentOS 为例,从零开始(不依赖现有镜像)构建基础镜像的详细步骤。我们将使用 yum…...

mongodb和clickhouse比较

好问题——MongoDB 也能处理这种高写入 定期删除的时间序列场景,尤其从 MongoDB 5.0 开始支持了专门的 Time Series Collections(时间序列集合),对你的需求其实挺对口的。 不过它有些优点和局限,需要具体分析下你场景…...

C#容器源码分析 --- List

List是一个非常常用的泛型集合类,它位于 System.Collections.Generic 命名空间下,本质上是一个动态数组,它提供了一系列方便的方法来管理和操作元素,例如添加、删除、查找等。与传统的数组相比,List可以根据需要动态调…...

以太坊区块大小的决定因素:深入解析区块 Gas 限制及其影响

以太坊(Ethereum)作为全球领先的区块链平台,其区块大小并非固定的物理尺寸,而是由区块 Gas 限制(Block Gas Limit)所决定。​理解区块 Gas 限制及其影响因素,对于深入掌握以太坊网络的运行机制至…...

利用DeepFlow解决APISIX故障诊断中的方向偏差问题

概要:随着APISIX作为IT应用系统入口的普及,其故障定位能力的不足导致了在业务故障诊断中,APISIX常常成为首要的“嫌疑对象”。这不仅导致了“兴师动众”式的资源投入,还可能使诊断方向“背道而驰”,从而导致业务故障“…...

智慧养老实训基地建设方案:如何以科技赋能养老实操培训

在人口老龄化加剧的当下,智慧养老产业蓬勃发展,对专业技能型人才的需求愈发迫切。智慧养老实训基地建设意义非凡,它为培育具备实操能力与创新思维的养老人才搭建关键平台,有助于填补行业人才缺口,推动养老服务从传统模…...

基于AI的Web应用防火墙(AppWall)实战:漏洞拦截与威胁情报集成

摘要:针对Web应用面临的OWASP、CVE等漏洞攻击,本文结合群联AI云防护系统的AppWall模块,详解AI规则双引擎的防御原理,并提供漏洞拦截配置与威胁情报集成代码示例。 一、Web应用安全挑战与AppWall优势 传统WAF依赖规则库更新滞后&a…...

什么是采购管理?如何做好采购管理的持续优化?

你是不是也遇到过这种情况: 公司采购部刚换了新供应商,结果原材料质量忽高忽低,生产线上三天两头出状况;行政采购的办公用品,月初买回来月底就堆在仓库吃灰;财务部天天追着问采购成本怎么又超支了... 这些…...

Unity 设置弹窗Tips位置

根据鼠标位于屏幕的区域&#xff0c;设置弹窗锚点以及位置 public static void TipsPos(Transform tf) {//获取ui相机var uiCamera GetUICamera();var popup tf.GetComponent<RectTransform>();//获取鼠标位置Vector2 mousePos Input.mousePosition;float screenWidt…...

区块链知识点5-Solidity编程基础

1. 全局变量名 具体描述 msg.sender 返回当前调用函数的调用者的地址 msg.value 当前消息所附带的以太币&#xff0c;单位为wei 2.变量的用法 默认存储位置修饰符 函数的返回值 memory 函数内部的局…...

OLAP与OLTP架构设计原理对比

OLAP与OLTP架构设计原理对比 一、核心区别 维度OLTPOLAP设计目标支持高并发、低延迟的事务操作&#xff08;增删改查&#xff09;支持复杂分析查询&#xff08;聚合、多维度统计&#xff09;数据模型规范化模型&#xff08;3NF&#xff09;&#xff0c;减少冗余维度模型&…...

ubuntu20.04在mid360部署direct_lidar_odometry(DLO)

editor&#xff1a;1034Robotics-yy time&#xff1a;2025.4.10 1.下载DLO&#xff0c;mid360需要的一些...: 1.1 在工作空间/src下 下载DLO&#xff1a; git clone https://github.com/vectr-ucla/direct_lidar_odometry 1.2 在工作空间/src下 下载livox_ros_driver2&…...

检索增强生成(RAG)架构深度解析:突破大模型边界的工程实践

一、RAG技术架构设计哲学 1.1 范式演进&#xff1a;从静态模型到动态知识系统 graph LR A[传统LLM架构] -->|问题| B[依赖预训练参数] B --> C[知识固化风险] C --> D[领域适配困难]A -->|解决方案| E[RAG增强架构] E --> F[实时知识检索] F --> G[动态上下…...

线代第四课:行列式的性质

行列式性质 转置行列式 把行列式的第一行转置成第一列&#xff0c;使用表示 如果在转置一下&#xff1a; 性质一&#xff1a; 行列地位相同&#xff0c;对行性质&#xff0c;对列性质 性质二&#xff1a; 交换D的两行&#xff08;列&#xff09;&#xff0c;D值变符号 性…...

【语音识别】vLLM 部署 Whisper 语音识别模型指南

目录 1. 模型下载 2. 环境安装 3. 部署脚本 4. 服务测试 语音识别技术在现代人工智能应用中扮演着重要角色&#xff0c;OpenAI开源的Whisper模型以其出色的识别准确率和多语言支持能力成为当前最先进的语音识别解决方案之一。本文将详细介绍如何使用vLLM&#xff08;一个高…...

Python | kelvin波的水平空间结构

写在前面 简单记录一下之前想画的一个图&#xff1a; 思路 整体比较简单&#xff0c;两个子图&#xff0c;本质上就是一个带有投影&#xff0c;一个不带投影&#xff0c;通常用在EOF的空间模态和时间序列的绘制中&#xff0c;可以看看之前的几个详细的画法。 Python | El Ni…...

什么叫行列式

《行列式&#xff1a;数学中的重要概念及其应用》 行列式是数学中的一个重要概念&#xff0c;主要用于描述线性方程组、向量空间等方面的性质。以下是关于它的详细介绍&#xff1a; 定义 行列式是由排成正方形的一组数&#xff08;称为元素&#xff09;按照特定的规则计算得…...

构建高可用大数据平台:Hadoop与Spark分布式集群搭建指南

想象一下&#xff0c;你手握海量数据&#xff0c;却因为测试环境不稳定&#xff0c;频频遭遇宕机和数据丢失的噩梦。Hadoop和Spark作为大数据处理的“黄金搭档”&#xff0c;如何在分布式高可用&#xff08;HA&#xff09;环境下稳如磐石地运行&#xff1f;答案就在于一个精心构…...

[leetcode]211. 添加与搜索单词(Trie+DFS)

题目链接 题意 实现词典类 WordDictionary &#xff1a; WordDictionary() 初始化词典对象void addWord(word) 将 word 添加到数据结构中&#xff0c;之后可以对它进行匹配bool search(word) 如果数据结构中存在字符串与 word 匹配&#xff0c;则返回 true &#xff1b;否则…...

AI | 字节跳动 AI 中文IDE编辑器 Trae 初体验

Trae 简介与安装 &#x1f526; 什么是 Trae Trae 是大厂字节跳动出品的国内首个 AI IDE&#xff0c;深度理解中文开发场景。AI 高度集成于 IDE 环境之中&#xff0c;为你带来比 AI 插件更加流畅、准确、优质的开发体验。说是能够不用写代码&#xff0c;全靠一张嘴跟 AI 聊天…...

【开发经验】结合实际问题解决详述HTTPS通信过程

最近的开发调试过程中涉及到了HTTPS发送与接收&#xff0c;遇到实际问题才发现对这部分尚属于一知半解。结合实际问题的解决过程来详细整理以下HTTPS通信过程。 需要调试的功能为BMC作为客户端向搭建好的Web服务器发送HTTPS请求&#xff0c;Web服务器负责接收处理发送过来的HT…...

灵霄破茧:仙途启幕 - 灵霄门新篇-(4)

重建之路&#xff0c;风云再起 灵霄门内一片萧瑟&#xff0c;残垣断壁间弥漫着悲伤与凝重。弟子们忙碌地清理着战场&#xff0c;救治伤员&#xff0c;每个人的脸上都带着劫后余生的疲惫。陈霄日夜守在玄风真人的榻前&#xff0c;眼中满是自责与担忧。玄风真人的伤势极重&#…...

微信小程序事件绑定基本语法

微信小程序使用 bind 或 catch 前缀绑定事件&#xff0c;语法如下&#xff1a; <组件 bind事件名"处理函数" catch事件名"处理函数"></组件> bind&#xff1a;事件绑定&#xff0c;允许事件冒泡&#xff08;向父组件传递&#xff09;。 catc…...

vscode 连不上 Ubuntu 18 server 的解决方案

下载 vscode 历史版本 18.5&#xff08;windows请装在 系统盘 C 盘&#xff09; 打开 vdcode&#xff0c;将 自动更新 设置为 None &#xff08;很关键&#xff0c;否则容易前功尽弃&#xff09; 重命名&#xff08;删除&#xff09; 服务器上的 .vscode-server 文件夹 重新…...

OSPF接口的网络类型和不规则区域

网络类型(数据链路层所使用的协议所构建的二层网络类型) 1、MA --- 多点接入网络 BMA --- 支持广播的多点接入网络 NBMA --- 不支持广播的多点接入网络 2、P2P --- 点到点网络 以太网 --- 以太网最主要的特点是需要基于MAC地址进行物理寻址&#xff0c;主要是因为以太网接口所连…...

基于Flask的勒索病毒应急响应平台架构设计与实践

基于Flask的勒索病毒应急响应平台架构设计与实践 序言&#xff1a;安全工程师的防御视角 作为从业十年的网络安全工程师&#xff0c;我深刻理解勒索病毒防御的黄金时间法则——应急响应速度每提升1分钟&#xff0c;数据恢复成功率将提高17%。本文介绍的应急响应平台&#xff…...

0410 | 软考高项笔记:项目管理概述

以下是不同组织结构中项目经理的角色、工作特点以及快速记忆的方法&#xff1a; 不同组织结构中项目经理的角色和工作特点 组织结构项目经理的角色工作特点职能型组织项目协调者、辅助管理者权力有限&#xff0c;主要负责协调部门间的工作&#xff0c;项目成员向部门经理汇报…...

基于 Qt 的图片处理工具开发(一):拖拽加载与基础图像处理功能实现

一、引言 在桌面应用开发中&#xff0c;图片处理工具的核心挑战在于用户交互的流畅性和异常处理的健壮性。本文以 Qt为框架&#xff0c;深度解析如何实现一个支持拖拽加载、亮度调节、角度旋转的图片处理工具。通过严谨的文件格式校验、分层的架构设计和用户友好的交互逻辑&am…...

2025年4月通信科技领域周报(3.31-4.06):6G技术加速落地与全连接生态构建

2025年4月通信科技领域周报&#xff08;3.31-4.06&#xff09;&#xff1a;6G技术加速落地与全连接生态构建 目录 一、本周热点回顾二、技术进展深度解析三、产业动态全景扫描四、行业生态与政策风向五、专业术语解释六、免责声明 一、本周热点回顾 1. 华为发布6G全场景技术…...

Codeforces-CF816B-Karen and Coffee(差分/前缀和)

题目翻译&#xff1a; Karen 喜欢咖啡。 她有 n 本食谱&#xff0c;第 i 本食谱包含两个数 li​,ri​&#xff0c;表示这本食谱推荐用 [li​,ri​] 之间的温度&#xff08;包含 li​.ri​&#xff09;来煮咖啡。 Karen 认为一个温度 a 是可接受的当且仅当有 ≥k 本食谱推荐用 …...