本文收集了10个常见的Solidity面试问题,旨在帮助求职者准备Solidity技术面试。这些问题不仅适合潜在的Solidity开发者自我测试,也可供招聘经理用以评估应聘者的技能水平。每个问题都提供了示例答案和简要解释,以帮助读者理解其重要性。
前10名 Solidity 面试问题帮助你为下一个 Solidity 技术面试做好准备。作为智能合约开发者,加入你梦想的团队!
如果你正在为一个 Solidity 技术面试做准备,找到相关的问题进行学习和练习可能具有挑战性,尤其是当这种语言正好存在不到十年的时候。
在本文中,我们收集了许多在一些最大区块链协议的技术面试中常被问到的前10名 Solidity 面试问题。
这个量身定制的问题列表将使你能够展示你的 Solidity 技能,而不会在小众的"陷阱"类型问题上跌倒。重点倾向于开放式的主题讨论,而不是狭窄的问题。
有志于成为 Solidity 开发者的人可以利用这些问题来测试他们的知识并为下次面试做准备。招聘经理可以使用这份 Solidity 面试问题列表作为识别初级开发者的路线图,并作为经验丰富的智能合约开发者展示的舞台。
每个问题都包括了示例答案和简要解释,以详细说明其背后的目的。
*从技术上讲,如果你可以读取 EVM 字节码,那么你不需要 ABI。你可以使用像 Foundry 的 cast 这样的工具手动创建 calldata。尽管这个问题相对简单,但它有效地探讨了进行 Solidity 开发所需的基本知识。我们的 初学者课程 详细说明了与 Remix 的合约交互,并提供有关合约 ABI 的更多信息。
Solidity 的基础知识。
可见性关键字
可变性和修饰符关键字
msg.value
在函数调用中直接接收原生气体代币。自定义修饰符
数据结构
成为优秀 Solidity 开发者还有很多内容远不止理解关键字,但对整体情况有良好的了解显然是重要的。在我们的 Solidity 智能合约开发课程 中可以找到更全面的内容。
delegatecall
来调用库的外部函数。仅包含内部函数的库不被部署,并且由于没有状态交互而不需要使用 delegatecall
。对这些构建块有扎实的理解,对于防止大型项目中出现大块杂乱无章的代码是非常重要的。
一盘温暖的意大利面代码。
一个称职的开发者应该能够快速列出常见的 EIP。如果他们难以举出基本代币以外的例子,那么他们就没有深入探讨许多核心的 DeFi 概念。拥有相关 EIP 经验的 Solidity 开发者是有价值的。
智能合约是不可变的,除非它们利用代理模式。代理模式解锁了更改实现合约地址的能力,使合约可以升级。所有模式使用 delegatecall
来调用实现,同时在中心化代理中维护状态。实现使用初始化器而不是构造函数。需要一个管理员来执行实现地址的更改。
功能选择符冲突、存储冲突和初始化缺失只是使用代理模式开发期间可能产生的一些错误。不熟悉这些概念的开发者和安全爱好者可能想要查看这篇 深入了解代理模式的综合介绍。深入理解代理对确保可升级项目在升级前、后保持无错误至关重要。
能够清晰表达 web3 概念的整体画面的一位开发者很可能是真正对整个生态系统充满热情和知识的人。
模糊测试是 向系统提供随机或半随机数据,以尝试找到破坏 不变性 的有害输入。不变性是系统必须始终保持真实的属性。形式验证 是将 底层逻辑解构 成数学证明的方法,以证明或反驳不变性将维持。
一个有状态的模糊测试随机调用更改状态的函数,以在系统中通过独特状态旅行,然后通过 invariant_
或 statefulFuzz_
标签的函数检查以确保声明的属性和不变性得以维持。以下是一个使用修改过的 Counter
合约的模拟示例,基于初始化的 Foundry 项目。
contract Counter {
uint256 public number;
uint256 public constant UPPER_LIMIT = 100;
function setNumber(uint256 newNumber) public {
require(newNumber <= UPPER_LIMIT, "数字太高");
number = newNumber;
}
function increment() public {
require(number < UPPER_LIMIT, "达到了限制");
number++;
}
}
contract CounterTest is StdInvariant, Test {
Counter public counter;
function setUp() public {
counter = new Counter();
// 强制模糊测试器专注于此合约进行测试。
targetContract(address(counter));
}
// 必须在 `invariant_` 前缀表示
// 与状态改变函数之间运行的与不变性相关的条件。
function invariant_numberNeverExceedsLimit() public {
assertTrue(counter.number() <= counter.UPPER_LIMIT());
}
理解和讨论测试技术的能力与开发者的成熟度相关。严格地尝试破坏 Solidity 代码尤为重要,因为用户资金直接与代码交织在一起。如果错误的代码被发布,恶意行为者将利用它来窃取资金。在糟糕的代码中发现许多缺陷的智能合约安全审查可能会大幅增加开发成本,如果代码库需要被废弃或大幅更改的话。
一名在铸造厂工作的男人,戴着安全帽。
cast sig
命令从函数签名生成函数选择器。运行 cast sig "transfer(address,uint256)"
将成功生成正确的函数选择器 0xa9059cbb
。CREATE
:合约地址创建的 默认方法。地址是通过从编码的发送者和其当前随机数的结果哈希中提取最后 20 个字节而产生的。CREATE2
:允许合约地址的预计算。地址是通过从发送者地址的结果哈希、32 字节的盐和初始化代码的哈希提取最后 20 个字节而生成的。该盐允许构造预计算的期望地址。理解智能合约地址生成和识别 calldata 中的函数选择器及其他信息应该不是陌生的材料。
Yul 是一种 中间语言,在语法上更接近操作码指令而非 Solidity。
sload
发送者和接收者余额,使用 lt 比较器来判断发送者是否有足够的代币,依靠 sstore
更新余额,使用 log3
记录两个地址和金额的事件,并在成功时使用 mstore
和 return
返回 true。0x40
,在临时空间之后,位于零槽之前。它最初指向 0x80
作为第一个可用位置。由于 Solidity 不释放内存,当需要在内存中存储新的数据时,FMP 会在每次移动 32 字节的块。当你在函数中手动调整了 FMP 时,需要 恢复 它,以确保以后的操作不会覆盖重要数据。
对汇编有一些理解,对于制定气体优化、理解按位操作的结果以及有效阅读或集成利用 Yul 提高效率的库都可以派上用场。
这正是 Solidity 开发者可以真正大显身手的地方。阐述适当防御措施以对抗 大量攻击向量 是保持合约安全的关键。如果你能参与公开的 安全审计竞赛、漏洞奖金,或进行私密安全审查,那么这是一种积极信号。培养在开发智能合约时保持安全思维的能力是非常有价值的。
一位开发者在解释常见的 Solidity 漏洞。
这个问题可以说是最重要的。探索一个开发者的完成产品、额外成就和他们激情所在,可以更清晰地展示他们的经验和倾向。
虽然在10个面试问题中很难遍历整个 Solidity 的景观,但这旨在作为有效的指南,以提取每个问题中尽可能多的相关 Solidity 知识。作为 Solidity 开发者,借此希望你学到了新东西,并对下次面试感到更有准备。对于作为招聘经理的读者,也许这可以作为一份基础信息的指引,帮助你寻找下一个 Solidity 梦之队。
任何热衷于 web3 开发和安全的人都应该加入 Cyfrin Updraft 来开启学习之旅,或在下次面试前拂去尘埃。
- 原文链接: cyfrin.io/blog/top-10-so...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!