《Lua程式設計第四版》 第二部分9~13章自做練習題答案

来源:https://www.cnblogs.com/linxiaoxu/archive/2023/08/15/17630254.html
-Advertisement-
Play Games

Lua程式設計第四版第二部分編程實操自做練習題答案,帶:star:為重點。 ## 9.1 > 請編寫一個函數integral,該函數以一個函數f為參數並返回其積分的近似值 使用右矩陣法近似積分值 ```lua function integral(f) return function(a, b) lo ...


Lua程式設計第四版第二部分編程實操自做練習題答案,帶⭐為重點。

9.1

請編寫一個函數integral,該函數以一個函數f為參數並返回其積分的近似值

使用右矩陣法近似積分值

function integral(f)
    return function(a, b)
        local sum = 0
        for i = 1, 10000, 1 do
            sum = sum + f(a + (b - a) * i / 10000)
        end
        return sum * (b - a) / 10000
    end
end

function x3(x)
    return 2 * x + 3 * x ^ 3
end

jf = integral(x3)
print(jf(0, 10)) -- 7601.510075 近似 7600

9.2

如下代碼段將輸出什麼結果

function F(x)
    return {
        set = function(y)
            x = y
        end,
        get = function()
            return x
        end
    }
end

o1 = F(10)
o2 = F(20)
print(o1.get(), o2.get())
o2.set(100)
o1.set(300)
print(o1.get(), o2.get())
-- 10      20
-- 300     100

9.3 ⭐

編寫練習5.4的柯里化版本

柯里化(Currying)是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,並且返回接受餘下的參數且返回結果的新函數的技術。

function newpoly(t)
    return function(x)
        local sum = 0
        for i, v in ipairs(t) do
            sum = sum + v * x ^ (i - 1)
        end
        return sum
    end
end

t = newpoly({3, 0, 1})
print(t(0))
print(t(5))
print(t(10))

9.4

使用幾何區域系統的例子,繪製一個北半球所能看到的峨眉月

編寫一個被其他函數B包含的函數A時,被包含的函數A可以訪問包含其的函數B的所有局部變數,這種特性被稱為詞法定界

-- 利用高階函數和詞法定界,定義一個指定圓心和半徑創建圓盤的工廠 --
function disk(cx, cy, r)
    return function(x, y)
        return (x - cx) ^ 2 + (y - cy) ^ 2 <= r ^ 2
    end
end

-- 創建一個指定邊界的軸對稱圖形
function rect(left, right, top, bottom)
    return function(x, y)
        return left <= x and x <= right and bottom <= y and y <= top
    end
end

-- 創建任何區域的補集
function complement(r)
    return function(x, y)
        return not r(x, y)
    end
end

-- 創建任何區域的並集
function union(r1, r2)
    return function(x, y)
        return r1(x, y) or r2(x, y)
    end
end

-- 交集
function intersection(r1, r2)
    return function(x, y)
        return r1(x, y) and r2(x, y)
    end
end

-- 差集
function difference(r1, r2)
    return function(x, y)
        return r1(x, y) and not r2(x, y)
    end
end

-- 按指定增量平移區域
function translate(r, dx, dy)
    return function(x, y)
        return r(x - dx, y - dy)
    end
end

function plot(r, M, N, file)
    f = io.open(file, "w")
    f:write("P1\n", M, " ", N, "\n")
    for i = 1, N, 1 do
        local y = (N - i * 2) / N
        for j = 1, M do
            local x = (j * 2 - M) / M
            f:write(r(x, y) and "1" or "0")
        end
        f:write("\n")
    end
    f:close()
end

circle = disk(0, 0, 0.5)
circle2 = translate(circle, -0.3, 0.2)
shape = difference(circle, circle2)
plot(shape, 512, 512, "test.pbm")

9.5 ⭐

在幾何區域系統的例子中,添加一個函數來實現將指定的區域旋轉指定的角度

image-20230814141934874

image-20230815042015553

-- 創建一個指定邊界的軸對稱圖形
function rect(left, right, top, bottom)
    return function(x, y)
        return left <= x and x <= right and bottom <= y and y <= top
    end
end

-- 創建任何區域的並集
function union(r1, r2)
    return function(x, y)
        return r1(x, y) or r2(x, y)
    end
end

-- 圖形根據坐標軸原點順時針旋轉d弧度
function rotate(r, d)
    return function(x, y)
        return r(-math.cos(d) * x + y * math.sin(d), -math.sin(d) * x - math.cos(d) * y)
    end
end

function plot(r, M, N, file)
    f = io.open(file, "w")
    f:write("P1\n", M, " ", N, "\n")
    for i = 1, N, 1 do
        local y = (N - i * 2) / N
        for j = 1, M do
            local x = (j * 2 - M) / M
            f:write(r(x, y) and "1" or "0")
        end
        f:write("\n")
    end
    f:close()
end

shape1 = rect(-0.5, 0.5, 0.5, -0.5)
shape2 = rect(-0.25, 0.25, 0.75, -0.25)
shape1 = rotate(shape, math.pi * 0.1) -- s1所處的坐標系平面被旋轉了,s2的並沒有
shape = union(shape1, shape2)
plot(shape, 512, 512, "test.pbm")
image-20230814150430157

10.1

請編寫一個函數split,該函數接收兩個參數,第1個參數是字元串,第2個參數是分隔符模式,函數的返回值是分隔符分割後的原始字元串中每一部分的序列

function split(s, sep)
    t = {}
    -- tmpindex = 0
    -- index = 1
    -- index = string.find(s, sep, index, true)
    -- while index do
    --     table.insert(t, string.sub(s, tmpindex + 1, index))
    --     tmpindex = index
    --     index = string.find(s, sep, index + 1, true)
    -- end
    -- if index ~= #s then
    --     table.insert(t, string.sub(s, tmpindex + 1, #s))
    -- end
    for w in string.gmatch(s, "[^" .. sep .. "]+") do
        t[#t + 1] = w
    end
    return t
end

t = split("a whole new world", " ")
-- t = split("", " ")
for k, v in pairs(t) do
    print(k, v)
end

10.2 ⭐

模式 [^%d%u] 與 [%D%U] 是否等價

不一樣

[^%d%u] 是 (數字∪大寫字母)的補集 = 排除數字和大寫字母
> string.find("123ABCA","[^%d%u]") 
nil
> string.find("123ABCa","[^%d%u]") 
7       7
[%D%U] 是  數字的補集∪大寫字母的補集 = 全集
> string.find("123ABC","[%D%U]")
1       1
使用第一種是正確的

10.3

請編寫一個函數transliterate,該函數接收兩個參數,第1個參數是字元串,第2個參數是一個表。函數transliterate根據第2個參數中的表使用一個字元替換字元串中的字元。如果表中將a映射為b,那麼該函數則將所有a替換為b。如果表中將a映射為false,那麼該函數則把結果中的所有a移除

function transliterate(s, t)
    return string.gsub(s, ".", function(w)
        if t[w] == false then
            return ""
        else
            return t[w]
        end
    end)
end

s = "apple"
s = transliterate(s, {
    a = "b",
    p = false,
    l = "i",
    e = "g"
})
print(s)

10.4 ⭐

我們定義了一個trim函數。

  • 構造一個可能會導致trim耗費O(n^2)時間複雜度的字元串
  • 重寫這個函數使得其時間複雜度為O(n)
function trim1(s)
    return string.gsub(s, "^%s*(.-)%s*$", "%1")
end

-- "雙指針法實現"
function trim2(s)
    local top = string.find(s, "%S")
    local tail = #s
    for i = 1, #s, 1 do
        if string.find(string.sub(s, -i, -i), "%s") then
            tail = #s - i
        else
            break
        end
    end
    return string.sub(s, top, tail)
end

s = string.rep(" ", 2 ^ 13)

s = (" " .. "a" .. s .. "a" .. " ")

start = os.clock()
t = trim2(s)
print(t:len() == 2 ^ 13 + 2)
print(os.clock() - start)

10.5

請使用轉義序列\x編寫一個函數,將一個二進位字元串格式化為Lua語言中的字元串常量

-- 二進位字元串格式化為Lua語言中的字元串常量
function escape(s)
    local pattern = string.rep("[01]", 8)
    s = string.gsub(s, pattern, function(bits)
        return string.format("\\x%02X", tonumber(bits, 2))
    end)
    return s
end

print(escape( "0100100001100001011100000111000001111001001000000110010101110110011001010111001001111001011001000110000101111001"))
-- \x48\x61\x70\x70\x79\x20\x65\x76\x65\x72\x79\x64\x61\x79

10.6

請為UTF-8字元串重寫10.3

function transliterate(s, t)
    return string.gsub(s, utf8.charpattern, function(w)
        if t[w] == false then
            return ""
        else
            return t[w]
        end
    end)
end

s = "天氣真好"
s = transliterate(s, {
    ["天"] = "大",
    ["氣"] = false,
    ["真"] = "爺"
})
print(s)

10.7

請編寫一個函數,該函數用於逆轉一個UTF-8字元串

function reverseUTF8(s)
    t = {}
    for w in string.gmatch(s, utf8.charpattern) do
        table.insert(t, 1, w)
    end
    return table.concat(t)
end

print(reverseUTF8("天氣真好"))

ANTI SPIDER BOT -- www.cnblogs.com/linxiaoxu

11.1

請改寫該程式,使它忽略長度小於4個字母的單詞

local counter = {}

io.input(arg[2] or "test.txt")

for line in io.lines() do
    -- 不能放在這,相當於無限執行gmatch死迴圈,gmatch只執行一次獲取迭代器
    for word in string.gmatch(line, "%w+") do
        if #word < 4 then
            goto a
        end
        counter[word] = (counter[word] or 0) + 1
        ::a:: -- 跳過當前計數
    end
end

local words = {}
for k, _ in pairs(counter) do
    words[#words + 1] = k
end

table.sort(words, function(w1, w2)
    return counter[w1] > counter[w2] or counter[w1] == counter[w2] and w1 < w2
end)

local n = math.min(tonumber(arg[1]) or math.huge, #words)

for i = 1, n, 1 do
    print(i, words[i], counter[words[i]])
end

11.2 ⭐

該程式還能從一個文本文件中讀取要忽略的單詞列表

local counter = {}
local ignore = {}

io.input(arg[2] or "test.txt")
f = io.open(arg[3] or "ignore.txt", 'r')
for line in f:lines() do
    ignore[string.match(line, "%w+")] = true
end

for line in io.lines() do
    -- 不能放在這,相當於無限執行gmatch死迴圈,gmatch只執行一次獲取迭代器
    for word in string.gmatch(line, "%w+") do
        if #word < 4 or ignore[word] then
            goto a
        end
        counter[word] = (counter[word] or 0) + 1
        ::a:: -- 跳過當前計數
    end
end

local words = {}
for k, _ in pairs(counter) do
    words[#words + 1] = k
end

table.sort(words, function(w1, w2)
    return counter[w1] > counter[w2] or counter[w1] == counter[w2] and w1 < w2
end)

local n = math.min(tonumber(arg[1]) or math.huge, #words)

for i = 1, n, 1 do
    print(i, words[i], counter[words[i]])
end

12.1

該函數返回指定日期和時間後恰好一個月的日期和時間(按數字形式表示)

function oneMonthLater(t)
    t.month = t.month + 1
    return os.time(t)
end

print(oneMonthLater(os.date("*t")))

12.2

該函數返回指定日期是星期幾(用整數表示,1表示星期天

function wday(t)
    return t.wday
end

print(wday(os.date("*t")))

12.3

該函數的參數為一個日期和時間(數值),返回當天中已經經過的秒數

function todayPassSeconds(t)
    t = os.date("*t", t)
    return t.hour * 3600 + t.min * 60 + t.sec
end

print(todayPassSeconds(os.time()))

12.4

該函數的參數為年,返回該年中第一個星期五是第幾天

function findFirstFriday(y)
    t = os.date("*t")
    t.year = y
    t.month = 1
    for i = 1, 7, 1 do
        t.day = i
        t = os.date("*t", os.time(t))
        if t.yday == 6 then
            return t.yday
        end
    end
end

print(findFirstFriday(2023))

12.5

該函數用於計算兩個指定日期之間相差的天數

function timeDiffDays(x, y)
    seconds = os.time(x) - os.time(y)
    return seconds // (24 * 3600)
end

t = os.date("*t")
t.year = 2012
print(timeDiffDays(os.date("*t"), t))

12.6

該函數用於計算兩個指定日期之間相差的月份

function timeDiffMonth(x, y)
    year = x.year - y.year
    month = x.month - y.month
    return math.abs(year) * 12 + math.abs(month)
end

t = os.date("*t")
t.year = 2023
t.month = 7
print(timeDiffMonth(os.date("*t"), t))

12.7

向指定日期添加一個月再添加一天得到的結果,是否與先添加一天再添加一個月得到的結果相同

buff = {
    year = 2023,
    month = 6,
    day = 30
}

t = os.date("*t", os.time(buff))
t.day = t.day + 1
t.month = t.month + 1

t2 = os.date("*t", os.time(buff))
t2.month = t2.month + 1
t2.day = t2.day + 1

print(os.difftime(os.time(t), os.time(t2)))

t = os.date("*t", os.time(buff))
t.day = t.day + 1
t = os.date("*t", os.time(t))
t.month = t.month + 1

t2 = os.date("*t", os.time(buff))
t2.month = t2.month + 1
t2 = os.date("*t", os.time(t2))
t2.day = t2.day + 1

print(os.difftime(os.time(t), os.time(t2)))

[[
0.0
86400.0 第二種方法會產生不同結果
]]

12.8

該函數用於輸出操作系統的時區

時區劃分是規定將全球劃分為24個時區,東、西各12個時區。1884年在華盛頓召開的一次國際經度會議(又稱國際子午線會議)上,規定將全球劃分為24個時區(東、西各12個時區)。規定英國(格林尼治天文臺舊址)為中時區(零時區)、東112區,西112區。每個時區橫跨經度15度,時間正好是1小時。最後的東、西第12區各跨經度7.5度,以東、西經180度為界。

function timeZone()
    local now = os.time()
    local glnz = os.time(os.date("!*t")) -- 格林尼治時間
    return (now - glnz) // 3600
end

print(timeZone())
-- 8 東8區

13.1 ⭐

該函數用於進行無符號整型數的取模運算

將無符號整數最低位提取充當b(0或1),其餘部分為a,a必為偶數。a再拆分為 2 * a/2,2為j,a/2為k。

\[(a+b) \mod c = ((a \mod c) + (b \mod c)) \mod c \\ (j*k) \mod c = ((j \mod c) * (k \mod c)) \mod c \]

--設條件 d<= 2^64 -1 , c <= 2^63-1
function unsignedMod(d, c)
    local even = d & -2
    local odd = d & 1
    local res1 = ((2 % c) * ((even >> 1) % c)) % c -- 等價於 even % c
    local res2 = (res1 + (odd % c)) % c
    return res2
end

print(unsignedMod(-101, 4294967296) == 4294967195)
print(unsignedMod(-1, math.maxinteger) == 1)
print(unsignedMod(-1111111, 114514) == 59155)

13.2

實現計算Lua語言中整型數所占位數的不同方法

-- 忽略符號位,計算剩下的63位中共占用幾位
function countBits1(d)
    local count = 0
    while d ~= 0 do
        d = d // 2
        count = count + 1
    end
    return count
end

function countBits2(d)
    local count = 0
    d = d & math.maxinteger
    while d ~= 0 do
        d = d >> 1
        count = count + 1
    end
    return count
end

print(countBits1(math.maxinteger) == 63)
print(countBits1(10) == 4)
print(countBits1(1) == 1)
print(countBits1(0) == 0)

print(countBits2(math.maxinteger) == 63)
print(countBits2(10) == 4)
print(countBits2(1) == 1)
print(countBits2(0) == 0)

13.3

如何判斷一個指定整數是不是2的整數次冪

-- 忽略符號位,計算剩下的63位中共占用幾位
function isPowerOf2(d)
    if d <= 0 then
        return false
    end
    while d & 1 == 0 do
        d = d >> 1
    end
    d = d >> 1
    if d > 0 then
        return false
    else
        return true
    end
end

print(isPowerOf2(1))
print(isPowerOf2(2))
print(isPowerOf2(3))
print(isPowerOf2(4))
print(isPowerOf2(5))
print(isPowerOf2(6))
print(isPowerOf2(7))
print(isPowerOf2(8))

13.4

該函數用於計算指定整數的漢明權重(數二進位表示的1的個數)

function hw(d)
    local count = 0
    while d ~= 0 do
        if d & 1 == 1 then
            count = count + 1
        end
        d = d >> 1
    end
    return count
end

print(hw(1)) -- 1
print(hw(2)) -- 1
print(hw(3)) -- 2
print(hw(4)) -- 1
print(hw(5)) -- 2
print(hw(6)) -- 2
print(hw(7)) -- 3
print(hw(8)) -- 1

print(hw(-1)) -- FFFF  64
print(hw(-2)) -- FFFE  63
print(hw(-3))
print(hw(-4))
print(hw(-5))
print(hw(-6))
print(hw(-7))
print(hw(-8))

13.5

該函數用於判斷註定整數的二進位表示是否為迴文數

function isPalindrome(d)
    local t = {}
    while d ~= 0 do
        table.insert(t, d & 1)
        d = d >> 1
    end
    for i = 1, 32, 1 do
        if t[i] ~= t[64 - i + 1] then
            return false
        end
    end
    return true
end

print(isPalindrome(1))
print(isPalindrome(0))
print(isPalindrome(-1))
print(isPalindrome(math.mininteger + 1))

13.6 ⭐

請在Lua語言實現一個比特數組

  • newBiteArrary(n) 創建一個具有n個比特的數組
  • setBit(a, n, v) 將布爾值v賦值給數組a的第n位
  • testBit(a, n) 將第n位的值作為布爾值返回
function newBiteArrary(n)
    local t = {}
    local count = (n - 1) // 64 + 1
    for i = 1, n, 1 do
        table.insert(t, 0)
    end
    return t
end

function setBit(a, n, v)
    local count = (n - 1) // 64 + 1
    local n = (n - 1) % 64 + 1
    local tmp1 = math.mininteger >> (n - 1) -- 000001000000
    local tmp2 = ~tmp1 -- 1111101111111
    if v then
        a[count] = a[count] | tmp1
    else
        a[count] = a[count] & tmp2
    end
end

function testBit(a, n)
    local count = (n - 1) // 64 + 1
    local n = (n - 1) % 64 + 1
    local tmp1 = math.mininteger >> (n - 1) -- 000001000000
    if tmp1 & a[count] == 0 then
        return false
    else
        return true
    end
end

a = newBiteArrary(300)
setBit(a, 1, true)
setBit(a, 100, true)
setBit(a, 105, true)
setBit(a, 105, false)
setBit(a, 300, true)
print(testBit(a, 1))
print(testBit(a, 100))
print(testBit(a, 105))
print(testBit(a, 300))

13.7 ⭐

假設有一個以一系列記錄組成的二進位文件,其中的每一個記錄的格式為

struct Record{
 int x;
 char[3] code;
 float value;
};

請編寫一個程式,該程式讀取這個文件,然後輸出value欄位的總和

function saveRecords(t)
    local f = io.open("records.txt", "w")
    for _, v in ipairs(t) do
        f:write(string.pack("j", v.x))
        f:write(string.pack("z", v.code))
        f:write(string.pack("n", v.value))
    end
    f:close()
end

function readCalcuteValue()
    local f = io.open("records.txt", "rb")
    local s = f:read('a')
    f:close()
    local i = 1
    local total = 0
    while i <= #s do
        local x, code, value
        x, i = string.unpack('j', s, i)
        code, i = string.unpack('z', s, i)
        value, i = string.unpack('n', s, i)
        print(x, code, value)
        total = total + value
    end
    return total
end

t = {{
    x = 100000,
    code = "abc",
    value = 100
}, {
    x = 200000,
    code = "def",
    value = 200
}, {
    x = 300000,
    code = "ghi",
    value = 300
}, {
    x = 400000,
    code = "jkl",
    value = 400
}}

saveRecords(t)
sum = readCalcuteValue()
print(sum)
[[
100000  abc     100.0
200000  def     200.0
300000  ghi     300.0
400000  jkl     400.0
1000.0
]]

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本機環境:win10專業版,64位,16G記憶體。 原先用的AS2.2,是很早之前在看《第一行代碼Android(第2版)》的時候,按書里的鏈接下載安裝的,也不用怎麼配置。(PS:第一行代碼這本書對新手確實很適合,第1版是eclise,第2版是Android studio) 最近想給AS升級一下,果不 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 form 表單恢復初始數據 在現代的 Web 開發中,表單是不可或缺的組件之一。用戶可以通過表單輸入和提交數據,而開發者則需要對這些數據進行處理和存儲。然而,在某些情況下,我們可能需要重置表單並恢復到最初的狀態。 本文介紹瞭如何使用 fo ...
  • 在我的項目中,使用i18n切換語言後,會進行`router.push`來刷新頁面。 但我發現寫在store中的選項(我把它們用作下拉框組件的`options`,例如`options="store.statusOption"`),卻並沒有切換語言。它們需要我手動刷新頁面後才能夠切換語言。然而其它組件中 ...
  • # Electron-builder打包和自動更新 # 前言 文本主要講述如何為 electron 打包出來軟體配置安裝引導和結合 github 的 release 配置自動更新。 electron-builder 是將 Electron 工程打包成相應平臺的軟體的工具,我的工程是使用 [elect ...
  • 最近前輩推薦我讀《設計模式之禪》這本書,原因是我寫的代碼質量實在是一言難盡,開發速度很快,但是bug數就很多了,設計原則這種知識就需要掌握 寫這篇文主要是記錄自己的學習以及督促自己 第一章【單一職責】 從我理解的層面來談談單一原則:明確每個類每個方法的任務,只做一件事,不能一法兩用 這也是我最大的一 ...
  • # 加油站圈存機系統 ​ 對於加油卡而言,圈存是將`用戶賬戶`中已存入的資金劃轉到所持的加油卡上後方可使用。通俗一點的說法就是您在網點把錢存入主卡中,再分配到下麵的副卡,由於副卡都在使用車輛的駕駛員手中,需要在加油的時候在加油站讓加油站員工劃一下即可,就是所謂的圈存。 #### 圈存操作流程 ​ 如 ...
  • 電商系統中秒殺是一種常見的業務場景需求,其中核心設計之一就是如何扣減庫存。本篇主要分享一些常見庫存扣減技術方案,庫存扣減設計選擇並非一味追求性能更佳,更多的應該考慮根據實際情況來進行架構取捨... ...
  • springboot項目通常配合mybatisplus來做數據CRUD。 我們在查詢或更新數據的時候,有時要用到in來過濾數據。比如SELECT * FROM emax_scbg_order WHERE order_no IN (1305679009380433922,130540525947283 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...