跟着 Lua 5.1 官方参考文档学习 Lua (1)
文章目录
- 1 – Introduction
- 2 – The Language
- 2.1 – Lexical Conventions
- 2.2 – Values and Types
- 2.2.1 – Coercion
1 – Introduction
Lua is an extension programming language designed to support general procedural programming with data description facilities. It also offers good support for object-oriented programming, functional programming, and data-driven programming. Lua is intended to be used as a powerful, light-weight scripting language for any program that needs one. Lua is implemented as a library, written in clean C (that is, in the common subset of ANSI C and C++).
例子:安装LuaJIT
LuaJIT is a Just-In-Time Compiler (JIT) for the Lua programming language.
官方页面:https://luajit.org/luajit.html
安装步骤
git clone https://github.com/LuaJIT/LuaJIT.git
make
make install
安装后的头文件路径:/usr/local/include/luajit-2.1/
ls -lh /usr/local/include/luajit-2.1/
total 44K
-rw-r--r-- 1 root root 5.9K Dec 24 12:27 lauxlib.h
-rw-r--r-- 1 root root 4.5K Dec 24 12:27 luaconf.h
-rw-r--r-- 1 root root 13K Dec 24 12:27 lua.h
-rw-r--r-- 1 root root 135 Dec 24 12:27 lua.hpp
-rw-r--r-- 1 root root 3.0K Dec 24 12:27 luajit.h
-rw-r--r-- 1 root root 1.2K Dec 24 12:27 lualib.h
安装后的库文件路径:/usr/local/lib/libluajit-5.1.so
root@ubuntu:~/luajit# ls -lh /usr/local/lib/libluajit-5.1.so
lrwxrwxrwx 1 root root 31 Dec 24 12:27 /usr/local/lib/libluajit-5.1.so -> libluajit-5.1.so.2.1.1736781742
Being an extension language, Lua has no notion of a “main” program: it only works embedded in a host client, called the embedding program or simply the host.
This host program can invoke functions to execute a piece of Lua code, can write and read Lua variables, and can register C functions to be called by Lua code.
例子:执行 Lua 代码并读取 Lua 变量
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>int main() {lua_State *L = luaL_newstate(); // 创建一个新的 Lua 状态luaL_openlibs(L); // 打开 Lua 标准库// 执行 Lua 代码定义一个变量const char *lua_code = "x = 42";if (luaL_dostring(L, lua_code) != LUA_OK) {printf("Error: %s\n", lua_tostring(L, -1));return 1;}// 获取 Lua 中的变量 xlua_getglobal(L, "x"); // 将 Lua 全局变量 x 的值压入栈// 检查栈顶的数据类型并获取其值if (lua_isnumber(L, -1)) {double x = lua_tonumber(L, -1);printf("Value of x: %f\n", x); // 输出 x 的值}lua_pop(L, 1); // 弹出栈顶的 x 变量lua_close(L); // 关闭 Lua 状态return 0;
}
编译程序
gcc -o test test.c -I/usr/local/include/luajit-2.1 -lluajit-5.1
输出
Value of x: 42.000000
例子:在 Lua 中修改宿主程序的变量
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>int main() {lua_State *L = luaL_newstate(); // 创建 Lua 状态luaL_openlibs(L); // 打开 Lua 标准库// 定义一个变量int value = 10;// 将 C 变量传递给 Lualua_pushnumber(L, value); // 将 value 压栈lua_setglobal(L, "value"); // 将栈顶的值设置为 Lua 中的全局变量 value// 在 Lua 中修改变量if (luaL_dostring(L, "value = value * 2") != LUA_OK) {printf("Error: %s\n", lua_tostring(L, -1));return 1;}// 获取 Lua 中修改后的变量值lua_getglobal(L, "value");if (lua_isnumber(L, -1)) {value = lua_tonumber(L, -1);printf("Modified value: %d\n", value); // 输出修改后的值}lua_close(L); // 关闭 Lua 状态return 0;
}
输出
Modified value: 20
例子:从 Lua 中调用 C 函数
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>// 定义一个 C 函数
int add_numbers(lua_State *L) {// 获取 Lua 中传入的参数int a = luaL_checknumber(L, 1);int b = luaL_checknumber(L, 2);// 将返回值压栈lua_pushnumber(L, a + b);return 1; // 返回 1 个值
}int main() {lua_State *L = luaL_newstate(); // 创建 Lua 状态luaL_openlibs(L); // 打开 Lua 标准库// 注册 C 函数到 Lualua_register(L, "add_numbers", add_numbers);// 在 Lua 中调用 C 函数if (luaL_dostring(L, "result = add_numbers(10, 20)") != LUA_OK) {printf("Error: %s\n", lua_tostring(L, -1));return 1;}// 获取 Lua 中的返回值lua_getglobal(L, "result");if (lua_isnumber(L, -1)) {double result = lua_tonumber(L, -1);printf("Result from Lua: %f\n", result); // 输出返回的值}lua_close(L); // 关闭 Lua 状态return 0;
}
输出
Result from Lua: 30.000000
Through the use of C functions, Lua can be augmented to cope with a wide range of different domains, thus creating customized programming languages sharing a syntactical framework. The Lua distribution includes a sample host program called lua
, which uses the Lua library to offer a complete, stand-alone Lua interpreter.
例子:使用 LuaJIT 交互式地执行Lua代码
luajit
LuaJIT 2.1.1736781742 -- Copyright (C) 2005-2025 Mike Pall. https://luajit.org/
JIT: ON SSE3 SSE4.1 fold cse dce fwd dse narrow loop abc sink fuse
> print('hello world')
hello world
> x = 10
> print(x)
10
Lua is free software, and is provided as usual with no guarantees, as stated in its license. The implementation described in this manual is available at Lua’s official web site, www.lua.org
.
Like any other reference manual, this document is dry in places. For a discussion of the decisions behind the design of Lua, see the technical papers available at Lua’s web site. For a detailed introduction to programming in Lua, see Roberto’s book, Programming in Lua (Second Edition).
2 – The Language
This section describes the lexis, the syntax, and the semantics of Lua. In other words, this section describes which tokens are valid, how they can be combined, and what their combinations mean.
The language constructs will be explained using the usual extended BNF notation, in which {a} means 0 or more a’s, and [a] means an optional a. Non-terminals are shown like non-terminal, keywords are shown like kword, and other terminal symbols are shown like `**=**´. The complete syntax of Lua can be found in §8 at the end of this manual.
2.1 – Lexical Conventions
Names (also called identifiers) in Lua can be any string of letters, digits, and underscores, not beginning with a digit. This coincides with the definition of names in most languages. (The definition of letter depends on the current locale: any character considered alphabetic by the current locale can be used in an identifier.) Identifiers are used to name variables and table fields.
例子:有效的变量名
i j i10 _ij
aSomewhatLongName _INPUT
The following keywords are reserved and cannot be used as names:
and break do else elseifend false for function ifin local nil not orrepeat return then true until while
Lua is a case-sensitive language: and
is a reserved word, but And
and AND
are two different, valid names.
As a convention, names starting with an underscore followed by uppercase letters (such as _VERSION
) are reserved for internal global variables used by Lua.
例子:Lua 内部使用的全局变量
print(_VERSION) -- 版本号print(_G) -- 保存全局变量的表
输出
Lua 5.1
table: 0x7f20e252bd78
The following strings denote other tokens:
+ - * / % ^ #== ~= <= >= < > =( ) { } [ ]; : , . .. ...
Literal strings can be delimited by matching single or double quotes, and can contain the following C-like escape sequences: ‘\a
’ (bell), ‘\b
’ (backspace), ‘\f
’ (form feed), ‘\n
’ (newline), ‘\r
’ (carriage return), ‘\t
’ (horizontal tab), ‘\v
’ (vertical tab), ‘\\
’ (backslash), ‘\"
’ (quotation mark [double quote]), and ‘\'
’ (apostrophe [single quote]).
Moreover, a backslash followed by a real newline results in a newline in the string.
例子:字符串
print('"hello"')
print("'hello'")
print("hello\"")
print('hello\'')
print("hello\n")
print("hello\
")
输出
"hello"
'hello'
hello"
hello'
hellohello
A character in a string can also be specified by its numerical value using the escape sequence \ddd
, where ddd is a sequence of up to three decimal digits.(Note that if a numerical escape is to be followed by a digit, it must be expressed using exactly three digits.)
例子:使用转义序列表示字符
print("alo\n123\"")print('\97lo\10\04923"')
输出
alo
123"
alo
123"
这两个字符串是一样的。字符’a’可以使用转义序列’\97’表示,‘a’的ASCII码是十进制数97。同样的,换行符’\n’的ASCII码是十进制数10。字符’1’的ASCII码是十进制数49。
由于字符’1’后面跟着数字字符’23’,所以必须使用3位十进制数’\049’来表示字符’1’,否则’\492’会导致报错无效的转义序列。
invalid escape sequence near ''alo
'
Strings in Lua can contain any 8-bit value, including embedded zeros, which can be specified as ‘\0
’.
例子:字符串中包含’\0’
local str = '123\0abc'
print(str)
print(#str) -- 长度为7,包含了字符'\0'的长度
输出
123abc
7
Literal strings can also be defined using a long format enclosed by long brackets. We define an opening long bracket of level n as an opening square bracket followed by n equal signs followed by another opening square bracket. So, an opening long bracket of level 0 is written as [[
, an opening long bracket of level 1 is written as [=[
, and so on. A closing long bracket is defined similarly; for instance, a closing long bracket of level 4 is written as ]====]
. A long string starts with an opening long bracket of any level and ends at the first closing long bracket of the same level. Literals in this bracketed form can run for several lines, do not interpret any escape sequences, and ignore long brackets of any other level. They can contain anything except a closing bracket of the proper level.
例子:使用长括号的形式定义字符串
page = [[
<html>
<head>
<title>An HTML Page</title>
</head>
<body>
<a href="http://www.lua.org">Lua</a>
</body>
</html>
]]print(page)
输出
<html>
<head>
<title>An HTML Page</title>
</head>
<body>
<a href="http://www.lua.org">Lua</a>
</body>
</html>
For convenience, when the opening long bracket is immediately followed by a newline, the newline is not included in the string. As an example, in a system using ASCII (in which ‘a
’ is coded as 97, newline is coded as 10, and ‘1
’ is coded as 49), the five literal strings below denote the same string:
a = 'alo\n123"'a = "alo\n123\""a = '\97lo\10\04923"'a = [[alo123"]]a = [==[alo123"]==]
A numerical constant can be written with an optional decimal part and an optional decimal exponent. Lua also accepts integer hexadecimal constants, by prefixing them with 0x
. Examples of valid numerical constants are
3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56
A comment starts with a double hyphen (--
) anywhere outside a string. If the text immediately after --
is not an opening long bracket, the comment is a short comment, which runs until the end of the line. Otherwise, it is a long comment, which runs until the corresponding closing long bracket. Long comments are frequently used to disable code temporarily.
例子:短注释和长注释
-- 短注释-- 长注释,注释一个函数
--[[
print(10) -- no action (comment)
--]]---[[ 取消函数注释
print(10) --> 10
--]]
输出
10
小技巧:在长注释前添加-可将长注释变成两个短注释,从而取消注释
2.2 – Values and Types
Lua is a dynamically typed language. This means that variables do not have types; only values do. There are no type definitions in the language. All values carry their own type.
All values in Lua are first-class values. This means that all values can be stored in variables, passed as arguments to other functions, and returned as results.
There are eight basic types in Lua: nil, boolean, number, string, function, userdata, thread, and table.
例子:Lua 的七种数据类型
print(type("Hello world")) --> string
print(type(10.4*3)) --> number
print(type(print)) --> function
print(type(true)) --> boolean
print(type(nil)) --> nil
print(type({})) --> table
print(type(coroutine.create(function () end))) --> thread
输出
string
number
function
boolean
nil
table
thread
userdata 类型的数据只能使用 C API 创建。
Nil is the type of the value nil, whose main property is to be different from any other value; it usually represents the absence of a useful value.
Boolean is the type of the values false and true.
Both nil and false make a condition false; any other value makes it true.
例子:0和空字符串使条件表达式的值为true
if 0 thenprint('true')
endif "" thenprint("true")
end
输出
true
true
Number represents real (double-precision floating-point) numbers. (It is easy to build Lua interpreters that use other internal representations for numbers, such as single-precision float or long integers; see file luaconf.h
.)
String represents arrays of characters. Lua is 8-bit clean: strings can contain any 8-bit character, including embedded zeros (‘\0
’) (see §2.1).
Lua can call (and manipulate) functions written in Lua and functions written in C (see §2.5.8).
例子:Lua 中调用 C 模块的函数
C模块代码
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>static int l_dir (lua_State *L) {DIR *dir;struct dirent *entry;int i;const char *path = luaL_checkstring(L, 1);/* open directory */dir = opendir(path);if (dir == NULL) { /* error opening the directory? */lua_pushnil(L); /* return nil */lua_pushstring(L, strerror(errno)); /* and error message */return 2; /* number of results */}/* create result table */lua_newtable(L);i = 1;while ((entry = readdir(dir)) != NULL) {lua_pushnumber(L, i++); /* push key */lua_pushstring(L, entry->d_name); /* push value */lua_settable(L, -3);}closedir(dir);return 1; /* table is already on top */
}static const luaL_Reg mylib[] = {{"dir", l_dir},{NULL, NULL}
};int luaopen_mylib (lua_State *L) {luaL_register(L, "mylib", mylib);return 1;
}
编译成动态库
gcc -o mylib.so -shared mylib.c -fPIC -I/usr/local/include/luajit-2.1 -lluajit-5.1
lua中调用C模块的dir函数
require "mylib"a = mylib.dir("/usr")
for i=1, #a doprint(a[i])
end
程序输出/usr目录下的所有目录名
The type userdata is provided to allow arbitrary C data to be stored in Lua variables. This type corresponds to a block of raw memory and has no pre-defined operations in Lua, except assignment and identity test. However, by using metatables, the programmer can define operations for userdata values (see §2.8). Userdata values cannot be created or modified in Lua, only through the C API. This guarantees the integrity of data owned by the host program.
例子:使用C API 创建 userdata 并在 Lua 中使用
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>typedef struct {int value;
} MyData;// 创建一个简单的 `userdata`
static int new_value(lua_State *L) {// 创建一个新的 userdata(MyData 类型)MyData *ud = (MyData *)lua_newuserdata(L, sizeof(MyData));// 初始化数据ud->value = 0;// 创建并设置元表luaL_getmetatable(L, "MyDataMetaTable");lua_setmetatable(L, -2);return 1; // 返回 userdata
}// 获取 userdata 的值
static int get_value(lua_State *L) {MyData *ud = (MyData *)luaL_checkudata(L, 1, "MyDataMetaTable");lua_pushinteger(L, ud->value);return 1;
}// 设置 userdata 的值
static int set_value(lua_State *L) {MyData *ud = (MyData *)luaL_checkudata(L, 1, "MyDataMetaTable");ud->value = luaL_checkinteger(L, 2);return 0;
}// 定义模块方法
static const struct luaL_Reg mydata_methods[] = {{"new", new_value},{"get", get_value},{"set", set_value},{NULL, NULL}
};// 打开模块并注册类型
int luaopen_mydata(lua_State *L) {// 创建并注册元表luaL_newmetatable(L, "MyDataMetaTable");// 注册模块方法luaL_register(L, "mydata", mydata_methods);return 1;
}
编译成动态库
gcc -o mydata.so -shared mydata.c -fPIC -I/usr/local/include/luajit-2.1 -lluajit-5.1
在Lua中使用userdata
local mydata = require("mydata")-- 创建一个MyData类型的userdata
local data = mydata.new()print(data)-- 打印userdata的值
print(mydata.get(data))-- 修改userdata的值
mydata.set(data, 100)
-- 打印新值
print(mydata.get(data))
输出
userdata: 0x7f9868901a80
0
100
The type thread represents independent threads of execution and it is used to implement coroutines (see §2.11). Do not confuse Lua threads with operating-system threads. Lua supports coroutines on all systems, even those that do not support threads.
例子:使用 C API 创建协程
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>int main() {// 初始化 Lua 状态lua_State *L = luaL_newstate();luaL_openlibs(L);// 创建一个新的协程lua_State *co = lua_newthread(L);// 定义 Lua 脚本const char *lua_code = "function my_func() \n"" for i = 1, 5 do \n"" print('Coroutine step: ' .. i) \n"" coroutine.yield() \n"" end \n""end \n";// 加载并执行 Lua 脚本if (luaL_dostring(L, lua_code) != LUA_OK) {fprintf(stderr, "Error loading Lua script: %s\n", lua_tostring(L, -1));lua_close(L);return 1;}// 获取 my_func 函数并传递给协程lua_getglobal(L, "my_func");lua_xmove(L, co, 1); // 将函数传递给协程// 启动协程,传递 0 个参数int status;while (1) {status = lua_resume(co, 0); // 每次执行一次协程if (status == LUA_YIELD) {printf("LUA_YIELD\n");} else if (status == LUA_OK) {// 协程执行完毕printf("Coroutine finished\n");break;} else {// 出现错误printf("Error or coroutine finished with error\n");break;}}// 清理lua_close(L);return 0;
}
输出
Coroutine step: 1
LUA_YIELD
Coroutine step: 2
LUA_YIELD
Coroutine step: 3
LUA_YIELD
Coroutine step: 4
LUA_YIELD
Coroutine step: 5
LUA_YIELD
Coroutine finished
例子:Lua 中调用 C 函数,C 函数执行 yield
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>int my_c_function(lua_State *L) {printf("in c function, yield\n");return lua_yield(L, 0);
}int main() {// 初始化 Lua 状态lua_State *L = luaL_newstate();luaL_openlibs(L);// 注册 C 函数lua_register(L, "my_c_function", my_c_function);// 创建一个新的协程lua_State *co = lua_newthread(L);// 定义 Lua 脚本。在 Lua 中调用 C 函数,在 C 函数中 yieldconst char *lua_code = "function my_func() \n"" for i = 1, 5 do \n"" print('Coroutine step: ' .. i) \n"" my_c_function() \n"" print('Coroutine continue') \n"" end \n""end \n";// 加载并执行 Lua 脚本if (luaL_dostring(L, lua_code) != LUA_OK) {fprintf(stderr, "Error loading Lua script: %s\n", lua_tostring(L, -1));lua_close(L);return 1;}// 获取 my_func 函数并传递给协程lua_getglobal(L, "my_func");lua_xmove(L, co, 1); // 将函数传递给协程// 启动协程,传递 0 个参数int status;while (1) {status = lua_resume(co, 0); // 每次执行一次协程if (status == LUA_YIELD) {} else if (status == LUA_OK) {// 协程执行完毕printf("Coroutine finished\n");break;} else {// 出现错误printf("Error or coroutine finished with error\n");break;}}// 清理lua_close(L);return 0;
}
输出
Coroutine step: 1
in c function, yield
Coroutine continue
Coroutine step: 2
in c function, yield
Coroutine continue
Coroutine step: 3
in c function, yield
Coroutine continue
Coroutine step: 4
in c function, yield
Coroutine continue
Coroutine step: 5
in c function, yield
Coroutine continue
Coroutine finished
注意:C 函数 yield 后,后续就不能继续进入 C 函数执行!
The type table implements associative arrays, that is, arrays that can be indexed not only with numbers, but with any value (except nil). Tables can be heterogeneous; that is, they can contain values of all types (except nil).
Tables are the sole data structuring mechanism in Lua; they can be used to represent ordinary arrays, symbol tables, sets, records, graphs, trees, etc.
补充:Lua uses tables to represent modules, packages, and objects as well. When we write io.read, we mean “the read function from the io module”. For Lua, this means “index the table io using the string “read” as the key”.
To represent records, Lua uses the field name as an index. The language supports this representation by providing a.name
as syntactic sugar for a["name"]
. There are several convenient ways to create tables in Lua (see §2.5.7).
Like indices, the value of a table field can be of any type (except nil). In particular, because functions are first-class values, table fields can contain functions. Thus tables can also carry methods (see §2.5.9).
Tables, functions, threads, and (full) userdata values are objects: variables do not actually contain these values, only references to them. Assignment, parameter passing, and function returns always manipulate references to such values; these operations do not imply any kind of copy.
The library function type
returns a string describing the type of a given value.
2.2.1 – Coercion
Lua provides automatic conversion between string and number values at run time. Any arithmetic operation applied to a string tries to convert this string to a number, following the usual conversion rules. Conversely, whenever a number is used where a string is expected, the number is converted to a string, in a reasonable format.
例子:字符串和数字的自动转换
print("10" + 1) --> 11
print("10 + 1") --> 10 + 1
print("-5.3e-10"*"2") --> -1.06e-09
print(10 .. 20) --> 1020
print("hello" + 1) -- ERROR (cannot convert "hello")
输出
11
10 + 1
-1.06e-09
1020
luajit: 3.lua:5: attempt to perform arithmetic on a string value
stack traceback:3.lua:5: in main chunk[C]: at 0x00404b20
For complete control over how numbers are converted to strings, use the format
function from the string library (see string.format
).
相关文章:
跟着 Lua 5.1 官方参考文档学习 Lua (1)
文章目录 1 – Introduction2 – The Language2.1 – Lexical Conventions2.2 – Values and Types2.2.1 – Coercion 1 – Introduction Lua is an extension programming language designed to support general procedural programming with data description facilities. I…...
计算机性能与网络体系结构探讨 —— 基于《计算机网络》谢希仁第八版
(꒪ꇴ꒪ ),Hello我是祐言QAQ我的博客主页:C/C语言,数据结构,Linux基础,ARM开发板,网络编程等领域UP🌍快上🚘,一起学习,让我们成为一个强大的攻城狮࿰…...
matlab欠驱动船舶模型预测控制
1、内容简介 matlab135-欠驱动船舶模型预测控制 可以交流、咨询、答疑 2、内容说明 略 针对在风 、 浪 、 流时变干扰下欠驱动水面船舶的轨迹跟踪控制问题 , 设计了一种基于模型 预测控制的轨迹跟踪控制器 . 考虑到欠驱动船舶在没有横向驱动力情况下…...
【MySQL常见疑难杂症】常见文件及其所存储的信息
1、MySQL配置文件的读取顺序 (非Win)/etc/my.cnf、/etc/mysql/my.cnf、/usr/local/mysql/etc/my.cnf、~/.my.cnf 可以通过命令查看MySQL读取配置文件的顺序 [roothadoop01 ~]# mysql --help |grep /etc/my.cnf /etc/my.cnf /etc/mysql/my.c…...
【LeetCode】3.无重复字符的最长字串
目录 题目算法解法解法一 暴力枚举 哈希表(判断字符是否重复出现) (O( n 2 n^{2} n2))解法二 滑动窗口 哈希表(判断字符是否重复出现) 代码 题目 题目链接:LeetCode-3题 给定一个字符串 s &a…...
李宏毅机器学习笔记:【6.Optimization、Adaptive Learning Rate】
Optimization 1.Adaptive Learning Rate2.不同的参数需要不同的学习率3.Root Mean Square4.RMSProp5.Adam6.learning rate scheduling7.warm up总结 critical point不一定是你在训练一个network时候遇到的最大的障碍。 1.Adaptive Learning Rate 也就是我们要给每个参数不同的…...
计算机组成原理—— 外围设备(十三)
记住,伟大的成就往往诞生于无数次尝试和失败之后。每一次跌倒,都是为了让你学会如何更加坚定地站立;每一次迷茫,都是为了让你找到内心真正的方向。即使前路漫漫,即使困难重重,心中的火焰也不应熄灭。它代表…...
React简介
React简介 A Brief Introduction to React By JacksonML 1. 关于React React是一个知名的Web框架。众所周知,jQuery, Angular, Vue等框架都曾闪亮登场,并且,都仍然在全球市场占有一席之地。React这个颇有担当的新锐,也进入到我…...
Linux-C/C++《七、字符串处理》(字符串输入/输出、C 库中提供的字符串处理函数、正则表达式等)
字符串处理在几乎所有的编程语言中都是一个绕不开的话题,在一些高级语言当中,对字符串的处理支 持度更是完善,譬如 C、 C# 、 Python 等。若在 C 语言中想要对字符串进行相关的处理,譬如将两个字符串进行拼接、字符串查找、两个…...
哈希动态规划dp_5
一.哈希 哈希(Hashing)是计算机科学中一种非常重要的技术,用于将输入的数据映射到固定大小的值(哈希值)上。哈希算法和哈希数据结构广泛应用于各种领域,包括数据查找、加密、缓存、数据库索引等。我们来详…...
电商分布式场景中如何保证数据库与缓存的一致性?实战方案与Java代码详解
文章目录 一、缓存一致性问题的本质写后读不一致:更新数据库后,缓存未及时失效并发读写竞争:多个线程同时修改同一数据缓存与数据库事务不同步:部分成功导致数据错乱 二、5大核心解决方案与代码实现方案1:延迟双删策略…...
DeepSeek-R1 大模型本地部署指南
文章目录 一、系统要求硬件要求软件环境 二、部署流程1. 环境准备2. 模型获取3. 推理代码配置4. 启动推理服务 三、优化方案1. 显存优化技术2. 性能加速方案 四、部署验证健康检查脚本预期输出特征 五、常见问题解决1. CUDA内存不足2. 分词器警告处理3. 多GPU部署 六、安全合规…...
【数据结构】 栈和队列
在计算机科学的世界里,数据结构是构建高效算法的基础。栈(Stack)和队列(Queue)作为两种基本且重要的数据结构,在软件开发、算法设计等众多领域都有着广泛的应用。今天,我们就来深入探讨一下栈和…...
用Python构建Mad Libs经典文字游戏
前言 Mad Libs 是一种经典的文字游戏,其中一名玩家向其他玩家询问各种词汇,如名词、动词、形容词等,而不提供任何上下文。然后将这些提示词插入到一个充满空白的故事模板中,从而创造出一个搞笑或荒谬的故事,供玩家大声朗读以获取乐趣。 自1950年代发明以来,Mad Libs 一…...
ReactiveSwift模拟登录功能
通过使用ReactiveSwift模拟一个简单的登录功能,该功能如下要求: 账号不能为空密码必须大于6位 登录按钮方可点击 LoginViewModel: import ReactiveSwiftclass LoginViewModel {// 创建两个信号let userName MutableProperty<String&g…...
亲测有效!使用Ollama本地部署DeepSeekR1模型,指定目录安装并实现可视化聊天与接口调用
文章目录 一、引言二、准备工作(Ollama 工具介绍与下载)2.1 Ollama介绍2.2 Ollama安装 三、指定目录安装 DeepSeek R1四、Chatbox 可视化聊天搭建4.1 Chatbox下载安装4.2 关联 DeepSeek R1 与 Chatbox 的步骤 五、使用 Ollama 调用 DeepSeek 接口5.1 请求…...
【第11章:生成式AI与创意应用—11.3 AI艺术创作的实现与案例分析:DeepArt、GANBreeder等】
凌晨三点的画室里,数字艺术家小美盯着屏幕上的GANBreeder界面——她将梵高的《星月夜》与显微镜下的癌细胞切片图进行混合,生成的新图像在柏林电子艺术展上引发轰动。这场由算法驱动的艺术革命,正在重写人类对创造力的定义。 一、机器视觉的觉醒之路 1.1 数字艺术的三次浪…...
MySQL的基本使用
MySQL 是一个强大且广泛使用的开源关系型数据库管理系统,适用于各种规模的应用程序。无论是初学者还是经验丰富的开发者,掌握 MySQL 的基本操作都是至关重要的。本文将带你了解 MySQL 的基础概念,并通过实例介绍如何执行一些常见的数据库操作…...
WEB安全--SQL注入--PDO与绕过
一、PDO介绍: 1.1、原理: PDO支持使用预处理语句(Prepared Statements),这可以有效防止SQL注入攻击。预处理语句将SQL语句与数据分开处理,使得用户输入的数据始终作为参数传递给数据库,而不会直…...
微信小程序image组件mode属性详解
今天学习微信小程序开发的image组件,mode属性的属性值不少,一开始有点整不明白。后来从网上下载了一张图片,把每个属性都试验了一番,总算明白了。现总结归纳如下: 1.使用scaleToFill。这是mode的默认值,sc…...
大模型炼丹基础--GPU内存计算
一、摘要 选择合适的GPU对成本和效率都至关重要,合理分析GPU 二、硬件计算基础 1 个字节可以表示零(00000000)和 255(11111111)之间的数字 模型参数常用的数据类型如下: float(32 位浮点&a…...
istio入门篇(一)
一、背景 一直以来“微服务”都是一个热门的词汇,在各种技术文章、大会上,关于微服务的讨论和主题都很多。对于基于 Dubbo、SpringCloud 技术体系的微服务架构,已经相当成熟并被大家所知晓,但伴随着互联网场景的复杂度提升、业务…...
Ubuntu 24.04.1 LTS 本地部署 DeepSeek 私有化知识库
文章目录 前言工具介绍与作用工具的关联与协同工作必要性分析 1、DeepSeek 简介1.1、DeepSeek-R1 硬件要求 2、Linux 环境说明2.1、最小部署(Ollama DeepSeek)2.1.1、扩展(非必须) - Ollama 后台运行、开机自启: 2.2、…...
沃德校园助手系统php+uniapp
一款基于FastAdminThinkPHPUniapp开发的为校园团队提供全套的技术系统及运营的方案(目前仅适配微信小程序),可以更好的帮助你打造自己的线上助手平台。成本低,见效快。各种场景都可以自主选择服务。 更新日志 V1.2.1小程序需要更…...
Visual Studio Code使用ai大模型编成
1、在Visual Studio Code搜索安装roo code 2、去https://openrouter.ai/settings/keys官网申请个免费的配置使用...
工业软件测试方案
一、方案概述 本测试方案致力于全面、系统地评估工业仿真软件的综合性能,涵盖性能表现、功能完整性以及用户体验层面的易用性。同时,将其与行业内广泛应用的MATLAB进行深入的对比分析,旨在为用户提供极具价值的参考依据,助力其在…...
红队视角出发的k8s敏感信息收集——Kubernetes API 扩展与未授权访问
针对 Kubernetes API 扩展与未授权访问 的详细攻击视角分析,聚焦 Custom Resource Definitions (CRD) 和 Aggregated API Servers 的潜在攻击面及利用方法: 攻击链示例 1. 攻击者通过 ServiceAccount Token 访问集群 → 2. 枚举 CRD 发现数据库配…...
一种 SQL Server 数据库恢复方案:解密、恢复并导出 MDF/NDF/BAK文件
方案特色 本方案可以轻松恢复和导出SQL数据库:MDF、NDF 和 BAK 文件。 恢复和导出SQL数据库:主(MDF),辅助(NDF)和备份(BAK)文件分析 SQL Server LOG 数据库事务日志将 …...
Pygame中自定义事件处理的方法2-1
1 Pygame事件处理流程 Pygame中的事件处理流程如图1所示。 图1 Pygame中事件处理流程 系统事件包括鼠标事件和键盘事件等,当用户点击了鼠标或者键盘时,这些事件会自动被放入系统的事件队列中。用户自定义事件需要通过代码才能被放入事件队列中。Pygame…...
langchain学习笔记之消息存储在内存中的实现方法
langchain学习笔记之消息存储在内存中的实现方法 引言背景消息存储在内存的实现方法消息完整存储:完整代码 引言 本节将介绍 langchain \text{langchain} langchain将历史消息存储在内存中的实现方法。 背景 在与大模型交互过程中,经常出现消息管理方…...
HarmonyOS组件之Tabs
Tabs 1.1概念 Tabs 视图切换容器,通过相适应的页签进行视图页面的切换的容器组件每一个页签对应一个内容视图Tabs拥有一种唯一的子集元素TabContent 1.2子组件 不支持自定义组件为子组件,仅可包含子组件TabContent,以及渲染控制类型 if/e…...
【C++】基础入门(详解)
🌟 Hello,我是egoist2023! 🌍 种一棵树最好是十年前,其次是现在! 目录 输入&输出 缺省参数(默认参数) 函数重载 引用 概念及定义 特性及使用 const引用 与指针的关系 内联inline和nullptr in…...
bps是什么意思
本文来自DeepSeek "bps" 是 "bits per second" 的缩写,表示每秒传输的比特数,用于衡量数据传输速率。1 bps 即每秒传输 1 比特。 常见单位 bps:比特每秒 Kbps:千比特每秒(1 Kbps 1,000 bps&am…...
OceanBase使用ob-loader-dumper导出表报ORA-00600
执行下面的语句导出表报错,同样的语句之前都没有报错。 ob-loader-dumper-4.2.8-RELEASE/bin/obdumper -h xxx.xxx.xxx.xxx -P 2883 -p 密码 --column-splitter| --no-sys-t gzuat_ss#ob8(集群) -D 数据库名 --cut --table teacher --no-ne…...
JUC并发总结一
大纲 1.Java集合包源码 2.Thread源码分析 3.volatile关键字的原理 4.Java内存模型JMM 5.JMM如何处理并发中的原子性可见性有序性 6.volatile如何保证可见性 7.volatile的原理(Lock前缀指令 + 内存屏障) 8.双重检查单例模式的volatile优化 9.synchronized关键字的原理 …...
hive:分区>>静态分区,动态分区,混合分区
分区表 使用场景:数据量庞大且经常用来做查询的表 特点:将数据分别存储到不同的目录里 优点:避免全盘扫描,提高查询效率 分区的类型 它们的默认值分别是: false, strict, 要求至少有一个静态分区列,而 nonstr…...
深入解析PID控制算法:从理论到实践的完整指南
前言 大家好,今天我们介绍一下经典控制理论中的PID控制算法,并着重讲解该算法的编码实现,为实现后续的倒立摆样例内容做准备。 众所周知,掌握了 PID ,就相当于进入了控制工程的大门,也能为更高阶的控制理论…...
linux--关于GCC、动态库静态库
gcc和g的异同 他们是不同的编译器, 在linux中,生成可执行文件不像和windows一样。 linux中是以**.out作为可执行文件**的 无论是什么系统,生成可执行文件分为4步: 预处理–>编译–>汇编–>链接。 从.c/.cpp–>.i文件…...
matlab汽车动力学半车垂向振动模型
1、内容简介 matlab141-半车垂向振动模型 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略...
Pygame中自定义事件处理的方法2-2
在《Pygame中自定义事件处理的方法2-1》中提到了处理自定义事件的方法。通过处理自定义事件,可以实现动画等效果。 1 弹跳小球程序 通过处理自定义事件,可以实现弹跳小球程序,如图1所示。 图1 弹跳小球程序 2 弹跳小球程序原理 实现弹跳小…...
B. Longest Divisors Interval
time limit per test 2 seconds memory limit per test 256 megabytes Given a positive integer nn, find the maximum size of an interval [l,r][l,r] of positive integers such that, for every ii in the interval (i.e., l≤i≤rl≤i≤r), nn is a multiple of ii. …...
什么是服务的雪崩、熔断、降级的解释以及Hystrix和Sentinel服务熔断器的解释、比较
1.什么是服务雪崩? 定义:在微服务中,假如一个或者多个服务出现故障,如果这时候,依赖的服务还在不断发起请求,或者重试,那么这些请求的压力会不断在下游堆积,导致下游服务的负载急剧…...
从驾驶员到智能驾驶:汽车智能化进程中的控制与仿真技术
在汽车技术持续演进的历程中,人类驾驶员始终是一个极具研究价值的智能控制系统“原型”。驾驶员通过视觉感知、行为决策与操作执行的闭环控制,将复杂的驾驶任务转化为车辆的实际动作,同时动态适应道路环境的变化。这一过程不仅体现了高度的自…...
mysql和minio
在现代应用架构中,Word 文档、PPT 等文件通常存储在对象存储服务(如 MinIO)中,而不是直接存储在关系型数据库(如 MySQL)中。以下是具体的分工和原因: 为什么选择对象存储(如 MinIO&a…...
java练习(24)
PS:练习来自力扣 合并两个有序数组 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。 注意&am…...
Android的Activity生命周期知识点总结,详情
一. Activity生命周期 1.1 返回栈知识点 二. Activity状态 2.1 启动状态 2.2 运行状态 2.3 暂停状态 2.4 停止状态 2.5 销毁状态 三. Activity生存期 3.1 回调方法 3.2 生存期 四. 体验Activity的生命周期 五. Activity被回收办法 引言: 掌握Acti…...
STM32——HAL库开发笔记19(串口中断接收实验)(参考来源:b站铁头山羊)
本实验,我们以中断的方式使得串口发送数据控制LED的闪烁速度,发送1,慢闪;发送2,速度正常;发送3,快闪。 一、电路连接图 二、实现思路&CubeMx配置 1、实现控制LED的闪烁速度 uint32_t bli…...
基于腾讯云TI-ONE 训练平台快速部署和体验 DeepSeek 系列模型
引言 在前两篇文章中,我们通过腾讯云的HAI部署了DeepSeek-R1,并基于此进行了一系列实践。 腾讯云HAI DeepSeek 腾讯云AI代码助手 :零门槛打造AI代码审计环境 基于腾讯云HAI DeepSeek 快速开发中医辅助问诊系统 这些尝试不仅帮助我们理解…...
python的类装饰器
装饰器不仅可以用于函数,还能作用于类。将装饰器应用于类时,其核心原理与作用于函数类似,都是通过接收一个类作为输入,然后返回一个新的类或者修改后的原类,以此来为类添加额外的功能 简单的类装饰器 def add_method…...
C++17中的LegacyContiguousIterator(连续迭代器)
文章目录 特点内存连续性与指针的兼容性更高的性能 适用场景与C接口交互高性能计算 支持连续迭代器的容器示例代码性能优势缓存局部性指针算术优化 注意事项总结 在C17标准里,LegacyContiguousIterator(连续迭代器)是一类特殊的迭代器。它不仅…...