MicroPython字节码文件——mpy文件解析

2024-03-26 17:12
文章标签 解析 字节 micropython mpy

本文主要是介绍MicroPython字节码文件——mpy文件解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考文档:MicroPython .mpy files

前置注意点

  • mpy文件的二进制文件是一种嵌套格式。先描述外层模块,然后描述子模块。
  • 使用vint(变长编码)表示整数,当前字节最高位置1表示还有后续字节。
  • 不同版本的MicroPython对应的mpy文件格式不一定兼容。

MicroPython项目提供了一个脚本mpy-tool.py来解析mpy文件的内容,所以想知道mpy文件的结构、具体包含了哪些信息,可以阅读下这个脚本源码。

You can inspect the contents of a .mpy file by using mpy-tool.py, for
example (run from the root of the main MicroPython repository):
$ ./tools/mpy-tool.py -xd myfile.mpy

可以自行下载阅读器(比如winHex),查看mpy文件的十六进制码。
在这里插入图片描述

mpy文件内容概览

全局的mpy文件内容构成如图,首先是4个字节的header,接着是2个vint,分别表示qstr和obj的数量。
在这里插入图片描述

Header

4个字节的头部,用于标识mpy文件和版本、CPU架构要求、小整型的位数。
在这里插入图片描述

qstr and constant objects tables

在这里插入图片描述

qstr表

在这个表中,每个qstr对象都由一个表示长度的vint和后续数据组成。

qstr unit

在这里插入图片描述
注意,mpy文件里的len是实际qstr长度的2倍。这是由于最低位用来判别是否为static qstr。比如字节码为 0a 416c 6963 6500,第一个字节0a最高位为0,表示无后续字节,则qstr长度为a/2 = 5。后面跟着5个字节为qstr的内容“Alice",第六个字节00表示字符串的结束。

def read_qstr(reader, segments):start_pos = reader.tell()ln = reader.read_uint()if ln & 1:# static qstrq = global_qstrs.get_by_index(ln >> 1)segments.append(MPYSegment(MPYSegment.META, q.str, start_pos, start_pos))return qln >>= 1start_pos = reader.tell()data = str_cons(reader.read_bytes(ln), "utf8")reader.read_byte()  # read and discard null terminatorsegments.append(MPYSegment(MPYSegment.QSTR, data, start_pos, reader.tell()))return global_qstrs.add(data)

obj表 //todo: 待补充

def read_obj(reader, segments):obj_type = reader.read_byte()if obj_type == MP_PERSISTENT_OBJ_FUN_TABLE:return MPFunTable()elif obj_type == MP_PERSISTENT_OBJ_NONE:return Noneelif obj_type == MP_PERSISTENT_OBJ_FALSE:return Falseelif obj_type == MP_PERSISTENT_OBJ_TRUE:return Trueelif obj_type == MP_PERSISTENT_OBJ_ELLIPSIS:return Ellipsiselif obj_type == MP_PERSISTENT_OBJ_TUPLE:ln = reader.read_uint()return tuple(read_obj(reader, segments) for _ in range(ln))else:ln = reader.read_uint()start_pos = reader.tell()buf = reader.read_bytes(ln)if obj_type in (MP_PERSISTENT_OBJ_STR, MP_PERSISTENT_OBJ_BYTES):reader.read_byte()  # read and discard null terminatorif obj_type == MP_PERSISTENT_OBJ_STR:obj = str_cons(buf, "utf8")if len(obj) < PERSISTENT_STR_INTERN_THRESHOLD:if not global_qstrs.find_by_str(obj):global_qstrs.add(obj)elif obj_type == MP_PERSISTENT_OBJ_BYTES:obj = bufelif obj_type == MP_PERSISTENT_OBJ_INT:obj = int(str_cons(buf, "ascii"), 10)elif obj_type == MP_PERSISTENT_OBJ_FLOAT:obj = float(str_cons(buf, "ascii"))elif obj_type == MP_PERSISTENT_OBJ_COMPLEX:obj = complex(str_cons(buf, "ascii"))else:raise MPYReadError(reader.filename, "corrupt .mpy file")segments.append(MPYSegment(MPYSegment.OBJ, obj, start_pos, reader.tell()))return obj

obj对象类型

MP_PERSISTENT_OBJ_FUN_TABLE = 0
MP_PERSISTENT_OBJ_NONE = 1
MP_PERSISTENT_OBJ_FALSE = 2
MP_PERSISTENT_OBJ_TRUE = 3
MP_PERSISTENT_OBJ_ELLIPSIS = 4
MP_PERSISTENT_OBJ_STR = 5
MP_PERSISTENT_OBJ_BYTES = 6
MP_PERSISTENT_OBJ_INT = 7
MP_PERSISTENT_OBJ_FLOAT = 8
MP_PERSISTENT_OBJ_COMPLEX = 9
MP_PERSISTENT_OBJ_TUPLE = 10

raw code header

在这里插入图片描述
字节码的头部是一个vint类型,最低两位表示代码类型

kind_len = reader.read_uint() # 读取一个vint
kind = (kind_len & 3) + MP_CODE_BYTECODE  # 取低2位加上MP_CODE_BYTECODE个偏移量

4种代码类型定义如下

MP_CODE_BYTECODE = 2
MP_CODE_NATIVE_PY = 3
MP_CODE_NATIVE_VIPER = 4
MP_CODE_NATIVE_ASM = 5

低第三位表示有无子模块,0表示无子模块,1表示有子模块。

has_children = (kind_len >> 2) & 1

其余位表示长度,注意字节的最高位只用于表示有无后续字节,不算进长度表示的位中。
头部后面跟着的就是字节码的内容了。


示例

最后放个py源码和生成的mpy字节码供大家参考学习。

class Wallet:def __init__(self, owner_name, balance=0):self.owner_name = owner_nameself.balance = balancedef deposit(self, amount):if amount > 0:self.balance += amountprint(f"Deposited ${amount}. New balance: ${self.balance}")else:print("Invalid deposit amount.")def withdraw(self, amount):if amount > 0 and self.balance >= amount:self.balance -= amountprint(f"Withdrew ${amount}. New balance: ${self.balance}")else:print("Invalid or insufficient funds for withdrawal.")def transfer(self, recipient_wallet, amount):if self.balance >= amount and recipient_wallet is not self:if amount > 0:self.withdraw(amount)recipient_wallet.deposit(amount)print(f"Transferred ${amount} to {recipient_wallet.owner_name}.")else:print("Invalid transfer amount.")else:print("Insufficient funds or invalid recipient.")def check_balance(self):print(f"Current balance: ${self.balance}")# Example usage:
# Create two wallet instances
wallet1 = Wallet("Alice", 100)
wallet2 = Wallet("Bob", 50)# Deposit money into wallet1
wallet1.deposit(50)# Withdraw money from wallet1
wallet1.withdraw(20)# Transfer money from wallet1 to wallet2
wallet1.transfer(wallet2, 30)# Check balance of wallet1 and wallet2
wallet1.check_balance()
wallet2.check_balance()
00000000: 4d06 001f 1608 1c77 616c 6c65 745f 7465  M......wallet_te  wallet_test.py
00000010: 7374 2e70 7900 0f0c 5761 6c6c 6574 000a  st.py...Wallet..  <module> Wallet
00000020: 416c 6963 6500 0642 6f62 000e 6465 706f  Alice..Bob..depo  Alice Bob deposit
00000030: 7369 7400 1077 6974 6864 7261 7700 1074  sit..withdraw..t  withdraw transfer
00000040: 7261 6e73 6665 7200 1a63 6865 636b 5f62  ransfer..check_b  check_balance
00000050: 616c 616e 6365 0023 146f 776e 6572 5f6e  alance.#.owner_n  __init__ owner_name
00000060: 616d 6500 0e62 616c 616e 6365 0081 290e  ame..balance..).  balance format
00000070: 7761 6c6c 6574 3100 0e77 616c 6c65 7432  wallet1..wallet2  wallet1 wallet2
00000080: 002f 2d35 8213 0c61 6d6f 756e 7400 8177  ./-5...amount..w  __name__ __module__ __qualname__ self amount print
00000090: 2072 6563 6970 6965 6e74 5f77 616c 6c65   recipient_walle  recipient_wallet
000000a0: 7400 051f 4465 706f 7369 7465 6420 247b  t...Deposited ${  Deposited ${}. New balance: ${}
000000b0: 7d2e 204e 6577 2062 616c 616e 6365 3a20  }. New balance:  
000000c0: 247b 7d00 0517 496e 7661 6c69 6420 6465  ${}...Invalid de  Invalid deposit amount.
000000d0: 706f 7369 7420 616d 6f75 6e74 2e00 051e  posit amount.... 
000000e0: 5769 7468 6472 6577 2024 7b7d 2e20 4e65  Withdrew ${}. Ne  Withdrew ${}. New balance: ${}
000000f0: 7720 6261 6c61 6e63 653a 2024 7b7d 0005  w balance: ${}.. 
00000100: 2d49 6e76 616c 6964 206f 7220 696e 7375  -Invalid or insu  Invalid or insufficient funds for withdrawal.
00000110: 6666 6963 6965 6e74 2066 756e 6473 2066  fficient funds f 
00000120: 6f72 2077 6974 6864 7261 7761 6c2e 0005  or withdrawal... 
00000130: 1654 7261 6e73 6665 7272 6564 2024 7b7d  .Transferred ${}  Transferred ${} to {}.
00000140: 2074 6f20 7b7d 2e00 0518 496e 7661 6c69   to {}....Invali  Invalid transfer amount.
00000150: 6420 7472 616e 7366 6572 2061 6d6f 756e  d transfer amoun 
00000160: 742e 0005 2849 6e73 7566 6669 6369 656e  t...(Insufficien  Insufficient funds or invalid recipient.
00000170: 7420 6675 6e64 7320 6f72 2069 6e76 616c  t funds or inval 
00000180: 6964 2072 6563 6970 6965 6e74 2e00 0514  id recipient.... 
00000190: 4375 7272 656e 7420 6261 6c61 6e63 653a  Current balance:  Current balance: ${}
000001a0: 2024 7b7d 0085 2418 1201 8923 2b6a 6968   ${}..$....#+jih  <module>
000001b0: 6a27 5432 0010 0234 0216 0211 0210 0322  j'T2...4......." 
000001c0: 8064 3402 160d 1102 1004 2232 3402 160e  .d4......."24... 
000001d0: 110d 1405 2232 3601 5911 0d14 0694 3601  ...."26.Y.....6. 
000001e0: 5911 0d14 0711 0e9e 3602 5911 0d14 0836  Y.......6.Y....6 
000001f0: 0059 110e 1408 3600 5951 6301 8274 0814  .Y....6.YQc..t..  Wallet
00000200: 0228 6820 8407 8407 840b 110f 1610 1002  .(h ............ 
00000210: 1611 802a 0153 3300 1609 3201 1605 3202  ...*.S3...2...2. 
00000220: 1606 3203 1607 3204 1608 5163 0581 18a3  ..2...2...Qc....  __init__
00000230: 010c 0912 0a0b 4024 b1b0 180a b2b0 180b  ......@$........ 
00000240: 5163 8310 3210 0512 1360 6025 2951 b180  Qc..2....``%)Q..  deposit
00000250: d844 5ab0 5713 0bb1 e55a 180b 1214 2300  .DZ.W....Z....#. 
00000260: 140c b1b0 130b 3602 3401 5942 4712 1423  ......6.4.YBG..# 
00000270: 0134 0159 5163 8348 3210 0612 1380 0d2c  .4.YQc.H2......,  withdraw
00000280: 2951 b180 d844 61b0 130b b1db 445a b057  )Q...Da.....DZ.W 
00000290: 130b b1e6 5a18 0b12 1423 0214 0cb1 b013  ....Z....#...... 
000002a0: 0b36 0234 0159 4247 1214 2303 3401 5951  .6.4.YBG..#.4.YQ 
000002b0: 6385 083b 1807 1215 1380 142d 2527 2751  c..;.......-%''Q  transfer
000002c0: 49b0 130b b2db 4473 b1b0 ded3 446d b280  I.....Ds....Dm.. 
000002d0: d844 5fb0 1406 b236 0159 b114 05b2 3601  .D_....6.Y....6. 
000002e0: 5912 1423 0414 0cb2 b113 0a36 0234 0159  Y..#.......6.4.Y 
000002f0: 4247 1214 2305 3401 5942 4712 1423 0634  BG..#.4.YBG..#.4 
00000300: 0159 5163 8130 2108 0812 801f 1214 2307  .YQc.0!.......#.  check_balance
00000310: 140c b013 0b36 0134 0159 5163            .....6.4.YQc mpy_source_file: wallet_test.mpy
source_file: wallet_test.py
header: 4d:06:00:1f
qstr_table[22]:wallet_test.py<module>WalletAliceBobdepositwithdrawtransfercheck_balance__init__owner_namebalanceformatwallet1wallet2__name____module____qualname__selfamountprintrecipient_wallet
obj_table: ['Deposited ${}. New balance: ${}', 'Invalid deposit amount.', 'Withdrew ${}. New balance: ${}', 'Invalid or insufficient funds for withdrawal.', 'Transferred ${} to {}.', 'Invalid transfer amount.', 'Insufficient funds or invalid recipient.', 'Current balance: ${}']
simple_name: <module>raw bytecode: 84 18:12:01:89:23:2b:6a:69:68:6a:27:54:32:00:10:02:34:02:16:02:11:02:10:03:22:80:64:34:02:16:0d:11:02:10:04:22:32:34:02:16:0e:11:0d:14:05:22:32:36:01:59:11:0d:14:06:94:36:01:59:11:0d:14:07:11:0e:9e:36:02:59:11:0d:14:08:36:00:59:11:0e:14:08:36:00:59:51:63prelude: (4, 0, 0, 0, 0, 0)args: []line info: 89:23:2b:6a:69:68:6a:2754          LOAD_BUILD_CLASS 32:00       MAKE_FUNCTION 010:02       LOAD_CONST_STRING Wallet34:02       CALL_FUNCTION 216:02       STORE_NAME Wallet11:02       LOAD_NAME Wallet10:03       LOAD_CONST_STRING Alice22:80:64    LOAD_CONST_SMALL_INT 10034:02       CALL_FUNCTION 216:0d       STORE_NAME wallet111:02       LOAD_NAME Wallet10:04       LOAD_CONST_STRING Bob22:32       LOAD_CONST_SMALL_INT 5034:02       CALL_FUNCTION 216:0e       STORE_NAME wallet211:0d       LOAD_NAME wallet114:05       LOAD_METHOD deposit22:32       LOAD_CONST_SMALL_INT 5036:01       CALL_METHOD 159          POP_TOP 11:0d       LOAD_NAME wallet114:06       LOAD_METHOD withdraw94          LOAD_CONST_SMALL_INT 20 36:01       CALL_METHOD 159          POP_TOP 11:0d       LOAD_NAME wallet114:07       LOAD_METHOD transfer11:0e       LOAD_NAME wallet29e          LOAD_CONST_SMALL_INT 30 36:02       CALL_METHOD 259          POP_TOP 11:0d       LOAD_NAME wallet114:08       LOAD_METHOD check_balance36:00       CALL_METHOD 059          POP_TOP 11:0e       LOAD_NAME wallet214:08       LOAD_METHOD check_balance36:00       CALL_METHOD 059          POP_TOP 51          LOAD_CONST_NONE 63          RETURN_VALUE children: ['Wallet']
simple_name: Walletraw bytecode: 46 08:14:02:28:68:20:84:07:84:07:84:0b:11:0f:16:10:10:02:16:11:80:2a:01:53:33:00:16:09:32:01:16:05:32:02:16:06:32:03:16:07:32:04:16:08:51:63prelude: (2, 0, 0, 0, 0, 0)args: []line info: 28:68:20:84:07:84:07:84:0b11:0f       LOAD_NAME __name__16:10       STORE_NAME __module__10:02       LOAD_CONST_STRING Wallet16:11       STORE_NAME __qualname__80          LOAD_CONST_SMALL_INT 0 2a:01       BUILD_TUPLE 153          LOAD_NULL 33:00       MAKE_FUNCTION_DEFARGS 016:09       STORE_NAME __init__32:01       MAKE_FUNCTION 116:05       STORE_NAME deposit32:02       MAKE_FUNCTION 216:06       STORE_NAME withdraw32:03       MAKE_FUNCTION 316:07       STORE_NAME transfer32:04       MAKE_FUNCTION 416:08       STORE_NAME check_balance51          LOAD_CONST_NONE 63          RETURN_VALUE children: ['__init__', 'deposit', 'withdraw', 'transfer', 'check_balance']
simple_name: __init__raw bytecode: 19 a3:01:0c:09:12:0a:0b:40:24:b1:b0:18:0a:b2:b0:18:0b:51:63prelude: (5, 0, 0, 3, 0, 1)args: ['self', 'owner_name', 'balance']line info: 40:24b1          LOAD_FAST 1 b0          LOAD_FAST 0 18:0a       STORE_ATTR owner_nameb2          LOAD_FAST 2 b0          LOAD_FAST 0 18:0b       STORE_ATTR balance51          LOAD_CONST_NONE 63          RETURN_VALUE children: []
simple_name: depositraw bytecode: 50 32:10:05:12:13:60:60:25:29:51:b1:80:d8:44:5a:b0:57:13:0b:b1:e5:5a:18:0b:12:14:23:00:14:0c:b1:b0:13:0b:36:02:34:01:59:42:47:12:14:23:01:34:01:59:51:63prelude: (7, 0, 0, 2, 0, 0)args: ['self', 'amount']line info: 60:60:25:29:51b1          LOAD_FAST 1 80          LOAD_CONST_SMALL_INT 0 d8          BINARY_OP 1 __gt__ 44:5a       POP_JUMP_IF_FALSE 26b0          LOAD_FAST 0 57          DUP_TOP 13:0b       LOAD_ATTR balanceb1          LOAD_FAST 1 e5          BINARY_OP 14 __iadd__ 5a          ROT_TWO 18:0b       STORE_ATTR balance12:14       LOAD_GLOBAL print23:00       LOAD_CONST_OBJ 'Deposited ${}. New balance: ${}'14:0c       LOAD_METHOD formatb1          LOAD_FAST 1 b0          LOAD_FAST 0 13:0b       LOAD_ATTR balance36:02       CALL_METHOD 234:01       CALL_FUNCTION 159          POP_TOP 42:47       JUMP 712:14       LOAD_GLOBAL print23:01       LOAD_CONST_OBJ 'Invalid deposit amount.'34:01       CALL_FUNCTION 159          POP_TOP 51          LOAD_CONST_NONE 63          RETURN_VALUE children: []
simple_name: withdrawraw bytecode: 57 32:10:06:12:13:80:0d:2c:29:51:b1:80:d8:44:61:b0:13:0b:b1:db:44:5a:b0:57:13:0b:b1:e6:5a:18:0b:12:14:23:02:14:0c:b1:b0:13:0b:36:02:34:01:59:42:47:12:14:23:03:34:01:59:51:63prelude: (7, 0, 0, 2, 0, 0)args: ['self', 'amount']line info: 80:0d:2c:29:51b1          LOAD_FAST 1 80          LOAD_CONST_SMALL_INT 0 d8          BINARY_OP 1 __gt__ 44:61       POP_JUMP_IF_FALSE 33b0          LOAD_FAST 0 13:0b       LOAD_ATTR balanceb1          LOAD_FAST 1 db          BINARY_OP 4 __ge__ 44:5a       POP_JUMP_IF_FALSE 26b0          LOAD_FAST 0 57          DUP_TOP 13:0b       LOAD_ATTR balanceb1          LOAD_FAST 1 e6          BINARY_OP 15 __isub__ 5a          ROT_TWO 18:0b       STORE_ATTR balance12:14       LOAD_GLOBAL print23:02       LOAD_CONST_OBJ 'Withdrew ${}. New balance: ${}'14:0c       LOAD_METHOD formatb1          LOAD_FAST 1 b0          LOAD_FAST 0 13:0b       LOAD_ATTR balance36:02       CALL_METHOD 234:01       CALL_FUNCTION 159          POP_TOP 42:47       JUMP 712:14       LOAD_GLOBAL print23:03       LOAD_CONST_OBJ 'Invalid or insufficient funds for withdrawal.'34:01       CALL_FUNCTION 159          POP_TOP 51          LOAD_CONST_NONE 63          RETURN_VALUE children: []
simple_name: transferraw bytecode: 81 3b:18:07:12:15:13:80:14:2d:25:27:27:51:49:b0:13:0b:b2:db:44:73:b1:b0:de:d3:44:6d:b2:80:d8:44:5f:b0:14:06:b2:36:01:59:b1:14:05:b2:36:01:59:12:14:23:04:14:0c:b2:b1:13:0a:36:02:34:01:59:42:47:12:14:23:05:34:01:59:42:47:12:14:23:06:34:01:59:51:63prelude: (8, 0, 0, 3, 0, 0)args: ['self', 'recipient_wallet', 'amount']line info: 80:14:2d:25:27:27:51:49b0          LOAD_FAST 0 13:0b       LOAD_ATTR balanceb2          LOAD_FAST 2 db          BINARY_OP 4 __ge__ 44:73       POP_JUMP_IF_FALSE 51b1          LOAD_FAST 1 b0          LOAD_FAST 0 de          BINARY_OP 7 <is> d3          UNARY_OP 3 <not> 44:6d       POP_JUMP_IF_FALSE 45b2          LOAD_FAST 2 80          LOAD_CONST_SMALL_INT 0 d8          BINARY_OP 1 __gt__ 44:5f       POP_JUMP_IF_FALSE 31b0          LOAD_FAST 0 14:06       LOAD_METHOD withdrawb2          LOAD_FAST 2 36:01       CALL_METHOD 159          POP_TOP b1          LOAD_FAST 1 14:05       LOAD_METHOD depositb2          LOAD_FAST 2 36:01       CALL_METHOD 159          POP_TOP 12:14       LOAD_GLOBAL print23:04       LOAD_CONST_OBJ 'Transferred ${} to {}.'14:0c       LOAD_METHOD formatb2          LOAD_FAST 2 b1          LOAD_FAST 1 13:0a       LOAD_ATTR owner_name36:02       CALL_METHOD 234:01       CALL_FUNCTION 159          POP_TOP 42:47       JUMP 712:14       LOAD_GLOBAL print23:05       LOAD_CONST_OBJ 'Invalid transfer amount.'34:01       CALL_FUNCTION 159          POP_TOP 42:47       JUMP 712:14       LOAD_GLOBAL print23:06       LOAD_CONST_OBJ 'Insufficient funds or invalid recipient.'34:01       CALL_FUNCTION 159          POP_TOP 51          LOAD_CONST_NONE 63          RETURN_VALUE children: []
simple_name: check_balanceraw bytecode: 22 21:08:08:12:80:1f:12:14:23:07:14:0c:b0:13:0b:36:01:34:01:59:51:63prelude: (5, 0, 0, 1, 0, 0)args: ['self']line info: 80:1f12:14       LOAD_GLOBAL print23:07       LOAD_CONST_OBJ 'Current balance: ${}'14:0c       LOAD_METHOD formatb0          LOAD_FAST 0 13:0b       LOAD_ATTR balance36:01       CALL_METHOD 134:01       CALL_FUNCTION 159          POP_TOP 51          LOAD_CONST_NONE 63          RETURN_VALUE children: []

这篇关于MicroPython字节码文件——mpy文件解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/849253

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

OWASP十大安全漏洞解析

OWASP(开放式Web应用程序安全项目)发布的“十大安全漏洞”列表是Web应用程序安全领域的权威指南,它总结了Web应用程序中最常见、最危险的安全隐患。以下是对OWASP十大安全漏洞的详细解析: 1. 注入漏洞(Injection) 描述:攻击者通过在应用程序的输入数据中插入恶意代码,从而控制应用程序的行为。常见的注入类型包括SQL注入、OS命令注入、LDAP注入等。 影响:可能导致数据泄

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

多线程解析报表

假如有这样一个需求,当我们需要解析一个Excel里多个sheet的数据时,可以考虑使用多线程,每个线程解析一个sheet里的数据,等到所有的sheet都解析完之后,程序需要提示解析完成。 Way1 join import java.time.LocalTime;public class Main {public static void main(String[] args) thro

ZooKeeper 中的 Curator 框架解析

Apache ZooKeeper 是一个为分布式应用提供一致性服务的软件。它提供了诸如配置管理、分布式同步、组服务等功能。在使用 ZooKeeper 时,Curator 是一个非常流行的客户端库,它简化了 ZooKeeper 的使用,提供了高级的抽象和丰富的工具。本文将详细介绍 Curator 框架,包括它的设计哲学、核心组件以及如何使用 Curator 来简化 ZooKeeper 的操作。 1

Unity3D自带Mouse Look鼠标视角代码解析。

Unity3D自带Mouse Look鼠标视角代码解析。 代码块 代码块语法遵循标准markdown代码,例如: using UnityEngine;using System.Collections;/// MouseLook rotates the transform based on the mouse delta./// Minimum and Maximum values can