lua 语法介绍与 NGINX lua 高级用法实战操作

文章目录

    • 一、概述
    • 二、lua 安装
    • 三、lua 语法
      • 1)lua 数据类型
      • 2)lua 变量
      • 3)lua 拼接字符串
      • 4)lua 循环
      • 5)lua 函数
      • 6)lua 条件控制
      • 7)lua 库模块
    • 四、NGINX lua 高级用法

一、概述

lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

官网:https://www.lua.org/

在这里插入图片描述

二、lua 安装

curl -L -R -O https://www.lua.org/ftp/lua-5.4.6.tar.gz
tar zxf lua-5.4.6.tar.gz
cd lua-5.4.6
make all test

测试

vim hello.lua
# 添加打印
print("Hello World!")

# 运行
lua hello.lua

命令模式

lua

三、lua 语法

1)lua 数据类型

Lua 是一种轻量级的脚本语言,具有简洁、灵活的数据类型。以下是 Lua 中的一些基本数据类型:

类型描述示例
nil表示没有值或者一个无效的值。在 Lua 中,变量默认初始化为 nil。local myVar = nil
布尔类型(boolean)有两个值,true 和 false。local isTrue = true
local isFalse = false
数字类型(number)表示整数或浮点数。local integerNumber = 42
local floatNumber = 3.14
字符串类型(string)由字符组成的序列。
字符串可以使用单引号或双引号定义。
也可以使用双方括号定义长字符串。
local myString = “Hello, Lua!”
local singleQuoted = ‘Single quoted string’
local doubleQuoted = “Double quoted string”
local longString = [[
This is a long string
that spans multiple lines.
]]
表(table)类似于字典或关联数组,是 Lua 中唯一的复杂数据结构。local myTable = {key1 = “value1”, key2 = “value2”}
#表中的元素可以通过键来访问。
print(myTable.key1) – 输出: value1
函数(function)表示一个可执行的代码块。local function add(a, b)
return a + b
end

local result = add(3, 4)
print(result) – 输出: 7

这些基本数据类型的组合和使用,以及 Lua 提供的灵活的表达式和控制结构,使得 Lua 成为编写脚本、配置文件、嵌入式系统等场景的理想语言。在使用 Lua 进行编程时,熟悉这些数据类型的特性和用法是很重要的。

2)lua 变量

Lua 中,变量是用来存储数据值的标识符。Lua 是一种动态类型的脚本语言,因此不需要显式声明变量的类型。以下是一些关于 Lua 变量的基本规则和示例:

  1. 变量命名规则: 变量名是由字母、数字和下划线组成的字符串,不能以数字开头。Lua 是大小写敏感的,因此 myVariableMyVariable 被视为不同的变量。

  2. 变量声明和赋值: 变量可以直接赋值,不需要事先声明。如果尝试访问一个尚未赋值的变量,其值将为 nil

myVariable = 42
anotherVariable = "Hello, Lua!"
  1. 多重赋值Lua 支持多重赋值,可以在一行中给多个变量赋值。
a, b, c = 1, 2, 3

此时,a 的值为 1,b 的值为 2,c 的值为 3。

  1. 全局变量和局部变量: 默认情况下,所有变量都是全局的。如果需要创建一个局部变量,可以使用关键字 local
local localVar = "I am local"

局部变量的作用范围限定在声明它的代码块内,而全局变量在整个程序中可见。

  1. nil 值: 在 Lua 中,未初始化的变量的值为 nil,表示没有值或无效值。
local uninitializedVar
print(uninitializedVar)  -- 输出: nil
  1. 删除变量Lua 没有提供直接删除变量的语法,但可以将变量赋值为 nil,以释放其内存。
myVariable = nil

这些是 Lua 中使用变量的基本规则。在实际编程中,注意作用域、避免全局变量滥用、使用有意义的变量名等是良好的编程习惯。

3)lua 拼接字符串

Lua 中,可以使用不同的方法来拼接字符串。以下是一些常见的字符串拼接方法:

  1. 使用 .. 运算符: Lua 中的字符串拼接可以使用 .. 运算符。这个运算符将两个字符串连接在一起。
local str1 = "Hello, "
local str2 = "Lua!"
local result = str1 .. str2
print(result)  -- 输出: Hello, Lua!
  1. 使用 string.format 函数string.format 函数可以用于格式化字符串,也可以用来拼接字符串。
local name = "John"
local age = 25
local result = string.format("My name is %s and I am %d years old.", name, age)
print(result)  -- 输出: My name is John and I am 25 years old.
  1. 使用 … 运算符连接多个字符串: 可以使用 .. 运算符连接多个字符串,形成更复杂的拼接。
local part1 = "Hello, "
local part2 = "how are "
local part3 = "you?"
local result = part1 .. part2 .. part3
print(result)  -- 输出: Hello, how are you?
  1. 使用表连接字符串: 将字符串存储在表中,然后使用 table.concat 函数进行连接。
local strings = {"Hello, ", "Lua!"}
local result = table.concat(strings)
print(result)  -- 输出: Hello, Lua!
  1. 使用迭代连接字符串: 可以使用迭代器将多个字符串连接起来。
local strings = {"Hello, ", "how ", "are ", "you?"}
local result = ""
for _, str in ipairs(strings) do
    result = result .. str
end
print(result)  -- 输出: Hello, how are you?

这些方法中,选择适合你需求的方式来拼接字符串。通常来说,.. 运算符是最简单和直观的方法,而 table.concat 在处理大量字符串时可能更高效。

4)lua 循环

Lua 提供了多种循环结构,可以根据不同的需求选择合适的循环类型。以下是 Lua 中常用的循环结构:

  1. while 循环: 当给定的条件为真时,while 循环会一直执行。
local i = 1
while i <= 5 do
    print(i)
    i = i + 1
end

  1. repeat … until 循环: 与 while 循环类似,但条件在循环结束时进行检查。即使条件一开始就为真,循环至少会执行一次。
local i = 1
repeat
    print(i)
    i = i + 1
until i > 5
  1. for 数值型循环: 遍历数值范围内的值。
for i = 1, 5 do
    print(i)
end

这个例子会输出 1 到 5 的数字。

  1. for 泛型循环: 遍历表中的元素。
local fruits = {"apple", "banana", "orange"}
for index, value in ipairs(fruits) do
    print(index, value)
end

这个例子会输出表中的索引和对应的值。

  • for 迭代器循环: 使用自定义迭代器遍历元素。
function squares(n)
    return function()
        n = n + 1
        return n, n * n
    end
end

for i, square in squares(3) do
    print(i, square)
end

这个例子会输出从 4 开始的平方数。

  1. 循环控制语句Lua 提供了 breakgoto 语句,用于在循环中进行控制流程。
for i = 1, 10 do
    if i == 5 then
        break  -- 跳出循环
    end
    print(i)
end
local i = 1
::mylabel::  -- 定义标签
if i <= 5 then
    print(i)
    i = i + 1
    goto mylabel  -- 跳转到标签
end

请注意,goto 在许多编程环境中被认为是不良实践,因为它可能导致代码不易理解和维护。尽量使用其他循环结构和控制语句来实现代码逻辑。

5)lua 函数

Lua 中,函数是一等公民,可以用来组织和结构化代码。以下是 Lua 中定义和使用函数的基本方法:

  1. 定义函数: 使用 function 关键字来定义函数,后跟函数名和参数列表。函数体包含在 end 关键字之前。
function greet(name)
    print("Hello, " .. name .. "!")
end
  1. 调用函数: 使用函数名和适当的参数列表来调用函数。
greet("John")

这会输出 “Hello, John!”。

  1. 返回值: 函数可以返回一个或多个值。使用 return 语句返回值。
function add(a, b)
    return a + b
end

local result = add(3, 4)
print(result)  -- 输出: 7
  1. 多返回值Lua 支持多返回值。函数可以返回多个值,用逗号分隔。
function multipleValues()
    return 1, 2, 3
end

local a, b, c = multipleValues()
print(a, b, c)  -- 输出: 1 2 3
  1. 匿名函数: 可以使用匿名函数(也称为 lambda 函数)。
local square = function(x)
    return x * x
end

print(square(5))  -- 输出: 25

或者使用箭头函数(Lua 5.2 及以上版本):

local square = (x) => x * x
print(square(5))  -- 输出: 25
  1. 函数作为参数: 可以将函数作为参数传递给其他函数。
function apply(func, value)
    return func(value)
end

local result = apply(square, 5)
print(result)  -- 输出: 25
  1. 可变参数: 使用 ... 表示可变参数。可以在函数内部通过 arg 表来访问这些参数。
function sum(...)
    local total = 0
    for _, value in ipairs{...} do
        total = total + value
    end
    return total
end

print(sum(1, 2, 3, 4, 5))  -- 输出: 15
  1. 闭包(Closure)Lua 支持闭包,即在函数内部定义的函数可以访问外部函数的局部变量。
function outer()
    local x = 10
    function inner()
        return x
    end
    return inner
end

local closure = outer()
print(closure())  -- 输出: 10
  1. 尾调用优化: Lua 支持尾调用优化,即在函数的最后一个动作是调用另一个函数时,不会增加堆栈深度。这有助于避免堆栈溢出。
function factorial_tail_recursive(n, acc)
    acc = acc or 1
    if n <= 1 then
        return acc
    else
        return factorial_tail_recursive(n - 1, n * acc)
    end
end

print(factorial_tail_recursive(5))  -- 输出: 120

这些是 Lua 中函数的基本用法。函数在 Lua 中是非常灵活和强大的工具,它们支持多种编程模式,包括面向对象编程和函数式编程。

6)lua 条件控制

Lua 中的条件控制主要通过ifelseifelse 语句来实现。以下是 Lua 中条件控制的基本语法和示例:

  1. if 语句: 用于执行一个条件表达式,如果条件为真,则执行相应的代码块。
local x = 10

if x > 0 then
    print("x is positive")
end
  1. if-else 语句: 用于执行两个代码块中的一个,取决于条件表达式的结果。
local x = -5

if x > 0 then
    print("x is positive")
else
    print("x is non-positive")
end
  1. if-elseif-else 语句: 用于执行多个条件表达式,选择第一个为真的代码块。
local x = 0

if x > 0 then
    print("x is positive")
elseif x < 0 then
    print("x is negative")
else
    print("x is zero")
end
  1. 嵌套的 if 语句: 可以在一个 if 语句的代码块中嵌套另一个 if 语句。
local x = 10
local y = 5

if x > 0 then
    print("x is positive")
    if y > 0 then
        print("y is also positive")
    end
end
  1. 条件表达式: 条件表达式的结果可以是任何能转换为布尔值的表达式。通常,任何非 nilfalse 的值都被认为是真。
local x = 42

if x then
    print("x is truthy")
else
    print("x is falsy")
end
  1. 短路运算Lua 支持短路运算,即在逻辑表达式中使用 andor 运算符时,如果确定结果的话就不再继续计算。
local x = 5
local y = 10

local result = (x > 0) and (y / x) or 0

print(result)  -- 输出: 2

这些是 Lua 中条件控制的基本用法。条件控制语句允许根据不同的条件执行不同的代码块,使得程序能够根据不同情况做出不同的决策。

7)lua 库模块

Lua 提供了一些核心的库模块,这些模块包含了一些常用的功能,以及用于处理字符串、文件、网络等任务的工具。以下是 Lua 中一些常见的库模块:

  1. string 模块: 提供了字符串处理的函数,包括拼接、查找、替换等操作。
local str1 = "Hello"
local str2 = "Lua"
local result = string.format("%s, %s!", str1, str2)
print(result)  -- 输出: Hello, Lua!
  1. table 模块: 提供了对 Lua 表(table)进行操作的函数,包括排序、连接、查找等操作。
local fruits = {"banana", "apple", "orange"}
table.sort(fruits)
print(table.concat(fruits, ", "))  -- 输出: apple, banana, orange
  1. math 模块: 提供了数学函数,如三角函数、指数函数、对数函数等。
local x = 5
local y = math.sqrt(x)
print(y)  -- 输出: 2.2360679774998
  1. io 模块: 提供了输入和输出的函数,用于读写文件、控制台等。
local file = io.open("example.txt", "w")
file:write("Hello, Lua!")
file:close()

local file = io.open("example.txt", "r")
local content = file:read("*a")
file:close()

print(content)  -- 输出: Hello, Lua!
  1. os 模块: 提供了一些与操作系统相关的函数,如执行系统命令、获取当前时间等。
local currentTime = os.time()
print(currentTime)
  1. debug 模块: 提供了一些用于调试的函数,如获取栈信息、设置断点等。
function foo()
    print(debug.traceback("Stack trace:"))
end

foo()
  1. coroutine 模块: 提供了协程(coroutine)的支持,允许非抢占式的多任务编程。
local co = coroutine.create(function()
    print("Coroutine 1")
    coroutine.yield()
    print("Coroutine 2")
end)

coroutine.resume(co)  -- 输出: Coroutine 1
coroutine.resume(co)  -- 输出: Coroutine 2
  1. package 模块: 提供了 Lua 的模块管理功能,用于加载其他 Lua 文件或库。
local myModule = require("mymodule")
myModule.myFunction()
  1. cjson 模块: cjson有两个模块:cjson和cjson.safe,前者在解析失败后会抛出异常,而后者则返回nil。

文档地址:https://github.com/openresty/lua-cjson

# 解析失败不会抛异常
local cjson = require "cjson.safe"
# 解析失败会抛异常
local cjson = require "cjson"

序列化

local obj = {
        code = 0,
        msg = "请求成功"
}
local json = cjson.encode(obj)

反序列化

local json = '{{"id":10001,"name":"SALSA AIR"}'
-- 反序列化
local obj = cjson.decode(json)


cjson.decode([[{"code":0,"msg":"请求成功"}]])
  1. redis 模块:openResty提供了操作Redis的模块,我们只需要引入该模块就能直接使用:
-- 引入redis模块
local redis = require('resty.redis')
-- 初始化Redis对象
local red = redis:new()
-- 设置redis超时时间
red:set_timeout(1000, 1000, 1000)

封装连接池函数:用来释放Redis连接,其实是释放连接池

-- 关闭redis连接的工具方法,其实是放入连接池
local function close_redis(red)
    local pool_max_idle_time = 10000 -- 连接的空闲时间,单位是毫秒
    local pool_size = 100 --连接池大小
    local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
    if not ok then
        ngx.log(ngx.ERR, "放入redis连接池失败: ", err)
    end
end

封装获取数据的函数

-- 查询redis的方法 ip和port是redis地址,key是查询的key
local function read_redis(ip, port, key)
    -- 获取一个连接
    local ok, err = red:connect(ip, port)
    if not ok then
        ngx.log(ngx.ERR, "连接redis失败 : ", err)
        return nil
    end
    -- 查询redis
    local resp, err = red:get(key)
    -- 查询失败处理
    if not resp then
        ngx.log(ngx.ERR, "查询Redis失败: ", err, ", key = " , key)
    end
    --得到的数据为空处理
    if resp == ngx.null then
        resp = nil
        ngx.log(ngx.ERR, "查询Redis数据为空, key = ", key)
    end
    close_redis(red)
    return resp
end

封装需要密码和db索引的函数

local function read_redis(ip, port, password, db_index, key)
    -- 获取一个连接
    local ok, err = red:connect(ip, port)
    if not ok then
        ngx.log(ngx.ERR, "连接redis失败 : ", err)
        return nil
    end
    -- 密码和选择的库
    red:auth(password)
    red:select(db_index)
    -- 查询redis
    local resp, err = red:get(key)
    -- 查询失败处理
    if not resp then
        ngx.log(ngx.ERR, "查询Redis失败: ", err, ", key = " , key)
    end
    --得到的数据为空处理
    if resp == ngx.null then
        resp = nil
        ngx.log(ngx.ERR, "查询Redis数据为空, key = ", key)
    end
    close_redis(red)
    return resp
end

四、NGINX lua 高级用法

NGINX with Lua 是指在 NGINX 服务器上使用 Lua 编程语言进行定制化开发和扩展功能。Lua 是一种轻量级、高效的脚本语言,可以嵌入到各种应用程序和服务中。通过将 Lua 引擎集成到 NGINX 中,可以实现更灵活的配置、请求处理、身份验证等功能。

在这里插入图片描述

nginx 部署与介绍可以参考我以下几篇文章:

  • NGINX - 高级负载均衡器、Web服务器、反向代理
  • NGINX 路由配置与参数详解(https配置、跨域配置、socket配置)
  • NGINX sub_filter和subs_filter 指令讲解

以下是一些 NGINX with Lua 的常见应用场景:

  1. 请求处理和重写: 使用 Lua 可以编写自定义的请求处理逻辑,例如 URL 重写、参数处理、请求头修改等。通过在 NGINX 配置中嵌入 Lua 脚本,可以实现更高级的请求处理。
location /example {
    content_by_lua_block {
        ngx.say("Hello from NGINX with Lua!")
    }
}
  1. 访问控制和身份验证: Lua 可以用于实现自定义的访问控制逻辑,例如基于用户、IP 地址、请求内容等的身份验证和授权。这使得可以根据具体需求定制灵活的访问策略。
location /admin {
    access_by_lua_block {
        local user = ngx.var.remote_user
        if user ~= "admin" then
            ngx.exit(ngx.HTTP_FORBIDDEN)
        end
    }
}
  1. 响应处理和过滤: Lua 可以用于在 NGINX 接收到后端服务的响应后进行进一步的处理,例如过滤响应内容、修改响应头等。
location /backend {
    proxy_pass http://backend_server;
    body_filter_by_lua_block {
        ngx.arg[1] = string.gsub(ngx.arg[1], "foo", "bar")
    }
}
  1. 动态内容生成: 使用 Lua 可以动态生成内容,例如基于后端服务的响应数据或其他外部数据源。
location /dynamic {
    content_by_lua_block {
        local args = ngx.req.get_uri_args()
        if args["enable_feature"] == "true" then
            ngx.say("Feature is enabled!")
        else
            ngx.say("Feature is disabled.")
        end
    }
}
  1. 调用外部服务: Lua 可以通过 ngx.location.capture 等方式调用外部服务,实现与其他服务的集成。
location /api {
    content_by_lua_block {
        local res = ngx.location.capture("/external-api")
        ngx.say("Response from External API: ", res.body)
    }
}
  1. 高级请求处理: Lua 可以用于更灵活的请求处理,例如在请求处理流程中进行动态的重定向、缓存控制等。
location /dynamic_redirect {
    content_by_lua_block {
        local args = ngx.req.get_uri_args()
        if args["redirect"] == "true" then
            ngx.redirect("/new_location", ngx.HTTP_MOVED_TEMPORARILY)
        else
            ngx.say("No redirection.")
        end
    }
}
  1. 自定义日志: Lua 可以用于自定义 NGINX 的日志记录,以便记录特定信息或格式化日志输出。
http {
    log_by_lua_block {
        ngx.log(ngx.NOTICE, "Custom log message")
    }
    # 其他配置...
}
  1. 反向代理和负载均衡: 使用 Lua 可以对请求进行更复杂的负载均衡策略,例如基于请求参数、cookie 等条件进行动态的反向代理选择。
http {
    upstream backend {
        server backend1;
        server backend2;
    }

    server {
        location / {
            proxy_pass http://backend;
            proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
        }
    }
}
  1. WebSocket 支持: Lua 可以用于处理 WebSocket 连接,实现更高级的 WebSocket 功能。
location /websocket {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    content_by_lua_block {
        -- Lua WebSocket处理逻辑
    }
}
  1. 使用 Lua 第三方库: Lua 可以使用第三方库来扩展功能,例如使用 LuaRocks 安装和使用第三方模块。
http {
    lua_package_path "/path/to/lua/?.lua;;";
    init_by_lua_block {
        require("my_custom_module")
    }
    # 其他配置...
}

这些是 NGINX Lua 模块的一些高级用法。通过结合 Lua 的强大脚本能力和 NGINX 的高性能特性,可以实现各种复杂的定制化需求。注意在使用 Lua 模块时要确保版本兼容性和安全性。

【温馨提示】默认情况下 Nginx 不支持 Lua 模块,需要安装 LuaJIT 解释器,并且重新编译Nginx,或者可使用国人开发的Openrestry

lua 语法介绍与 NGINX lua 高级用法实战操作讲解就先到这里了,有任何疑问也可关注我公众号:大数据与云原生技术分享,进行技术交流,如本篇文章对您有所帮助,麻烦帮忙一键三连(点赞、转发、收藏)~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/367952.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【AI绘画UI+Windows部署】Fooocus:Controlnet原作者结合了sd的开源和Midjourney重新设计的UI

代码&#xff1a;https://github.com/lllyasviel/Fooocus windows一键启动包下载&#xff1a;https://github.com/lllyasviel/Fooocus/releases/download/release/Fooocus_win64_2-1-831.7z B站视频教程&#xff1a;AI绘画入门神器&#xff1a;Fooocus | 简化SD流程&#xff0c…

Boosting semantic human matting with coarse annotations

前向推理在modelscope中开源了&#xff0c;但是训练没开源&#xff0c;且是基于TensorFlow的&#xff0c;复现起来是比较麻烦的。 1.Introduction 分割技术主要集中在像素级二元分类&#xff0c;抠图被建模为前景图像F和背景图像B的加权融合&#xff0c;大多数matte方法采用指…

不做中位剧的腾讯,能靠精品撑起长视频会员吗?

回顾腾讯视频的2023年,马化腾用“厚积薄发”来形容。 在腾讯年会上,马化腾回顾了过去一年长视频业务板块的发展情况,同时也清晰地提出了未来的规划,总结来说就是以下三点: 1、《繁花》《三体》《漫长的季节》是腾讯过去一年特别出彩的剧集,几部大剧撑起了长视频会员业务…

设计模式——2_1 命令(Command)

文章目录 定义图纸一个例子&#xff1a;空调和他的遥控器只有控制面板的空调遥控器可以撤销的操作 碎碎念命令和Runnable命令和事务 定义 把请求封装成一个对象&#xff0c;从而使你可以用不同的请求对客户进行参数化&#xff0c;对请求排队或记录请求日志&#xff0c;以及支持…

Spring Bean 生命周期常见错误

虽然说 Spring 容器上手简单&#xff0c;可以仅仅通过学习一些有限的注解&#xff0c;即可达到快速使用的目的。但在工程实践中&#xff0c;我们依然会从中发现一些常见的错误。尤其当你对 Spring 的生命周期还没有深入了解时&#xff0c;类初始化及销毁过程中潜在的约定就不会…

超越现实,体验无限可能——VMware Workstation 的魅力之旅

随着科技的飞速发展&#xff0c;虚拟化技术已经深入人心&#xff0c;成为现代人工作与学习的必备工具。在这其中&#xff0c;VMware Workstation以其卓越的性能和稳定的运行环境&#xff0c;成为众多电脑爱好者和专业人士的首选。今天&#xff0c;让我们一起探索VMware Worksta…

初探unity中的ECS

ECS是一种软件架构模式&#xff0c;就像MVC一样。ECS最早在游戏《守望先锋》中提及到的相关链接。ECS具体是指实体&#xff08;entity&#xff09;、 组件&#xff08;component&#xff09;和系统&#xff08;system&#xff09;&#xff1a; 实体&#xff1a;实体是一个ID&a…

docker踩坑记录

踩坑记录 1.1 后台启动容器&#xff0c;实际没有启动 现象&#xff1a; 后台启动centos&#xff0c;结果执行docker ps命令&#xff0c;容器没启动。 原因&#xff1a; docker是以容器启动的&#xff0c;必须要有个前台进程&#xff0c;若是全部都是后台deamon守护进程&…

C语言第十七弹---指针(一)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 指针 1、内存和地址 1.1、内存 2、指针变量和地址 2.1、取地址操作符&#xff08;&&#xff09; 2.2、指针变量和解引用操作符&#xff08;*&#xff09;…

数字巨轮航行大数据海洋:数据可视化引领时代潮流

在大数据时代的潮流中&#xff0c;数据可视化如同一艘畅行无阻的科技巨轮&#xff0c;引领我们穿越数字浩瀚的大海&#xff0c;使我们在信息的航程中游刃有余。下面我就从可视化从业者的角度&#xff0c;来简单说说数据可视化是如何帮助我们在大数据时代畅行无阻的。 数据可视化…

Python 数据分析(PYDA)第三版(七)

原文&#xff1a;wesmckinney.com/book/ 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 附录 附录 A&#xff1a;高级 NumPy 原文&#xff1a;wesmckinney.com/book/advanced-numpy 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 此开放访问网络版本的《Pyt…

苹果电脑Mac清理内存怎么清理卸载残留

苹果电脑中的应用程序大部分是可以通过将其拖拽至废纸篓并倾倒来卸载的。但是部分程序在卸载后仍有残留文件&#xff0c;比如support文件和pref设置等文件的。小编今天介绍下苹果电脑清理内存怎么清理卸载残留以及好用的清理技巧分享。 一、苹果电脑清理内存怎么清理卸载残留 …

使用雨云的虚拟主机建设兰空图床

安装前须知 因需要安装FileInfo拓展&#xff0c;因此你需要购买2048MB及以上运存的服务器。 确保MySQL版本高于或等于5.7 什么是兰空图床&#xff1f; Lsky Pro 是一个用于在线上传、管理图片的图床程序&#xff0c;中文名&#xff1a;兰空图床&#xff0c;你可以将它作为自己…

八、访存顺序(Memory Ordering)

前言 这部分的内容比较抽象&#xff0c;很多内容我无法理解&#xff0c;都是直接翻译过来的。虽然难&#xff0c;但是不可不看&#xff0c;如果遇到无法理解的都直接跳过&#xff0c;那后面都无法学习下去了。觉得无法理解是因为目前的知识还很欠缺&#xff0c;到后面具备了这…

MySQL进阶45讲【11】怎么更好地给字符串字段加索引?

1 前言 现在&#xff0c;几乎所有的系统都支持邮箱登录&#xff0c;如何在邮箱这样的字段上建立合理的索引&#xff0c;是我们今天要讨论的问题。 假设&#xff0c;现在维护一个支持邮箱登录的系统&#xff0c;用户表是这么定义的&#xff1a; mysql> create table SUser…

Vulnhub-DC8

信息收集 # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:43:7c:b1, IPv4: 192.168.1.60 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.1.1 00:50:56:c0:00:08 VMware, Inc. 192.168.1.2 00:50:56:f…

java-static关键字

目录​​​​​​​ 1、介绍 2、静态代码块 3、静态代码块初始化时机 3.1、例子一 3.2、例子二 1、介绍 ​​​​​​​static翻译为静态的。static修饰的方法是静态方法。static修饰的变量是静态变量。都可以使用“类名.”的方式访问&#xff0c;当然也可以用引用.的方式…

Android学习之路(27) ProGuard,混淆,R8优化

前言 使用java编写的源代码编译后生成了对于的class文件&#xff0c;但是class文件是一个非常标准的文件&#xff0c;市面上很多软件都可以对class文件进行反编译&#xff0c;为了我们app的安全性&#xff0c;就需要使用到Android代码混淆这一功能。 针对 Java 的混淆&#x…

JavaWeb,Vue的学习(下)

Router路由 路由&#xff08;Router&#xff09;简介 定义&#xff1a;路由就是根据不同的 URL 地址展示不同的内容或页面。通俗理解&#xff1a;路由就像是一个地图&#xff0c;我们要去不同的地方&#xff0c;需要通过不同的路线进行导航。 路由的作用 单页应用程序&…

Flink CEP(基本概念)

Flink CEP 在Flink的学习过程中&#xff0c;我们已经掌握了从基本原理和核心层的DataStream API到底层的处理函数&#xff0c;再到应用层的Table API和SQL的各种手段&#xff0c;可以应对实际应用开发的各种需求。然而&#xff0c;在实际应用中&#xff0c;还有一类更为复…