面试题之Lua基础

1、元表的使用,实现一个面向对象的类

Lua查找表元素的过程​​​​​​​

基础学习:Lua面向对象编程 (__index、__newindex、__call、__add)_ccsu_deer-CSDN博客​​​​​​​

做法:用__index实现继承

--继承关系
Shape = {area = 0}
function Shape:new(o, side)
	o = o or {}
	setmetatable(o, self)
	self.__index = self  --保持继承链,不加此行, t1就没有__index元方法,下面的t2 = t1:new({}, 4)会报错
	side = side or 0
	o.area = side * side
	return o
end
 
t1 = Shape:new({key1 = 1}, 3)
print("t1.area:", t1.area)
print("t1.key1:", t1.key1)
t2 = t1:new({key2 = 2}, 4)
print("t2.key1:", t2.key1)
print("t2.key2:", t2.key2)
t3 = t2:new({key3 = 3}, 5)
 
print("t3.key1:", t3.key1)
print("t3.key2:", t3.key2)
print("t3.key3:", t3.key3)

2、元方法的使用

用setmetatable,重载元表里的相关运算函数即可

如:

__add(a, b)                     对应表达式 a + b

__sub(a, b)                     对应表达式 a - b

__mul(a, b)                     对应表达式 a * b

__div(a, b)                     对应表达式 a / b

__mod(a, b)                     对应表达式 a % b

__pow(a, b)                     对应表达式 a ^ b

__unm(a)                        对应表达式 -a

__concat(a, b)                  对应表达式 a .. b

__len(a)                        对应表达式 #a

__eq(a, b)                      对应表达式 a == b

__lt(a, b)                      对应表达式 a < b

__le(a, b)                      对应表达式 a <= b

重载__add例子:

--只读table
 
t = setmetatable({1, 2, 3},{
	__add = function(self, newtable)
		len1 = #self
		len2 = #newtable
		sum = 0
		for i=1, len1 do
			sum = sum + self[i]
		end
		for i=1, len2 do
			sum = sum + newtable[i]
		end
		return sum
 
	end
})
 
 
t1 = {2,3,4}
 
answer = t + t1
print("answer:", answer)

 3、Lua的GC

三色标记法:深入探究Lua的GC算法_jinxinliu1的专栏-CSDN博客_lua的gc

一、GC的原理及其算法设计

不同的语言,对GC算法的设计不同,常见的GC算法是引用计数和Mark-Sweep算法, c#采用的是Mark-sweep && compact算法, Lua采用的是Mark-sweep算法,分开说一下:

引用计数算法:在一个对象被引用的情况下,将其引用计数加1,反之则减1,如果计数值为0,则在GC的时候回收,这个算法有个问题就是循环引用。

Mark-sweep算法:每次GC的时候,对所有对象进行一次扫描,如果该对象不存在引用,则被回收,反之则保存。

在Lua5.0及其更早的版本中,Lua的GC是一次性不可被打断的过程,使用的Mark算法是双色标记算法(Two color mark),这样系统中对象的非黑即白,要么被引用,要么不被引用,这会带来一个问题:在GC的过程中如果新加入对象,这时候新加入的对象无论怎么设置都会带来问题,如果设置为白色,则如果处于回收阶段,则该对象会在没有遍历其关联对象的情况下被回收;如果标记为黑色,那么没有被扫描就被标记为不可回收,是不正确的。

为了降低一次性回收带来的性能问题以及双色算法的问题,在Lua5.1后,Lua都采用分布回收以及三色增量标记清除算法(Tri-color incremental mark and sweep)

其基本的原理伪代码,参考书中原文为:

每个新创建的对象颜色设置为白色

//初始化阶段

遍历root节点中引用的对象,从白色置为灰色,并且放入到灰色节点列表中

//标记阶段

while(灰色链表中还有未扫描的元素):

从中取出一个对象,将其置为黑色

遍历这个对象关联的其他所有对象:

if 为白色

标记为灰色,加入到灰色链表中(insert to the head)



//回收阶段

遍历所有对象:

if 为白色,

没有被引用的对象,执行回收

else

重新塞入到对象链表中,等待下一轮GC

4、Lua和C++的相互调用

Lua和C相互调用_ccsu_deer-CSDN博客

5、setfenv和getfenv

6、热更新的实现和流程

1.对比差异文件

2.下载

3.解压

4.删除旧文件,移动新文件

5.删除多余文件

6.重新加载脚本

1、首次进入app,初始化版本号version=0

2、socket::send()把版本号发送给服务器,进行版本校验

3、服务器版本号校验,如果app版本号与服务器版本号不一致,进行资源列表下载

4、socket::receive()    app进行校验,版本资源中,是否已经存在要下载的资源,如果存在,对应的不下载;如果不存在,进行下载。情况二:把本地版本已存在的进行移除,接着进行下载

5、app读取资源,进行资源下载 
 

猜你喜欢

转载自blog.csdn.net/qq_41286356/article/details/123312293