【腾讯云】后端一面,OMG|0309

1. session里存啥,session和cookie区别

解析:

计算机网络基础题,必备题。

参考答案:

在Web开发中,Session和Cookie是两种常用的机制,用于在服务器和客户端之间存储和传递数据。

Session是服务器端存储用户信息的一种机制。当用户第一次访问服务器时,服务器会为该用户创建一个唯一的Session ID,并将该ID存储在Cookie中发送给客户端。客户端在后续的请求中会携带该Cookie,服务器通过Session ID可以找到对应的Session数据。服务器可以在Session中存储用户的登录状态、购物车信息等数据,以便在用户不同请求之间保持状态的一致性。Session数据存储在服务器端,相对来说更安全,但会占用服务器的内存资源。

Cookie是存储在客户端的一小段文本信息。服务器在响应中通过Set-Cookie头部将Cookie信息发送给客户端,客户端会将Cookie保存起来,并在后续的请求中携带该Cookie发送给服务器。Cookie可以存储一些用户偏好设置、登录凭证等信息。由于Cookie存储在客户端,所以可以在不同的浏览器和设备之间共享,但也存在一定的安全风险,比如可能被恶意篡改或窃取。

Session和Cookie的区别主要在于存储位置和安全性。Session数据存储在服务器端,相对安全但占用服务器资源;Cookie存储在客户端,方便共享但存在一定的安全风险。

学习指导: Cookie和Session的区别

面经专栏直通车

面经专栏下载

2. redis和mysql双写一致性为什么删缓存而不是更新缓存

解析:

考察Redis作为缓存相关知识,属于常考题,必备题,难度中等。

参考答案

主要有以下几个原因:

  1. 数据一致性:当数据发生更新时,为了保证数据的一致性,需要先更新数据库,再更新缓存。如果先更新缓存,再更新数据库,可能会导致数据库更新失败或发生异常,导致数据库和缓存之间的数据不一致。而如果选择删除缓存,下次请求时会重新从数据库中读取最新数据并更新缓存,确保了数据的一致性。
  2. 并发写入:在高并发的场景下,多个请求同时写入数据库可能会导致并发冲突和数据不一致的问题。如果先更新缓存,再更新数据库,可能会导致多个请求同时读取到旧的缓存数据并同时写入数据库,造成数据冲突。而删除缓存后,下次请求会重新从数据库读取最新数据并更新缓存,避免了并发写入的问题。
  3. 缓存更新成本:更新缓存需要进行网络通信和缓存的写入操作,相对于删除缓存来说,更新缓存的成本更高。而删除缓存后,下次请求会重新从数据库读取最新数据并更新缓存,可以减少缓存更新的成本。

删除缓存后,下次请求会重新从数据库读取最新数据并更新缓存,可能会对系统的性能产生一定的影响,因为需要进行数据库查询和缓存写入的操作。因此,在实际应用中,需要根据具体的业务场景和性能需求来选择适合的缓存策略。

学习指导:Redis与MySQL双写一致性如何保证?

3. 布隆过滤器会不会比较耗内存,添加数据怎么办,删除数据怎么办

解析:

数据结构的基本应用,数据近今年新出的题,一般与Redis易通考察。、

参考答案

布隆过滤器是一种用于快速判断一个元素是否存在于集合中的数据结构,它的优点是查询效率高且占用内存较少。然而,布隆过滤器也存在一些限制和操作上的考虑。

  1. 内存消耗:布隆过滤器的内存消耗主要取决于预期的误判率和要存储的元素数量。误判率越低,所需的内存空间就越大。一般情况下,布隆过滤器的内存消耗相对较小,但随着元素数量的增加,内存占用也会逐渐增加。
  2. 添加数据:向布隆过滤器添加数据时,需要对元素进行哈希计算,并将对应的位标记为1。如果哈希冲突较多,可能会导致位的重复标记,进而影响误判率。在添加数据时,可以适当调整布隆过滤器的容量和哈希函数的数量,以平衡误判率和内存消耗。
  3. 删除数据:布隆过滤器本身不支持直接删除已添加的元素,因为删除一个元素可能会影响其他元素的判断结果。如果需要删除元素,一种常见的做法是使用计数器或其他数据结构辅助记录元素的添加次数,然后在判断元素是否存在时,根据计数器的值进行判断。当计数器为0时,可以认为元素不存在。

需要注意的是,布隆过滤器在判断元素是否存在时,可能存在一定的误判率。因此,在使用布隆过滤器时,需要根据具体的应用场景和需求来选择合适的误判率和内存消耗。

学习指导:布隆过滤器优化内存占用过大问题

4. 解决缓存穿透其他方法

解析:

Redis 相关知识,属于必考题。

参考答案:

访问一个缓存和数据库都不存在的 key,此时会直接打到数据库上,并且查不到数据,没法写缓存,所以下一次同样会打到数据库上。此时,缓存起不到作用,请求每次都会走到数据库,流量大时数据库可能会被打挂。此时缓存就好像被“穿透”了一样,起不到任何作用。

解决方案:

1、**接口校验。**在正常业务流程中可能会存在少量访问不存在 key 的情况,但是一般不会出现大量的情况,所以这种场景最大的可能性是遭受了非法攻击。可以在最外层先做一层校验:用户鉴权、数据合法性校验等,例如商品查询中,商品的ID是正整数,则可以直接对非正整数直接过滤等等。

2、缓存空值。当访问缓存和DB都没有查询到值时,可以将空值写进缓存,但是设置较短的过期时间,该时间需要根据产品业务特性来设置。

3、布隆过滤器。使用布隆过滤器存储所有可能访问的 key,不存在的 key 直接被过滤,存在的 key 则再进一步查询缓存和数据库。

学习指导:缓存穿透问题,线上解决方案

5. 缓存击穿解决方案,抛开分布式的话如何解决

解析:

Redis 相关知识,属于必考题。

缓存击穿:某一个热点 key,在缓存过期的一瞬间,同时有大量的请求打进来,由于此时缓存过期了,所以请求最终都会走到数据库,造成瞬时数据库请求量大、压力骤增,甚至可能打垮数据库。

  1. 设置热点数据永不过期:对于一些热点数据,可以将其缓存设置为永不过期,确保即使缓存失效,也能够从缓存中获取到数据。这样可以避免热点数据失效后,大量请求直接访问数据库。
  2. 加锁机制:在缓存失效的瞬间,可以使用互斥锁(如分布式锁)来保证只有一个请求能够访问数据库,其他请求等待结果。当第一个请求从数据库中获取到数据后,更新缓存并释放锁,其他请求再从缓存中获取数据。
  3. 缓存预热:在系统启动或者定时任务中,将热点数据预先加载到缓存中。这样可以避免在热点数据失效时,大量请求直接访问数据库,而是直接从缓存中获取数据。
  4. 异步更新缓存:在数据更新时,先更新数据库,然后异步更新缓存。这样可以保证数据的一致性,同时减少对数据库的访问延迟。
  5. 限流和熔断:对请求进行限流和熔断处理,当请求量过大时,可以直接拒绝请求或者返回默认结果,避免对数据库造成过大的压力。

学习指导:缓存穿透、缓存击穿、缓存雪崩解决方案

6. 给消息队列发消息失败了怎么办

解析:

消息队列相关知识,难度中等,常考题

参考答案:

当给消息队列发送消息失败时,可以采取以下几种处理方式:

  1. 重试发送:首先,可以尝试重新发送消息。消息队列通常提供了重试机制,可以设置重试次数和重试间隔。在发送失败后,可以根据重试策略进行自动或手动的重试操作,直到消息发送成功或达到最大重试次数。
  2. 消息持久化:如果消息发送失败,可以将消息持久化到本地或者其他存储介质中,以便稍后进行重试。在持久化时,需要注意保证消息的唯一性和顺序性,避免重复发送或乱序发送。
  3. 错误日志记录:记录发送失败的消息和相关错误信息到日志中,以便后续进行排查和处理。错误日志可以包含发送失败的消息内容、发送时间、错误码等信息,有助于定位问题和进行故障排除。
  4. 监控和报警:建立监控系统,实时监控消息队列的发送状态和错误情况。当发现消息发送失败时,及时触发报警机制,通知相关人员进行处理和修复。
  5. 容错处理:在设计系统时,可以考虑引入容错机制,例如使用备份队列或者消息重放机制。当主队列发送失败时,可以将消息发送到备份队列,或者通过消息重放机制重新发送消息,以确保消息的可靠性。

需要根据具体的业务场景和消息队列的特性选择合适的处理方式。同时,也要注意监控和及时处理发送失败的消息,以保证系统的稳定性和可靠性。

学习指导:RabbitMq消息丢失原因及其解决方案

7. 限流是针对什么进行限流

解析:

后端技术的常考提,难度简单。

参考答案:

限流是一种流量控制的手段,用于限制系统或服务的请求流量,以保护系统免受过载或恶意攻击的影响。限流可以针对以下几个方面进行限制:

  1. 请求频率限流:限制单位时间内的请求次数或请求速率。例如,限制每秒钟的请求次数不超过某个阈值,或者限制每分钟的请求速率不超过某个阈值。这种限流方式可以防止系统被过多的请求压垮,保证系统的稳定性和可用性。
  2. 并发连接限流:限制同时连接到系统的请求数量。通过设置最大并发连接数,可以防止系统因为过多的并发请求而资源耗尽或崩溃。这种限流方式适用于需要控制系统负载和资源消耗的场景。
  3. API接口限流:对特定的API接口进行限流。可以根据接口的重要性、资源消耗情况、用户权限等因素,设置不同的限流策略。这种限流方式可以保护重要接口免受滥用或恶意攻击,确保接口的可用性和稳定性。
  4. IP限流:对特定IP地址进行限流。可以根据IP地址的访问频率、访问行为等进行限制,防止某个IP地址对系统进行恶意攻击、爬虫行为或者过多的请求。这种限流方式可以保护系统免受恶意访问的影响。

限流的目的是为了保护系统的稳定性、可用性和安全性,防止系统被过载或恶意攻击。具体的限流策略和方式需要根据系统的实际情况和需求进行选择和配置。

学习指导:什么是限流?

8. docker实现原理

解析:

简历提到了docker,一般会问。

参考答案:

Docker 是一种开源的容器化平台,它的实现原理主要包括以下几个方面:

  1. 命名空间(Namespaces):Docker 使用 Linux 的命名空间技术,包括 PID 命名空间、网络命名空间、挂载命名空间等,通过隔离进程、网络、文件系统等资源,使得每个容器拥有独立的运行环境。
  2. 控制组(Cgroups):Docker 使用 Linux 的控制组技术,通过限制和管理资源的使用,如 CPU、内存、磁盘、网络带宽等,实现对容器资源的控制和隔离。
  3. 联合文件系统(UnionFS):Docker 使用联合文件系统来构建容器的文件系统。联合文件系统允许将多个文件系统挂载到同一个目录下,形成一个统一的文件系统视图。Docker 默认使用的联合文件系统是 OverlayFS。
  4. 容器镜像(Container Image):Docker 使用容器镜像来打包和分发应用程序及其依赖。容器镜像是一个只读的模板,包含了运行应用程序所需的文件系统、库、环境变量等。Docker 镜像采用分层存储的方式,每一层都是一个只读的文件系统,多个镜像可以共享相同的基础层,节省存储空间。
  5. 容器运行时(Container Runtime):Docker 使用容器运行时来创建和管理容器。常用的容器运行时包括 Docker 自带的 Docker Engine、Containerd、CRI-O 等。容器运行时负责加载容器镜像、创建容器的命名空间和控制组、启动容器进程等。
  6. Docker 守护进程(Docker Daemon):Docker 守护进程是 Docker 的核心组件,负责接收和处理用户的命令,管理容器的生命周期,与容器运行时进行交互,监控容器的状态等。

通过以上的技术和组件,Docker 实现了轻量级、快速启动、隔离性好的容器化环境。用户可以使用 Docker 命令和 API 来创建、启动、停止、删除容器,以及构建、推送、拉取和管理容器镜像。

学习指导:一文弄懂Docker核心技术与实现原理

9. docker的虚拟网络如何实现

解析:

简历提到了docker,一般会问。

参考答案:

Docker的虚拟网络实现主要依赖于Linux内核提供的Network Namespace功能,该功能可以创建多个隔离的网络空间,每个网络空间都有独自的网络栈信息。当Docker创建一个容器时,会执行一系列操作来设置和配置容器的虚拟网络。

以下是Docker创建一个容器时执行的主要操作:

  1. 创建一对虚拟接口:Docker会在本地主机(Docker宿主机)和新创建的容器中各创建一个虚拟接口。
  2. 连接虚拟接口到网桥:本地主机一端的虚拟接口会连接到默认的docker0网桥或指定的网桥上,并会获得一个以“veth”开头的唯一名字,如veth1234。
  3. 放置并重命名容器端虚拟接口:容器一端的虚拟接口会被放置到新创建的容器中,并修改其名字,通常是“eth0”。这个接口只在容器的命名空间内可见。
  4. 分配IP地址:Docker会从网桥可用地址段中获取一个空闲地址,例如172.17.0.2/16,并将其分配给容器的eth0接口。同时,还会配置默认路由网关为docker0网卡的内部接口IP地址。

完成上述操作后,容器就可以使用其eth0虚拟网卡来连接其他容器和访问外部网络。这种机制允许容器仿佛自己都在独立的网络中运行,而不同Network Namespace的资源相互不可见,彼此之间无法通信。

此外,Docker还提供了多种网络模式供用户选择,包括bridge模式(默认值,连接到默认的网桥)、host模式(容器使用本地主机的网络,拥有完全的本地主机接口访问权限)等。用户可以通过docker network命令来手动管理网络,定制适合自身需求的网络配置。

学习指导:Docker 网络模式详解及容器间网络通信

10. xss攻击

解析:

常见的安全相关的问题,如果问安全相关的题,属于常考题。

参考答案:

XSS(Cross-Site Scripting)攻击是一种常见的网络安全漏洞,攻击者通过注入恶意脚本代码到受信任的网页中,使得用户在浏览器中执行这些恶意脚本,从而达到攻击的目的。XSS 攻击可以分为以下几种类型:

  1. 存储型 XSS:攻击者将恶意脚本代码存储到目标网站的数据库中,当其他用户访问包含恶意代码的页面时,恶意代码会从服务器返回并在用户浏览器中执行。
  2. 反射型 XSS:攻击者将恶意脚本代码作为参数附加在 URL 中,当用户点击包含恶意代码的链接时,服务器将恶意代码返回给用户浏览器并执行。
  3. DOM 型 XSS:攻击者通过修改网页的 DOM 结构,使得恶意脚本代码被执行。这种攻击方式不涉及服务器的参与,而是直接在用户浏览器中执行。

XSS 攻击可能导致以下危害:

  • 盗取用户敏感信息,如登录凭证、个人信息等。
  • 劫持用户会话,进行恶意操作。
  • 在受攻击网站上注入恶意广告或重定向到恶意网站。
  • 篡改网页内容,欺骗用户或破坏网站的可信度。

为了防止 XSS 攻击,可以采取以下措施:

  • 输入验证和过滤:对用户输入的数据进行验证和过滤,确保只接受合法的数据。
  • 输出编码:在将用户输入的数据输出到网页时,进行适当的编码,防止恶意代码被执行。
  • 使用 HTTP 头部中的 Content Security Policy(CSP)来限制页面中可执行的脚本。
  • 设置 HttpOnly 属性,防止恶意脚本通过 JavaScript 访问敏感的 Cookie 数据。
  • 对于存储型 XSS,对用户输入的数据进行严格的过滤和转义,确保恶意代码无法存储到数据库中。

学习指导:web攻防之XSS攻击详解——XSS简介与类型

11. sql注入

解析:

常见的安全相关的问题,如果问安全相关的题,属于常考题。

SQL注入是一种常见的网络安全漏洞,攻击者通过在应用程序的输入字段中注入恶意的SQL代码,从而绕过应用程序的输入验证,执行恶意的SQL查询或命令。这可能导致数据库被攻击者非法访问、数据泄露、数据篡改或系统瘫痪等问题。

SQL注入攻击可以分为以下几种类型:

  1. 基于错误的注入:攻击者通过构造恶意的SQL语句,利用应用程序返回的错误信息来获取数据库的信息。
  2. 基于布尔的盲注入:攻击者通过构造恶意的SQL语句,利用应用程序的不同响应来判断SQL语句的执行结果,从而逐步获取数据库的信息。
  3. 基于时间的盲注入:攻击者通过构造恶意的SQL语句,利用应用程序的延迟响应来判断SQL语句的执行结果,从而逐步获取数据库的信息。

学习指导:入坑解读 | 什么是SQL注入?

15. 如何防止sql注入

解析:

常见的安全相关的问题,如果问安全相关的题,属于常考题。

参考答案:

要防止SQL注入攻击,可以采取以下几个关键措施:

  1. 输入验证和过滤:对用户输入的数据进行验证和过滤,确保只接受合法的数据。可以使用白名单或正则表达式来验证输入数据的格式和内容,并拒绝包含特殊字符或恶意代码的输入。
  2. 使用参数化查询或预编译语句:使用参数化查询或预编译语句可以将用户输入的数据作为参数传递给SQL查询,而不是将其直接拼接到SQL语句中。这样可以防止攻击者通过注入恶意代码来改变SQL查询的逻辑。
  3. 避免动态拼接SQL语句:尽量避免在应用程序中动态拼接SQL语句,特别是使用用户输入的数据拼接SQL语句。如果必须拼接SQL语句,确保对用户输入的数据进行适当的转义或编码,以防止恶意代码的注入。
  4. 最小权限原则:数据库用户应该具有最小的权限,只能访问必要的数据和执行必要的操作。限制数据库用户的权限可以减少攻击者的影响范围,即使发生SQL注入攻击,也能最大程度地减少损失。
  5. 使用安全的开发框架和库:使用经过安全审计和验证的开发框架和库,这些框架和库通常会提供内置的防御机制来防止SQL注入攻击。例如,ORM(对象关系映射)框架可以自动处理参数化查询,从而减少了手动编写SQL语句的风险。
  6. 日志记录和监控:记录应用程序的日志,并监控异常的SQL查询,及时发现和阻止潜在的注入攻击。定期审查日志,以便及时发现异常行为并采取相应的应对措施。
  7. 定期更新和维护:及时更新和维护应用程序和数据库的软件版本,以修复已知的安全漏洞。同时,定期进行安全审计和漏洞扫描,以发现和修复潜在的SQL注入漏洞。

通过综合应用上述措施,可以大大降低SQL注入攻击的风险,并保护应用程序和数据库的安全。

学习指导:sql注入攻击的原理以及防范措施

16. mysql的prepare

解析:

MySQL 比较冷门的题,适当了解即可。

参考答案:

MySQL的PREPARE语句是一种用于执行动态SQL的机制。它允许在执行之前预先准备SQL语句,并在需要时执行该语句。PREPARE语句的语法如下:

复制PREPARE statement_name FROM 'sql_statement';

其中,statement_name是自定义的准备语句的名称,sql_statement是要准备的SQL语句。

使用PREPARE语句的好处是可以将SQL语句与参数分离,从而提高查询的效率和安全性。通过将参数作为占位符(如?)放入SQL语句中,然后在执行时将具体的参数值传递给准备语句,可以避免SQL注入攻击,并且可以重复使用准备语句以提高性能。

下面是一个使用PREPARE语句的示例:

复制PREPARE stmt FROM 'SELECT * FROM users WHERE id = ?';
SET @id = 1;
EXECUTE stmt USING @id;

在上述示例中,首先使用PREPARE语句准备了一个查询语句,然后使用EXECUTE语句执行该准备语句,并通过USING子句将参数值传递给准备语句。

执行PREPARE语句后,可以使用DEALLOCATE PREPARE语句来释放准备语句的资源,例如:

复制DEALLOCATE PREPARE stmt;

通过PREPARE语句,可以动态构建和执行SQL语句,提高查询的效率和安全性。但需要注意的是,PREPARE语句在使用时需要谨慎处理参数,确保参数的合法性和正确性,以避免潜在的安全风险。

学习指导:mysql 存储过程中的 prepare语句

17. mysql唯一索引和主键索引区别 唯一索引可以空吗 主键索引可以空吗

解析:

MySQL 常考题,必会题。

参考答案:

唯一索引和主键索引在MySQL中有一些区别,包括是否允许为空和是否可以有重复值。

  1. 唯一索引(Unique Index):
    • 唯一索引允许为空值,即可以在索引列中存储NULL值。
    • 唯一索引可以用来保证数据表中某列的值是唯一的。
  2. 主键索引(Primary Key Index):
    • 主键索引不允许为空值,即主键列不能为空。
    • 主键索引要求每个索引值都是唯一的。
    • 主键索引用于唯一标识数据表中的每一行数据,每个数据表只能有一个主键。

学习指导:sql:主键和唯一索引区别

18. redis的pipeline

解析:

Redis 的中等难度题,常考题。

参考答案:

Redis的pipeline是一种在客户端与服务器之间进行批量命令传输和响应的技术。它允许客户端一次性发送多个命令给服务器,而不需要等待每个命令的响应。服务器收到这些命令后,会将它们按顺序执行,并将所有命令的响应一次性返回给客户端,从而减少了通信的往返次数,提高了性能和吞吐量。Pipeline对于需要批量处理的场景非常有用,例如批量写入、批量读取等。

学习指导:Redis Pipeline这一篇就够了

19. 读接口并发量高怎么优化(限流,缓存,数据库查询优化)

解析:

一般是和项目关联,结合项目回答即可。

参考答案:

当接口的并发量高时,确实需要通过多种策略来优化性能。以下是一些针对限流、缓存和数据库查询优化的建议:

限流

限流是控制接口请求速率的一种手段,目的是防止因过多的请求而导致的系统崩溃或资源耗尽。

  1. 令牌桶算法或漏桶算法:使用这两种算法来限制接口的请求速率。令牌桶算法允许突发流量,而漏桶算法则更加平滑。
  2. 分布式限流:对于微服务架构,可以使用Redis等分布式系统来实现全局限流。
  3. API网关限流:在API网关层进行限流,可以保护后端服务不受过量请求的冲击。

缓存

缓存可以显著提高接口的响应速度,减少对数据库的访问次数。

  1. 本地缓存:使用如Guava Cache、Ehcache等本地缓存库,存储热点数据。
  2. 分布式缓存:对于需要共享缓存的场景,可以使用Redis、Memcached等分布式缓存系统。
  3. 缓存击穿与雪崩:注意处理缓存击穿(当缓存中没有数据,大量请求直接打到数据库)和缓存雪崩(大量缓存同时失效,导致请求全部打到数据库)的问题。

数据库查询优化

数据库查询优化是提升接口性能的关键环节。

  1. 索引优化:确保经常查询的字段都有合适的索引,同时避免全表扫描。
  2. SQL语句优化:简化复杂的SQL语句,避免在SQL中使用子查询和复杂的连接操作。
  3. 读写分离读写:使用主从复制等技术,将读操作和写操作分离到不同的数据库服务器上,提高并发性能。
  4. 批量操作:尽量减少数据库的操作次数,可以将多次操作合并为一次批量操作。
  5. 数据库连接池:使用数据库连接池可以减少数据库连接的创建和销毁开销。

其他优化策略

除了上述提到的限流、缓存和数据库查询优化外,还可以考虑以下策略:

  1. 异步处理:对于非实时性要求较高的请求,可以使用异步处理的方式,减少主线程的阻塞时间。
  2. 负载均衡:通过负载均衡技术,将请求分发到多个服务器上,提高系统的处理能力。
  3. 服务拆分:对于复杂的业务逻辑,可以将其拆分为多个微服务,降低单个服务的复杂度。
  4. 监控与告警:建立完善的监控与告警系统,及时发现并解决性能瓶颈。

学习指导:高并发读写优化方案

20. 写接口并发量高怎么优化(异步+批量)

解析:

一般是和项目关联,结合项目回答即可。

参考答案:

写接口并发量高时,可以采取以下优化措施:

  1. 异步处理: 将写接口的处理逻辑进行异步化,使用消息队列等技术将请求放入队列中,然后异步处理队列中的请求。这样可以减少请求的排队等待时间,提高接口的并发处理能力。
  2. 单线程变多线程写、批量写操作
  3. 批量处理,合并写请求: 将多个写操作合并成批量操作,减少单个写操作的次数,从而减少对数据库的频繁访问。通过批量操作可以提高数据库的吞吐量,减少写入操作的响应时间。

学习指导:高并发读写优化方案

更多面经直通车

原贴连接

24面经大全 文章被收录于专栏

收录各个网友分享的各个公司的面经,并给出答案。

全部评论
m
点赞 回复
分享
发布于 03-10 16:25 贵州
m
点赞 回复
分享
发布于 03-10 18:57 陕西
联想
校招火热招聘中
官网直投
m
点赞 回复
分享
发布于 03-11 20:03 重庆
需要的话可以看看我首页内推码,米哈游有很多岗位,直接扫描投递,可咨询
点赞 回复
分享
发布于 03-28 08:47 上海

相关推荐

29 240 评论
分享
牛客网
牛客企业服务