宣讲家网站 家风建设/2345网址导航设为主页
1 基础知识
标识符:标识符的定义和 C语言相同:字母和下划线_ 开头, 下划线_ + 大写字母一般是lua保留字, 如_VERSION
全局变量:默认情况下,变量总是认为是全局的,不需要申明,给一个变量赋值后即创建了这个全局变量,访问一个没有初始化的全局变量也不会出错,只不过得到的结果是:nil
2 数据类型
数据类型:lua是动态型语言,变量不需要类型定义,直接赋值即可。 值可以存储在变量中,作为参数传递或者结果return
–nil: 无效值, 在条件表达式中相当于false
– boolean: true false, 注意: false 和 nil 看作是 false,其他的都为 true,数字 0 也是 true
– number: 双精度类型的实浮点数 相当于double, 注意:Lua 默认只有一种 number 类型 – double(双精度)类型(默认类型可以修改 luaconf.h 里的定义)
– string:字符串,由一对双引号或者单引号表示
– funtcion: 由c或者lua编写的函数
– userdata:表示任意存储在变量中的c数据结构
– thread:表示执行的独立线路,用于执行协同程序
– table:Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字符串或表类型。
– 在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。
–可以使用type函数测试给定变量或者值的类型:
print(type(“Hello world”))
print(type(66))
print(type(‘66’))
print(type(“66”))
print(type(nil))
2.1 多重赋值
Lua
可以对多个变量同时赋值,变量用逗号
分开,赋值
语句右边的值
会依次赋给左边的变量
。
n = 1
a, b = 10, 2*n
2.2 交换变量
a = 34
b = 12
a, b = b, a
print(a, b) --输出:12 34
3 运算符
3.1 算数运算符
+ 加法
- 减法
* 乘法
/ 除法
% 取余,求出除法的余数
^ 乘幂,计算次方
- 负号,取负值
3.2 逻辑运算符
a = true
b = false
c = nilprint(a and b) -- 与 输出:false
print(a or b) -- 或 输出:true
print(not a) -- 非 输出:false
4 字符串相关
字符串的三种表示方式:
- 单引号间的一串字符
- 双引号间的一串字符
- [[…]] 间的一串字符, 支持换行
4.1 字符串操作
4.1.1字符串拼接: …
print("d" .. "cj")
4.1.2字符串转换
c = tostring(10) -- 数字 转 字符串
print(c)d = tonumber("666") --字符串转数字,若转换失败返回nil
print(d)e = tonumber("abc")
print(e)
输出:
4.1.3 获取字符串长度
str = "dcj666"
print(#str)
print(#"dcj666")
输出:
5 函数
function lua_func_test(n)if 0 == n thenprint("0 == n")return 0else print("1 == n")return nend
end--这与上述是一样的
lua_func_test2 = function(n)if 0 == n thenprint("0 == n")return 0else print("1 == n")return nend
endret = lua_func_test(5)
print(ret)
输出:
函数支持多值返回:
function lua_func_test_02(a, b, c)return a, b, c
end
local i, j, k = lua_func_test_02(11, 22, 33)
print(i, j, k)
输出:
6 Table
lua的table中可以放置任意类型的数据:如number,string,function等
6.1 数字下标:从 1 开始
注意:lua中数组下标从 1 开始
a = {112, {}, function () end, "dcj"}
print(a[1])
print(#a) --获取table元素个数a[1] = 666
print(a[1])table.insert(a, 2, "666") --在a[2]处插入"666"
local s = table.remove(a, 2) --删除a[2]这个元素, 并将删除的元素返回给s
输出:
function做table的元素
funcList = {function(a, b) return a*b end,function(a, b) return a-b end,function(a) return (-a) end
}
print(funcList[1](3,4))
print(funcList[2](3,4))
print(funcList[3](3))
输出:
6.2 table下标:指定下标
前面例子中的table
都只是一些简单的List(列表),每个元素的下标
都是自动从1排列的
实际上,Lua中,下标可以直接在声明时进行指定,像下面这样:
t = {6,7,8,9}
--上面和下面的代码等价
t = {[1] = 6,[2] = 7,[3] = 8,[4] = 9,
}--甚至你可以跳过某些下标
t = {[1] = 6,[3] = 7,[5] = 8,[7] = 9,
}
print(t[7]) --输出9--在声明后赋予元素值也是可以的
t = {}--空的table
t[101] = 10
print(t[101]) --输出10
t = {[1] = 123,[13] = "abc",[666] = "666",
}print("下标为1的元素:",t[1],type(t[1]))
print("下标为13的元素:",t[13],type(t[13]))
print("下标为666的元素:",t[666],type(t[666]))输出:
下标为1的元素: 123 number
下标为13的元素: abc string
下标为666的元素: 666 string
6.3 字符串做下标
前面学习的table下标都是数字,在lua中,下标也可以是字符串:
t = {a1 = "aa",["666"] = "666", -- 666 = "666", 这样会报错["apple"] = 10,banana = 12,pear = 6,
}
--使用["下标"] = 值 和 下标 = 值 都是正确写法, 当第二种方式有歧义时,应该用第一种方式t["new"] = "new values" -- 也可以新增--可以用下面两种方式访问:
print(t["apple"]) --输出10
print(t.apple) --输出10print(t["666"]) --输出666
--print(t.666) --报错print(t["banana"]) --输出12
print(t.banana) --输出12print(t["new"]) --输出new values
t = {apple = {price = 7.52,weight = 2.1,},banana = {price = 8.31,weight = 1.4,year = '2018'},year = '2019',{price = 6.21,weight = 2.5,},
}print(t.price, --输出nilt.apple.price, --输出7.52t.banana.weight, --输出1.4t.year, --输出2019t[1].price, --输出6.21t[1].weight --输出2.5
)print( t["price"], --输出nilt["apple"]["price"], --输出7.52t["banana"]["weight"], --输出1.4t["year"] --输出2019
)
7 全局表 _G
lua中所有的全局变量都在** _G** 这个table中
例如定义一个全局变量a, 在_G这个table中打印出来:
dcj = 666;
print(_G["dcj"])
table自身也是个全局变量,也在_G中, 并且table.insert中的insert函数是table的下标,也可以将insert打印出来:
print(_G["table"])
print(_G["table"]["insert"])
输出:
8 boolean类型
注意:lua中只有false和nil表示假, 其余都为真(0也表示真)
a = true
b = false
c = nulprint(1 < 2)
print(1 > 2)
print(1 >= 2)
print(1 <= 2)
print(1 == 2)
print(1 ~= 2) -- 注意:~=表示不等于print(a and b) -- 与
print(a or b) -- 或
print(not a) -- 非
输出:
b = 1
print(b > 10 and "yes" or "no")b = 11
print(b > 10 and "yes" or "no")
输出:no
yes
9 分支判断
a = 2if a == 1 thenprint("a == 1")
elseif a == 2 thenprint("a == 2")
elseif a == 3 thenprint("a == 3")
elseprint(a)
endif 0 thenprint("0 is true")
end
输出:
a == 2
0 is true
10 循环
10.1 for循环
临时变量名
可以直接在代码区域使用(但不可更改),每次循环会自动加步长值
,并且在到达结束值
后停止循环。
for i = 1, 10, 2 do -- 1表示循环储值,10表示结束值, 2表示步长, i的作用域仅仅在for循环内部print(i)
endprint(i) -- 输出nil,i的作用域仅仅在for循环内部
10.2 while循环
local n = 10while n >= 1 doif n==5 thenbreak --跳出循环endprint(n)n = n - 1 -- lua 不支持 n-- 这种操作
end
输出:
11 迭代器
pairs和ipairs的区别:
:::info
同:都是能遍历集合(表、数组),两者均优先按顺序输出没有key的值;
:::
:::info
异:对于有key的集合:
ipairs从第一个数字key开始,依次输出所有的key+1的键值,遇到字符下标并不会结束遍历,只是不输出而已,如果遇到nil则退出;
pairs无序输出字符类型key或者数字类型key的键值,遇到nil不输出,但不会停止遍历;
:::
11.1 ipairs
t = {"aa", "bb", "cc", "dd", "ee"}for i = 1, #t do --从下标1开始,到下标#t结束(#t表示t的元素个数)print(i, t[i])
end--针对数字下标的数组,可以使用ipairs迭代器
--等同于下面
for i, j in ipairs(t) do -- i表示下标, j存放下标i对应的值print(i, j)
end
输出:
t = {[1] = "aaaaaa",[2] = "bbbbbbb",[3] = "ccccccc",[5] = "ddddddddd" --下标不连续,t[4]为nil,遇到nil会自动停止
}for i, j in ipairs(t) do -- i表示下标, j表示下标i对应的值print(i, j)
endfor i, j in pairs(t) do -- i表示下标, j表示下标i对应的值print(i, j)
end
输出:
结论:
1、ipairs会按照key的顺序输出数据,遇到不连续的数据停止输出;
2、pairs会无序输出所有数据;
table = { [3] = "test3",["test"] = "val1","val3" ,[4] = "val2","val4"
}
print("-----------ipairs----------------")
for k,v in ipairs(table) doprint(k,v)
end
print("-----------pairs----------------")
for k,v in pairs(table) doprint(k,v)
end
结论:
1、pairs和ipairs均优先输出没有key的value;
2、pairs会输出所有的数据,不带key的值按顺序输出,带key的值无序输出;
3、ipairs会跳过字符串的key,按顺序输出数字型key的值;
table = { [6] = "test3",["test"] = "val1","val3" ,[11] = "val2",nil,"val4"
}
print("-----------ipairs----------------")
for k,v in ipairs(table) doprint(k,v)
end
print("-----------pairs----------------")
for k,v in pairs(table) doprint(k,v)
end
输出:
结论:
1、ipairs遇到nil会停止输出;
2、pairs遇到nil不会停止输出;
11.2 pairs
针对字符串做数组下标的数组迭代,使用pairs迭代器
t = {apple = "aa",banana = "bb",water = "cc",
}
for i, j in pairs(t) do -- i表示下标, j存放下标i对应的值print(i, j)
end
输出:
12 多文件调用require
require:
- 运行指定文件
- 末尾不带拓展名
- 目录层级用“.”分隔
- 只会运行一次
- 从package.path中的路径里查找
13 元表、面向对象
t = {a = 66,
}
mt = {__add = function(a, b)return a.a + bend,__index = function(table, key)return 123end
}
setmetatable(t, mt)
print(t+1) --输出67
print(t["dcj"]) --访问一个不存在的下标,会调用__index元方法, 输出123t = {a = 66,
}
mt = {__add = function(a, b)return a.a + bend,__index = {abc = 123,def = 456,},
}
setmetatable(t, mt)
print(t["dcj"]) --__index也可以是个table, 在__index也可以是个table找“dcj”元素,输出nil
print(t["abc"]) --__index也可以是个table, 在__index也可以是个table找“abc”元素, 输出123
print(t["def"]) --__index也可以是个table, 在__index也可以是个table找“def”元素, 输出456
13.1 语法糖:
t = {a = 66,add = function(tab, sum)tab.a = tab.a + sumend,
}t:add(10) -- 等价于 t.add(t, 10), 输出:76
print(t.a)
13.2 面向对象
需要好好理解!!!
bag = {}
bagmt = {put = function(t, item)table.insert(t.items, item)end,take = function(t)return table.remove(t.items, item)end,list = function(t)return table.concat(t.items, ", ")end,clear = function(t)t.items = {}end,
}
bagmt["__index"] = bagmt
function bag.new()local t = {items = {}}setmetatable(t, bagmt) --当调用t中不存在的函数的时候,就回去t的metatable中去找return t
end--bag.new()函数中会新建一个表t,t设置了元表bagmt, bagmt中有四个元方法(put,take,list,clear)
--由于b中没有put这些方法,所以回去bagmt中找
local b = bag.new()
b:put("apple1") --等价于b.put(b, "apple1"), 将"apple1"放入b的items表中
b:put("apple2")
b:put("apple3")
b:put("apple4")print(b:take())print(b:list())
14 数据打包和解包
aaa = 0x11223344
bbb = 0x55667788data = string.pack(">LL", aaa, bbb) --数据打包print("len:", #data)for i=1, #data doprint(i, data:byte(i))
enda, b = string.unpack(">LL", data) --数据解包
str_a = string.format("0x%x", a)
str_b = string.format("0x%x", b)print("str_a: ", str_a)
print("str_b: ", str_b)
输出:
15 C语言与lua的相关调用
15.1 C语言中调用lua
c代码只需要编译一次,lua可以随时改动;因为lua是动态语言。嵌入lua的好处是c只需要写一次代码,编译一次程序,所有的变化都可以通过修改lua的代码.
main.c 中调用math.lua中的函数
/** @Descripttion: xx模块* @Author: cjDong* @Date: 2024-07-15 11:30:05* @LastEditors: cjDong* @LastEditTime: 2024-07-17 14:07:04*/#include <stdio.h>#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"static int call_func(lua_State *L, const char* funcname, int x, int y)
{int ret;lua_getglobal(L, funcname); // 查找lua文件中的全局函数,并压入虚拟栈/* 压栈,传入参数 */lua_pushnumber(L, x);lua_pushnumber(L, y);lua_call(L, 2, 1); /* 执行函数,lua_call 的参数中第二个是参入参数个数,第三个是返回值个数 *//* 取出返回值 */ret = (int)lua_tonumber(L, -1);/*清除返回值的栈*/lua_pop(L, 1);return ret;
}int main(int argc, char *argv[])
{lua_State *L = luaL_newstate(); /* 创建lua虚拟机 */luaL_openlibs(L); /* 加载lua库,比如math库、table库等 *//* 加载lua文件到c语言内存中,进行语法检查,不会编译 */luaL_dofile(L, "math.lua");/* 调用C函数,这个里面会调用lua函数 */call_func(L, "add", 2, 3);call_func(L, "sub", 2, 3);call_func(L, "mul", 2, 3);call_func(L, "div", 2, 3);/* 清除Lua */lua_close(L);return 0;
}
function add(x, y)print("lua: add function\r\n")return x + y
endfunction sub(x, y)print("lua: sub function\r\n")return x - y
endfunction mul(x, y)print("lua: mul function\r\n")return x * y
endfunction div(x, y)print("lua: div function\r\n")return x / y
end
#!/bin/bashgcc -o out main.c -llua -ldl -lm./out
15.2 lua中调用c语言
Q:Lua调用C函数的两种方式?
A:
1、程序主体在C中运行,C函数注册到Lua中。C调用Lua,Lua调用C注册的函数,C得到函数的执行结果。
2、程序主体在Lua中运行,C函数作为库函数供Lua使用。
第一种方式看起来很罗嗦,也很奇怪。既然程序主体运行在C中,而且最终使用的也是C中定义的函数,那么为何要将函数注册给Lua,然后再通过Lua调用函数呢?
相比于第一种方式,第二种方式使用的更加普遍。
一个Lua库(Lua本身所提供的库)实际上是一个定义了若干Lua函数的”chunk”,这些函数通常作为”table”的域来保存。一个C库(C语言编写,注册给Lua使用的库)的实现方式类似于Lua库的实现方式。首先C库中定义提供给Lua使用的函数,其次还需要一个“特殊函数”,它的作用是注册所有C库中的函数,并将它们存储在适当的位置(类似于Lua库中的函数作为”table”的域来保存)。
Lua可以调用C库中的函数,就是通过这个注册的过程实现的。一旦C函数注册到Lua中,Lua就可以直接通过C函数的引用获取到C函数的地址(这也是我们注册的意义,将C函数的地址提供给Lua)。换句话说,一旦C函数注册,Lua调用他们不依赖于函数名,”package”位置,或者是可见规则。
以上两种方式下面都会列举对应的例子,理解第一种方式,将有助于你理解第二种方式的实现流程。
Q:从Lua中调用C所遵循的规则?
A:当C调用Lua函数的时候,必须遵循一些简单的协议来传递参数和获取返回结果。同样的,从Lua中调用C函数,也必须遵循一些协议来传递参数和获得返回结果。此外,从Lua调用C函数我们必须注册函数,也就是说,我们必须把C函数的地址以一个适当的方式传递给Lua解释器。
任何在Lua中注册的C函数必须有同样的原型,
typedef int (*lua_CFunction) (lua_State *L); // 定义在"lua.h"中。
被注册的C函数接收一个单一的lua_State类型的参数,同时返回一个表示返回值个数的数字。函数在将返回值入栈之前无需清理栈,在函数返回之后,Lua会自动清除栈中返回结果下面的所有内容。
15.2.1 方式1:程序主体在C中运行
该方式看起来很罗嗦,也很奇怪。既然程序主体运行在C中,而且最终使用的也是C中定义的函数,那么为何要将函数注册给Lua,然后再通过Lua调用函数呢?
15.2.2 方式2:程序主体在Lua中运行
该方式使用的更加普遍
#include <stdio.h>
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>/* 所有注册给Lua的C函数具有* "typedef int (*lua_CFunction) (lua_State *L);"的原型。*/
static int l_sin(lua_State *L)
{ // 如果给定虚拟栈中索引处的元素可以转换为数字,则返回转换后的数字,否则报错。double d = luaL_checknumber(L, 1);lua_pushnumber(L, sin(d)); /* push result *//* 这里可以看出,C可以返回给Lua多个结果,* 通过多次调用lua_push*(),之后return返回结果的数量。*/return 1; /* number of results */
}/* 需要一个"luaL_Reg"类型的结构体,其中每一个元素对应一个提供给Lua的函数。* 每一个元素中包含此函数在Lua中的名字,以及该函数在C库中的函数指针。* 最后一个元素为“哨兵元素”(两个"NULL"),用于告诉Lua没有其他的函数需要注册。*/
static const struct luaL_Reg mylib[] = {{"mysin", l_sin},{NULL, NULL}
};/* 此函数为C库中的“特殊函数”。* 通过调用它注册所有C库中的函数,并将它们存储在适当的位置。* 此函数的命名规则应遵循:* 1、使用"luaopen_"作为前缀。* 2、前缀之后的名字将作为"require"的参数。*/
extern int luaopen_mylib(lua_State* L)
{/* void luaL_newlib (lua_State *L, const luaL_Reg l[]);* 创建一个新的"table",并将"mylib"中所列出的函数注册为"table"的域。*/ luaL_newlib(L, mylib);return 1;
}
--[[ 这里"require"的参数对应C库中"luaopen_mylib()"中的"mylib"。C库就放在"main.lua"的同级目录,"require"可以找到。
]]local mylib = require "mylib"-- 结果与上面的例子中相同,但是这里是通过调用C库中的函数实现。
print(mylib.mysin(3.14 / 2)) --> 0.99999968293183
gcc math.c -fPIC -shared -o mylib.so -Walllua main.lua
相关文章:

Lua基础知识入门
1 基础知识 标识符:标识符的定义和 C语言相同:字母和下划线_ 开头, 下划线_ 大写字母一般是lua保留字, 如_VERSION 全局变量:默认情况下,变量总是认为是全局的,不需要申明,给一个变…...

【机器学习实战】Datawhale夏令营2:深度学习回顾
#DataWhale夏令营 #ai夏令营 文章目录 1. 深度学习的定义1.1 深度学习&图神经网络1.2 机器学习和深度学习的关系 2. 深度学习的训练流程2.1 数学基础2.1.1 梯度下降法基本原理数学表达步骤学习率 α梯度下降的变体 2.1.2 神经网络与矩阵网络结构表示前向传播激活函数…...

开发扫地机器人系统时无法兼容手机解决方案
在开发扫地机器人系统时,遇到无法兼容手机的问题,可以从以下几个方面寻求解决方案: 一、了解兼容性问题根源 ① 操作系统差异:不同手机可能运行不同的操作系统(如iOS、Android),且即使是同一操…...

Elasticsearch 角色和权限管理
在大数据和云计算日益普及的今天,Elasticsearch 作为一款强大的开源搜索引擎和数据分析引擎,被广泛应用于日志分析、全文搜索、实时监控等领域。随着业务规模的扩大和数据敏感性的增加,对 Elasticsearch 的访问控制和权限管理也变得越来越重要…...

华为HCIP Datacom H12-821 卷42
42.填空题 如图所示,MSTP网络中SW1为总根,请将以下交换机与IST域根和主桥配对。 参考答案:主桥1468 既是IST域根又是主桥468 既不是又不是就是25 解析: 主桥1468 既是IST域根又是主桥468 既不是又不是就是25 43.填空题 网络有…...

【精品资料】物业行业BI大数据解决方案(43页PPT)
引言:物业行业BI(Business Intelligence,商业智能)大数据解决方案是专为物业管理公司设计的一套综合性数据分析与决策支持系统。该解决方案旨在通过集成、处理、分析及可视化海量数据,帮助物业企业提升运营效率、优化资…...

推荐一款处理TCP数据的架构--EasyTcp4Net
EasyTcp4Net是一个基于c# Pipe,ReadonlySequence的高性能Tcp通信库,旨在提供稳定,高效,可靠的tcp通讯服务。 基础的消息通讯 重试机制 超时机制 SSL加密通信支持 KeepAlive 流量背压控制 粘包和断包处理 (支持固定头处理,固定长度处理,固定字符处理) 日志支持Pipe &…...

2、电脑各部件品牌介绍 - 计算机硬件品牌系列文章
笔者是一个电脑IT达人,对于电脑硬件挺感兴趣,今天有必要讲讲关于电脑各部件的品牌问题。关于电脑硬件介绍,见博文版块:计算机硬件系列 。下面对电脑的各部件品牌等进行介绍,便于大家选购电脑的时候做参考。 1、 CPU&am…...

Git【撤销远程提交记录】
在实际开发中,你是否遇到过错误的提交了代码,想要删掉本次提交记录的情况,你可以按照如下方法实现。 1、使用 git revert 如果你想要保留历史记录,并且对远程仓库其他使用者的影响最小,你可以使用 git revert 命令。这…...

java基础学习:序列化之 - Fast serialization
在Java中,序列化是将对象的状态转换为字节流的过程,以便保存到文件、数据库或通过网络传输。Java标准库提供了java.io.Serializable接口和相应的机制来进行序列化和反序列化。然而,标准的Java序列化机制性能较低,并且生成的字节流…...

Microsoft Build 2024 推出 .NET 9:Tensor<T>、 OpenAI Collaboration和.NET Aspire
在 Microsoft Build 2024 上,.NET 9 4 发布,引入了用于深度学习的 Tensor 类型以及与 OpenAI Collaboration实现GPT4o和Assistants v2等功能。这些最新改进还带来了 .NET Aspire,简化了云原生应用开发。更新涵盖 ASP.NET Core、Blazor 和 .NE…...

【Neural signal processing and analysis zero to hero】- 2
Nonstationarities and effects of the FT course from youtube: 传送地址 why we need extinguish stationary and non-stationary signal, because most of neural signal is non-stationary. Welch’s method for smooth spectral decomposition Full FFT method y…...

好用的AI搜索引擎
1. 360AI 搜索 访问 360AI 搜索: https://www.huntagi.com/sites/1706642948656.html 360AI 搜索介绍: 360AI 搜索,新一代智能答案引擎,值得信赖的智能搜索伙伴,为复杂搜索提供专业支持,解锁更相关、更全面的答案。AI…...

十、Java集合 ★ ✔(模块18-20)【泛型、通配符、List、Set、TreeSet、自然排序和比较器排序、Collections、可变参数、Map】
day05 泛型,数据结构,List,Set 今日目标 泛型使用 数据结构 List Set 1 泛型 1.1 泛型的介绍 ★ 泛型是一种类型参数,专门用来保存类型用的 最早接触泛型是在ArrayList,这个E就是所谓的泛型了。使用ArrayList时,只要给E指定某一个类型…...

阿里云开源 Qwen2-Audio 音频聊天和预训练大型音频语言模型
Qwen2-Audio由阿里巴巴集团Qwen团队开发,它能够接受各种音频信号输入,对语音指令进行音频分析或直接文本回复。与以往复杂的层次标签不同,Qwen2-Audio通过使用自然语言提示简化了预训练过程,并扩大了数据量。 喜好儿网 Qwen2-Au…...

SpringBoot集成MQTT实现交互服务通信
引言 本文是springboot集成mqtt的一个实战案例。 gitee代码库地址:源码地址 一、什么是MQTT MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe&…...

python实现插入排序、快速排序
python实现插入排序、快速排序 算法步骤: Python实现插入排序快速排序算法步骤: Python实现快速排序算法时间复杂度 插入排序是一种简单直观的排序算法。它的基本思想是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫…...

Spring Boot集成kudu快速入门Demo
1.什么是kudu 在Kudu出现前,由于传统存储系统的局限性,对于数据的快速输入和分析还没有一个完美的解决方案,要么以缓慢的数据输入为代价实现快速分析,要么以缓慢的分析为代价实现数据快速输入。随着快速输入和分析场景越来越多&a…...

html超文本传输协议
在今天的Web开发学习中,我掌握了一些HTML和CSS的基础知识,下面我将分享我的学习笔记,帮助大家快速构建一个简单的Web界面。 一、HTML基础标签 1. 网站头 使用<title>标签定义网页的标题。 html <title>我的第一个网页</t…...

利用AI辅助制作ppt封面
如何利用AI辅助制作一个炫酷的PPT封面 标题使用镂空字背景替换为动态视频 标题使用镂空字 1.首先,新建一个空白的ppt页面,插入一张你认为符合主题的图片,占满整个可视页面。 2.其次,插入一个矩形,右键选择设置形状格式…...

【spring boot】初学者项目快速练手
一小时带你从0到1实现一个SpringBoot项目开发_哔哩哔哩_bilibili 一、简介 二、项目结构 三、代码结构 1.生成框架 Spring Initializr 快速生成一个初始的项目代码,会生成一个demo文件 打开intellj idea,导入demo文件 2.目录结构 源码都放在src-ma…...

Laravel+swoole 实现websocket长链接
需要使用 swoole 扩展 我使用的是 swoole 5.x start 方法启动服务 和 定时器 调整 listenQueue 定时器可以降低消息通讯延迟 定时器会自动推送队列里面的消息 testMessage 方法测试给指定用户推送消息 使用 laravel console 启动 <?phpnamespace App\Console\Comman…...

【C#】Array和List
C#中的List<T>和数组(T[])在某些方面是相似的,因为它们都是用来存储一系列元素的集合。然而,它们在功能和使用上有一些重要的区别: 数组(Array) 固定大小:数组的大小在声明时…...

SpringCloud网关的实现原理与使用指南
Spring Cloud网关是一个基于Spring Cloud的微服务网关,它是一个独立的项目,可以对外提供API接口服务,负责请求的转发和路由。本文将介绍Spring Cloud网关的实现原理和使用指南。 一、Spring Cloud网关的实现原理 Spring Cloud网关基于Spring…...

LabVIEW 与 PLC 通讯方式
在工业自动化中,LabVIEW 与 PLC(可编程逻辑控制器)的通信至关重要,常见的通信方式包括 OPC、Modbus、EtherNet/IP、Profibus/Profinet 和 Serial(RS232/RS485)。这些通信协议各有特点和应用场景,…...

数据结构初阶·排序算法(内排序)
目录 前言: 1 冒泡排序 2 选择排序 3 插入排序 4 希尔排序 5 快速排序 5.1 Hoare版本 5.2 挖坑法 5.3 前后指针法 5.4 非递归快排 6 归并排序 6.1递归版本归并 6.2 非递归版本归并 7 计数排序 8 排序总结 前言: 目前常见的排序算法有9种…...

PL/SQL oracle上多表关联的一些记录
1.记录自己在PL/SQL上写的几张表的关联条件没有跑出来的一些优化 1. join后面跟上筛选条件 left join on t1.id t2.id and --- 带上分区字段,如 t1.month 202405, 操作跑不出来的一些问题,可能是数据量过大,未做分区过滤 2. 创建…...

Java.Net.UnknownHostException:揭开网络迷雾,解锁异常处理秘籍
在Java编程的浩瀚宇宙中,java.net.UnknownHostException犹如一朵不时飘过的乌云,让开发者在追求网络畅通无阻的道路上遭遇小挫。但别担心,今天我们就来一场说走就走的探险,揭秘这个异常的真面目,并手把手教你几招应对之…...

第十课:telnet(远程登入)
如何远程管理网络设备? 只要保证PC和路由器的ip是互通的,那么PC就可以远程管理路由器(用telnet技术管理)。 我们搭建一个下面这样的简单的拓扑图进行介绍 首先我们点击云,把云打开,点击增加 我们绑定vmn…...

【概率论三】参数估计:点估计(矩估计、极大似然法)、区间估计
文章目录 一. 点估计1. 矩估计法2. 极大似然法2.1. 似然函数2.2. 极大似然估计法 3. 评价估计量的标准3.1. 无偏性3.2. 有效性3.3. 一致性 二. 区间估计1. 区间估计的概念2. 正态总体参数的区间估计 参数估计讲什么 由样本来确定未知参数参数估计分为点估计与区间估计 一. 点估…...