Skip to content

3)Lua

🧠 第 1 题:Lua 是什么语言?它的定位和优势是什么?

Q1:请简要介绍 Lua,它适合解决什么问题?

📝 参考答案:

Lua 是一种 轻量级、嵌入式、扩展性强的脚本语言,最初由巴西人开发,广泛应用于游戏开发、脚本引擎、配置系统等。

📌 核心特性:

  • 极简核心(整个语言核心不足 300KB)
  • 可嵌入性强(C/C++、Nginx、Redis 等都支持嵌入 Lua)
  • 动态类型、自动垃圾回收
  • 表(table)是唯一的数据结构,灵活但抽象度高

📍 常见应用场景:

  • 游戏开发脚本(如 Roblox、Warcraft)
  • Nginx 的 OpenResty 模块
  • Redis 脚本(EVAL 命令)
  • 嵌入式设备或配置语言

🧱 第 2 题:Lua 的 table 是什么?为什么它是万能的?

Q2:你能解释一下 Lua 中 table 的设计理念和它为何可以实现数组、字典、对象等功能?

📝 参考答案:

在 Lua 中,table 是唯一的数据结构,类似于其他语言中的“数组 + 哈希表 + 对象”三合一。

📌 它的强大之处在于:

  • 支持任意 key(除了 nil 和 NaN)作为键
  • 可用作数组(1-based 数组)、字典(key-value)、对象(metatable 模拟类)
  • 能实现面向对象编程、模块、闭包、协程等高级功能

🎯 举个例子:

lua
local t = {name = "Alice", age = 30}
t[1] = "hello"     -- 数组形式
print(t["name"])   -- 字典形式

✨ 类比思维:

Lua 的 table 就像一块黏土,能随你需要捏成各种形状:数组、字典、对象,功能全靠你“如何使用”。

🔁 第 3 题:Lua 如何实现与 C/C++ 的交互?

Q3:Lua 是怎么与 C/C++ 打通的?请简单介绍底层调用流程?

📝 参考答案:

Lua 设计之初就考虑嵌入性,因此可以通过 C API 嵌入到 C/C++ 程序中:

📌 简要流程:

  1. 在 C 中创建 Lua 虚拟机(luaL_newstate()
  2. 加载脚本或代码字符串(luaL_dofile() / luaL_loadstring()
  3. 调用脚本函数并从栈中取出结果(lua_getglobal()lua_pcall()
  4. 也可以把 C 函数注册给 Lua 脚本调用(lua_register()

💡 项目中常见:

  • 游戏客户端调用 Lua 脚本控制逻辑
  • 嵌入设备中 Lua 脚本用来控制底层硬件命令

🌐 第 4 题:Lua 在 Nginx 和 Redis 中是如何使用的?

Q4:请简要说说你对 OpenResty 和 Redis 中 Lua 脚本的理解与使用?

📝 参考答案:

🌀 OpenResty(基于 Nginx + LuaJIT)

  • 将 Lua 嵌入到 Nginx 的请求处理流程中
  • 支持异步非阻塞调用、灵活处理请求逻辑
  • 常用于实现灰度发布、限流、WAF、防爬虫逻辑

示例:

lua
local token = ngx.req.get_headers()["Authorization"]
if not token then
    ngx.exit(ngx.HTTP_UNAUTHORIZED)
end

🧠 Redis 中的 Lua

  • 使用 EVAL 命令执行 Lua 脚本,实现原子性操作
  • 常用于:分布式锁、流水线操作、限流算法
lua
-- Redis 限流脚本
local current = redis.call("incr", KEYS[1])
if current > tonumber(ARGV[1]) then
    return 0
end
redis.call("expire", KEYS[1], ARGV[2])
return 1

🧩 第 5 题:用 Lua 实现一个限流算法,你会怎么设计?

Q5:请用 Lua 实现一个固定窗口或滑动窗口限流算法(如 Nginx/Redis 使用场景)?

📝 参考实现:固定窗口限流(基于 Redis)

lua
-- KEYS[1]: 限流 key,如 "ip:127.0.0.1"
-- ARGV[1]: 最大次数
-- ARGV[2]: 时间窗口(秒)

local current = redis.call("incr", KEYS[1])
if current == 1 then
    redis.call("expire", KEYS[1], ARGV[2])
end
if current > tonumber(ARGV[1]) then
    return 0  -- 拒绝
end
return 1  -- 放行

🎯 实践中,可以将它封装为 OpenResty 限流中间件或 Redis 限流网关脚本。

🧠 总结思维图:Lua 面试五维分析

维度内容
基础动态脚本语言,轻量可嵌入,核心是 table
进阶与 C/C++ 交互、面向对象、模块化
实战Redis 脚本、OpenResty 流量控制
类比黏土(万能结构)、接线员(脚本调控逻辑)
应用游戏脚本、配置语言、限流算法、自动化脚本