【面试系列】Ruby 高频面试题

欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏:

⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题.

⭐️ AIGC时代的创新与未来:详细讲解AIGC的概念、核心技术、应用领域等内容。

⭐️ 全流程数据技术实战指南:全面讲解从数据采集到数据可视化的整个过程,掌握构建现代化数据平台和数据仓库的核心技术和方法。

文章目录

    • [Ruby 初级面试题及附详细解答](#Ruby 初级面试题及附详细解答)
      • [1. Ruby中的变量有哪几种类型?](#1. Ruby中的变量有哪几种类型?)
      • [2. Ruby中的符号(Symbol)是什么?](#2. Ruby中的符号(Symbol)是什么?)
      • [3. 什么是块(Block)?如何定义和使用?](#3. 什么是块(Block)?如何定义和使用?)
      • [4. Ruby中什么是Proc和Lambda?它们有何区别?](#4. Ruby中什么是Proc和Lambda?它们有何区别?)
      • [5. 如何定义和调用Ruby中的方法?](#5. 如何定义和调用Ruby中的方法?)
      • [6. Ruby中的类和模块有什么区别?](#6. Ruby中的类和模块有什么区别?)
      • [7. 如何在Ruby中进行字符串插值?](#7. 如何在Ruby中进行字符串插值?)
      • [8. Ruby中的迭代器是什么?举个例子。](#8. Ruby中的迭代器是什么?举个例子。)
      • [9. Ruby中的异常处理如何实现?](#9. Ruby中的异常处理如何实现?)
      • [10. 如何在Ruby中定义和使用哈希?](#10. 如何在Ruby中定义和使用哈希?)
    • [Ruby 中级面试题及详细解答](#Ruby 中级面试题及详细解答)
      • [1. 解释 Ruby 的模块(Module)是什么,以及它们如何用于混入(Mixins)?](#1. 解释 Ruby 的模块(Module)是什么,以及它们如何用于混入(Mixins)?)
      • [2. 如何在 Ruby 中创建并使用自定义异常?](#2. 如何在 Ruby 中创建并使用自定义异常?)
      • [3. 解释 Ruby 的块(Block)、Proc 和 Lambda 之间的区别。](#3. 解释 Ruby 的块(Block)、Proc 和 Lambda 之间的区别。)
      • [4. 什么是 Ruby 的元编程?请举例说明。](#4. 什么是 Ruby 的元编程?请举例说明。)
      • [5. 如何在 Ruby 中实现单例模式?](#5. 如何在 Ruby 中实现单例模式?)
      • [6. 解释 Ruby 中的 `super` 关键字及其用法。](#6. 解释 Ruby 中的 super 关键字及其用法。)
      • [7. 什么是 Ruby 中的 `method_missing` 方法?如何使用它?](#7. 什么是 Ruby 中的 method_missing 方法?如何使用它?)
      • [8. 如何在 Ruby 中处理文件读写操作?](#8. 如何在 Ruby 中处理文件读写操作?)
      • [9. Ruby 中的 `self` 关键字有什么用?](#9. Ruby 中的 self 关键字有什么用?)
      • [10. 解释 Ruby 中的垃圾回收机制。](#10. 解释 Ruby 中的垃圾回收机制。)
    • [Ruby 高级面试题及详细解答](#Ruby 高级面试题及详细解答)
      • [1. 解释 Ruby 中的 `method_missing` 方法。它有什么用处?如何使用它?](#1. 解释 Ruby 中的 method_missing 方法。它有什么用处?如何使用它?)
      • [2. Ruby 中的 `self` 关键字是什么意思?它在不同上下文中的含义是什么?](#2. Ruby 中的 self 关键字是什么意思?它在不同上下文中的含义是什么?)
      • [3. 什么是模块(Module)中的 `include` 和 `extend` 方法?它们有何区别?](#3. 什么是模块(Module)中的 includeextend 方法?它们有何区别?)
      • [4. 如何在 Ruby 中实现单例模式?提供一个示例。](#4. 如何在 Ruby 中实现单例模式?提供一个示例。)
      • [5. Ruby 中的 `Proc` 和 `Lambda` 有什么区别?](#5. Ruby 中的 ProcLambda 有什么区别?)
      • [6. Ruby 中的 `super` 关键字如何工作?提供一个示例。](#6. Ruby 中的 super 关键字如何工作?提供一个示例。)
      • [7. Ruby 中的 `method` 和 `define_method` 有什么不同?](#7. Ruby 中的 methoddefine_method 有什么不同?)
      • [8. 解释 Ruby 中的 `Enumerable` 模块及其常用方法。](#8. 解释 Ruby 中的 Enumerable 模块及其常用方法。)
      • [9. 解释 Ruby 中的垃圾回收机制。](#9. 解释 Ruby 中的垃圾回收机制。)
      • [10. 如何在 Ruby 中处理多线程?简要描述线程同步的方法。](#10. 如何在 Ruby 中处理多线程?简要描述线程同步的方法。)
    • 主要知识点梳理
      • [1. 基础语法和数据类型](#1. 基础语法和数据类型)
      • [2. 控制流和迭代](#2. 控制流和迭代)
      • [3. 方法和块](#3. 方法和块)
      • [4. 面向对象编程](#4. 面向对象编程)
      • [5. 错误处理](#5. 错误处理)
      • [6. 文件和 I/O 操作](#6. 文件和 I/O 操作)
      • [7. 元编程](#7. 元编程)
      • [8. 数据库操作](#8. 数据库操作)
      • [9. 测试和调试](#9. 测试和调试)
      • [10. Ruby 生态系统](#10. Ruby 生态系统)
      • [11. 性能优化和内存管理](#11. 性能优化和内存管理)

Ruby 初级面试题及附详细解答

1. Ruby中的变量有哪几种类型?

Ruby中有四种类型的变量:局部变量(local variables),全局变量(global variables),实例变量(instance variables),和类变量(class variables)。
解答:

  • 局部变量:以小写字母或下划线开头,仅在定义它的块、方法或类中有效。
  • 全局变量 :以$开头,可以在程序的任何地方访问和修改。
  • 实例变量 :以@开头,只在特定的对象实例中有效。
  • 类变量 :以@@开头,在类及其子类的实例之间共享。

2. Ruby中的符号(Symbol)是什么?

符号是不可变的、唯一的标识符,通常用于哈希键或常量。

解答:

符号以冒号(:)开头,如:symbol。它们比字符串更高效,因为它们在内存中只存储一次,适合用作哈希键等需要重复使用的地方。

3. 什么是块(Block)?如何定义和使用?

块是封装了一组代码的匿名函数,可以作为方法的参数传递。

** 解答:**

块可以用大括号 {}do...end 包围。通常与方法一起使用,如:

ruby 复制代码
[1, 2, 3].each { |num| puts num }

ruby 复制代码
[1, 2, 3].each do |num|
  puts num
end

4. Ruby中什么是Proc和Lambda?它们有何区别?

Proc和Lambda都是用于封装代码块的对象,但在参数处理和返回行为上有区别。

解答:

  • Proc :用Proc.newproc创建。返回时,退出整个方法。
  • Lambda :用lambda->创建。返回时,退出lambda本身。对参数数量要求严格。
ruby 复制代码
pr = Proc.new { |x, y| puts x + y }
lm = lambda { |x, y| puts x + y }

5. 如何定义和调用Ruby中的方法?

def关键字定义方法,方法名后跟参数列表,用end结束定义。

解答:

ruby 复制代码
def greet(name)
  "Hello, #{name}!"
end

puts greet("Alice")

输出:Hello, Alice!

6. Ruby中的类和模块有什么区别?

类用于创建对象,模块用于组织和重用代码,但不能实例化。

解答:

  • :使用class关键字定义,可以创建对象实例。
  • 模块 :使用module关键字定义,不能实例化。用于包含方法和常量,可用includeextend混入类。
ruby 复制代码
module Greetings
  def hello
    "Hello!"
  end
end

class Person
  include Greetings
end

p = Person.new
puts p.hello  # Output: Hello!

7. 如何在Ruby中进行字符串插值?

使用#{}语法在字符串中插入变量或表达式的值。

解答:

ruby 复制代码
name = "Alice"
puts "Hello, #{name}!"  # Output: Hello, Alice!

8. Ruby中的迭代器是什么?举个例子。

迭代器是用于遍历集合(如数组、哈希)的方法。

解答:

常见迭代器如eachmapselect。示例:

ruby 复制代码
[1, 2, 3].each { |num| puts num }

输出:1\n2\n3

9. Ruby中的异常处理如何实现?

begin...rescue...end结构来处理异常。

解答:

ruby 复制代码
begin
  # 可能引发异常的代码
  result = 10 / 0
rescue ZeroDivisionError => e
  puts "Error: #{e.message}"
end

输出:Error: divided by 0

10. 如何在Ruby中定义和使用哈希?

用大括号 {} 定义哈希,键值对用冒号或箭头表示。

解答:

ruby 复制代码
hash = { key1: 'value1', key2: 'value2' }
puts hash[:key1]  # Output: value1

这些问题涵盖了Ruby编程中的基本概念和操作,通过这些问题和详细解答,可以帮助初学者在面试中表现得更好。

Ruby 中级面试题及详细解答

1. 解释 Ruby 的模块(Module)是什么,以及它们如何用于混入(Mixins)?

解答

模块是一个可以包含方法、类、常量和其他模块的集合。它们不能被实例化,但可以被包含到类中。通过 includeextend,模块可以将其方法混入类中,实现代码重用和多重继承。

ruby 复制代码
module Greet
  def greet
    "Hello!"
  end
end

class Person
  include Greet
end

p = Person.new
p.greet # => "Hello!"

2. 如何在 Ruby 中创建并使用自定义异常?

解答

自定义异常类需要继承自 StandardError 或其子类。创建自定义异常后,可以使用 raise 关键字引发异常,并使用 rescue 关键字捕获异常。

ruby 复制代码
class CustomError < StandardError; end

begin
  raise CustomError, "Something went wrong"
rescue CustomError => e
  puts e.message
end

3. 解释 Ruby 的块(Block)、Proc 和 Lambda 之间的区别。

解答

块(Block)是匿名代码块,可以传递给方法。Proc 是一个可以存储代码块的对象。Lambda 是一种特殊的 Proc,具有更严格的参数检查和返回行为。

ruby 复制代码
def example_block
  yield
end

example_block { puts "Block" }

proc = Proc.new { puts "Proc" }
proc.call

lambda = -> { puts "Lambda" }
lambda.call

4. 什么是 Ruby 的元编程?请举例说明。

解答

元编程是编写代码来操作其他代码的技术。Ruby 的元编程允许动态地创建方法、类和修改现有代码。常用的元编程技术包括 define_methodmethod_missing

ruby 复制代码
class MyClass
  define_method(:dynamic_method) do
    "Hello from dynamic method"
  end
end

obj = MyClass.new
puts obj.dynamic_method

5. 如何在 Ruby 中实现单例模式?

解答

可以使用 Singleton 模块来实现单例模式,确保一个类只有一个实例,并提供全局访问点。

ruby 复制代码
require 'singleton'

class SingletonClass
  include Singleton
end

obj1 = SingletonClass.instance
obj2 = SingletonClass.instance

puts obj1 == obj2 # => true

6. 解释 Ruby 中的 super 关键字及其用法。

解答
super 关键字用于调用父类中的同名方法。如果不带参数,super 会传递当前方法的所有参数;带参数时,super 仅传递指定参数。

ruby 复制代码
class Parent
  def greet(name)
    "Hello, #{name}"
  end
end

class Child < Parent
  def greet(name)
    super(name) + " from Child"
  end
end

puts Child.new.greet("John") # => "Hello, John from Child"

7. 什么是 Ruby 中的 method_missing 方法?如何使用它?

解答
method_missing 是当调用一个对象上不存在的方法时被触发的钩子方法。可以在类中重写 method_missing 方法来实现动态方法调用。

ruby 复制代码
class DynamicMethod
  def method_missing(name, *args)
    "You called #{name} with #{args.join(', ')}"
  end
end

obj = DynamicMethod.new
puts obj.undefined_method(1, 2, 3) # => "You called undefined_method with 1, 2, 3"

8. 如何在 Ruby 中处理文件读写操作?

解答

可以使用 File 类来处理文件读写操作。File.open 可以打开文件,并通过块操作确保文件在使用完毕后自动关闭。

ruby 复制代码
# 写入文件
File.open('example.txt', 'w') do |file|
  file.write("Hello, Ruby!")
end

# 读取文件
File.open('example.txt', 'r') do |file|
  content = file.read
  puts content
end

9. Ruby 中的 self 关键字有什么用?

解答
self 关键字引用当前对象。在类方法中,self 引用的是类本身;在实例方法中,self 引用的是实例对象。使用 self 可以明确调用当前对象的方法或访问当前对象的属性。

ruby 复制代码
class MyClass
  def instance_method
    self
  end

  def self.class_method
    self
  end
end

obj = MyClass.new
puts obj.instance_method == obj  # => true
puts MyClass.class_method == MyClass # => true

10. 解释 Ruby 中的垃圾回收机制。

解答

Ruby 使用垃圾回收机制(GC)来自动管理内存。Ruby 的 GC 是基于标记-清除(mark-and-sweep)算法的,并在最新版本中引入了增量和分代垃圾回收机制,以提高性能。GC 会定期扫描堆内存,标记不再使用的对象并释放它们的内存。

ruby 复制代码
# 强制垃圾回收
GC.start

这些题目涵盖了 Ruby 中的一些中级概念,熟练掌握这些知识点可以帮助面试者在 Ruby 面试中表现出色。

Ruby 高级面试题及详细解答

1. 解释 Ruby 中的 method_missing 方法。它有什么用处?如何使用它?

解答:
method_missing 是 Ruby 中一种元编程技术。当调用一个对象上不存在的方法时,会触发 method_missing 方法。它可以用来捕获这些调用,执行一些默认操作或抛出自定义错误。例如,动态代理模式或创建灵活的 API 时常使用它。

ruby 复制代码
class DynamicMethodHandler
  def method_missing(method_name, *args, &block)
    puts "You called: #{method_name} with arguments: #{args.join(', ')}"
  end
end

handler = DynamicMethodHandler.new
handler.foo(1, 2, 3)  # Output: You called: foo with arguments: 1, 2, 3

通过定义 method_missing,可以处理未知的方法调用,增强类的灵活性和扩展性。

2. Ruby 中的 self 关键字是什么意思?它在不同上下文中的含义是什么?

解答:
self 在 Ruby 中指代当前对象。在不同上下文中,self 的含义不同:

  • 在类定义内部self 指代类自身。
  • 在实例方法内部self 指代方法所属的实例。
  • 在类方法内部self 指代当前类。
    例如:
ruby 复制代码
class MyClass
  def self.class_method
    puts "Class method: #{self}"
  end

  def instance_method
    puts "Instance method: #{self}"
  end
end

MyClass.class_method           # Output: Class method: MyClass
MyClass.new.instance_method    # Output: Instance method: #<MyClass:0x...>

理解 self 有助于掌握对象上下文和方法调用机制。

3. 什么是模块(Module)中的 includeextend 方法?它们有何区别?

解答:

  • include:将模块的方法作为实例方法混入类中,使得类的实例可以调用这些方法。
  • extend:将模块的方法作为类方法混入类中,使得类本身可以调用这些方法。
ruby 复制代码
module Greetings
  def hello
    "Hello!"
  end
end

class Person
  include Greetings
end

p = Person.new
puts p.hello  # Output: Hello!

class MyClass
  extend Greetings
end

puts MyClass.hello  # Output: Hello!

include 用于实例方法混入,extend 用于类方法混入,二者分别为实例和类提供功能扩展。

4. 如何在 Ruby 中实现单例模式?提供一个示例。

解答:

单例模式可以通过 Singleton 模块实现,确保一个类只有一个实例。

ruby 复制代码
require 'singleton'

class SingletonClass
  include Singleton
end

instance1 = SingletonClass.instance
instance2 = SingletonClass.instance

puts instance1.equal?(instance2)  # Output: true

通过 Singleton 模块,可以保证类只有一个实例,适用于全局唯一对象的场景。

5. Ruby 中的 ProcLambda 有什么区别?

解答:
ProcLambda 都是闭包,但有一些关键区别:

  • 返回行为Lambda 会从自身返回,而 Proc 会从包含它的方法返回。
  • 参数处理Lambda 检查参数数量,而 Proc 则不会。
ruby 复制代码
pr = Proc.new { return "Returning from Proc" }
lm = lambda { return "Returning from Lambda" }

def call_proc
  pr.call
  "Returning from method"
end

def call_lambda
  lm.call
  "Returning from method"
end

puts call_proc      # Output: Returning from Proc
puts call_lambda    # Output: Returning from method

ProcLambda 的不同特性适用于不同的代码组织和控制流需求。

6. Ruby 中的 super 关键字如何工作?提供一个示例。

解答:
super 调用父类中与当前方法同名的方法。可以传递参数或不传递参数,不传参数时会传递当前方法的所有参数。

ruby 复制代码
class Parent
  def greet(name)
    "Hello, #{name}!"
  end
end

class Child < Parent
  def greet(name)
    super + " How are you?"
  end
end

child = Child.new
puts child.greet("Alice")  # Output: Hello, Alice! How are you?

super 提供了一种调用父类方法的方式,有助于方法的扩展和重用。

7. Ruby 中的 methoddefine_method 有什么不同?

解答:

  • method:获取一个对象的方法对象,用于调用或传递。
  • define_method:动态定义方法,用于运行时创建方法。
ruby 复制代码
class MyClass
  define_method(:dynamic_method) do |arg|
    "Hello, #{arg}!"
  end
end

obj = MyClass.new
puts obj.dynamic_method("Ruby")  # Output: Hello, Ruby!

# Using `method`
m = obj.method(:dynamic_method)
puts m.call("World")  # Output: Hello, World!

method 用于操作已有方法,define_method 用于动态创建方法,提供了灵活的元编程能力。

8. 解释 Ruby 中的 Enumerable 模块及其常用方法。

解答:
Enumerable 模块提供集合遍历、搜索、排序等常用功能。类需要实现 each 方法并包含 Enumerable 模块。

常用方法:

  • map:返回包含块结果的新数组。
  • select:返回包含满足块条件的元素的新数组。
  • reduce:将块应用于集合的每个元素,累计结果。
ruby 复制代码
class MyCollection
  include Enumerable

  def initialize(*items)
    @items = items
  end

  def each
    @items.each { |item| yield item }
  end
end

collection = MyCollection.new(1, 2, 3, 4)
puts collection.map { |x| x * 2 }      # Output: [2, 4, 6, 8]
puts collection.select { |x| x.even? } # Output: [2, 4]

Enumerable 提供强大的集合操作能力,提高代码简洁性和可读性。

9. 解释 Ruby 中的垃圾回收机制。

解答:

Ruby 使用标记-清除(mark-and-sweep)算法进行垃圾回收。垃圾回收器通过标记所有可达对象,然后清除未标记的对象来回收内存。Ruby 2.1 引入了增量式垃圾回收,Ruby 2.2 引入了符号垃圾回收,提升了性能和内存管理。

ruby 复制代码
# Example: Creating and discarding objects
1000.times { Object.new }
GC.start  # Manually trigger garbage collection

理解垃圾回收机制有助于优化内存管理和性能。

10. 如何在 Ruby 中处理多线程?简要描述线程同步的方法。

解答:

Ruby 使用 Thread 类进行多线程编程。线程同步可以通过互斥量(Mutex)实现,避免多个线程同时访问共享资源导致竞态条件。

ruby 复制代码
mutex = Mutex.new
counter = 0

threads = 10.times.map do
  Thread.new do
    mutex.synchronize do
      temp = counter
      sleep(0.1)
      counter = temp + 1
    end
  end
end

threads.each(&:join)
puts counter  # Output: 10

通过互斥量同步线程,可以安全地访问和修改共享资源,避免并发问题。

主要知识点梳理

在准备 Ruby 面试时,掌握以下知识点至关重要。这些知识点涵盖了从基础到高级的内容,面试者应深入理解和实践,以展示对 Ruby 语言的全面掌握和实际应用能力。

1. 基础语法和数据类型

  • 变量和常量:理解局部变量、全局变量、实例变量和类变量的使用和作用范围。掌握常量的定义和使用。
  • 数据类型 :熟悉 Ruby 的基本数据类型如 StringArrayHashSymbolIntegerFloatBoolean,以及它们的常用方法。
  • 操作符:了解算术操作符、比较操作符、逻辑操作符和位操作符的使用。

2. 控制流和迭代

  • 条件语句 :掌握 ifelseelsifunlesscase 和三元操作符的使用。
  • 循环语句 :熟悉 whileuntilfor 循环,以及迭代器如 eachmapselectrejectreduce 等。

3. 方法和块

  • 方法定义和调用:理解方法的定义、参数传递(包括默认参数和可变参数)、返回值和方法调用。
  • 块、Proc 和 Lambda:了解块(Block)的概念和使用场景,理解 Proc 和 Lambda 的区别和用法,以及它们的创建和调用。

4. 面向对象编程

  • 类和对象 :掌握类的定义、对象的创建、实例变量和类变量的使用,以及 initialize 方法。
  • 继承和模块 :理解类的继承机制,掌握 super 关键字,了解模块(Module)的作用以及 includeextend 的使用。
  • 多态性和接口:了解 Ruby 如何实现多态性,通过鸭子类型(Duck Typing)实现接口。

5. 错误处理

  • 异常处理 :掌握异常的捕获和处理,使用 beginrescueensureraise 关键字处理异常,了解自定义异常类的创建和使用。

6. 文件和 I/O 操作

  • 文件操作 :理解文件的读取和写入,使用 File 类和 IO 类进行文件操作,掌握文件模式(如读、写、追加)。
  • 标准输入输出 :熟悉 putsprintgets 等方法进行标准输入输出操作。

7. 元编程

  • 动态方法 :理解 method_missingdefine_method 的用法,掌握如何动态定义和调用方法。
  • 反射 :了解 send 方法和 respond_to? 方法的使用,通过反射机制操作对象。

8. 数据库操作

  • ActiveRecord:掌握 Ruby on Rails 中的 ActiveRecord 模型,理解 ORM 的基本概念,熟悉常用的数据库操作如查询、插入、更新和删除。
  • 数据库连接:了解如何使用 Ruby 连接和操作不同类型的数据库(如 SQLite、PostgreSQL、MySQL)。

9. 测试和调试

  • 测试框架:掌握常用的测试框架如 RSpec、Minitest 的基本使用,理解单元测试、功能测试和集成测试的区别和用法。
  • 调试技巧 :熟悉调试工具如 byebugpry,掌握如何设置断点、检查变量和堆栈信息。

10. Ruby 生态系统

  • Gem 和 Bundler :理解 RubyGems 的作用,掌握如何使用 gemBundler 管理依赖。
  • Ruby on Rails:了解 Ruby on Rails 框架的基本架构和常用组件,掌握 Rails 应用的创建、配置和部署。

11. 性能优化和内存管理

  • 性能调优 :理解常见的性能问题,掌握性能分析工具如 benchmarkmemory_profiler,了解优化代码性能的方法。
  • 垃圾回收:了解 Ruby 的垃圾回收机制,理解如何调优垃圾回收以提高应用性能。

通过深入理解和实践这些知识点,面试者可以展示对 Ruby 语言的全面掌握,从而在面试中表现出色。熟练掌握这些领域的内容,将有助于应对各种复杂的面试问题和实际编程挑战。

💗💗💗 如果觉得这篇文对您有帮助,请给个点赞、关注、收藏吧,谢谢!💗💗💗

相关推荐
面试鸭1 小时前
离谱!买个人信息买到网安公司头上???
java·开发语言·职场和发展
测试19983 小时前
2024软件测试面试热点问题
自动化测试·软件测试·python·测试工具·面试·职场和发展·压力测试
马剑威(威哥爱编程)4 小时前
MongoDB面试专题33道解析
数据库·mongodb·面试
不能再留遗憾了5 小时前
RabbitMQ 高级特性——消息分发
分布式·rabbitmq·ruby
程序员勋勋5 小时前
【自动化测试】如何在jenkins中搭建allure
职场和发展·jenkins·测试覆盖率
独行soc6 小时前
#渗透测试#SRC漏洞挖掘#深入挖掘XSS漏洞02之测试流程
web安全·面试·渗透测试·xss·漏洞挖掘·1024程序员节
咕咕吖6 小时前
对称二叉树(力扣101)
算法·leetcode·职场和发展
理想不理想v6 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
sszmvb12347 小时前
测试开发 | 电商业务性能测试: Jmeter 参数化功能实现注册登录的数据驱动
jmeter·面试·职场和发展
测试杂货铺7 小时前
外包干了2年,快要废了。。
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展