面试题手册

梳理高频技术问题,帮助你按主题复习和查漏补缺。

前端阅读 12月7日 00:13

Java中的对象是如何创建的?

在Java中,对象是通过使用关键字 new 来创建的。首先,我们需要定义一个类,类是创建对象的模板。当我们使用 new 关键字创建类的实例时,Java虚拟机(JVM)会在堆内存中为该对象分配空间,并调用构造函数来初始化对象。例如,如果我们有一个名为 Person 的类:public class Person { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; }}我们可以通过以下方式创建 Person 类的对象:Person person = new Person("John Doe", 30);这里,new Person("John Doe", 30) 部分首先为 Person 对象分配堆内存,然后调用 Person 类的构造函数,并传入 "John Doe" 和 30 作为参数,完成对象的初始化。
前端阅读 02月7日 00:13

如何在Java中创建线程?

在Java中创建线程主要有两种方式:继承Thread类:首先,定义一个继承自Thread的类。然后,在该类中覆写run()方法,将你想要在该线程中执行的代码放入run()方法中。创建这个继承了Thread类的实例,并调用实例的start()方法来启动线程。示例代码: class MyThread extends Thread { public void run(){ System.out.println("我的线程正在运行"); } } public class TestThread { public static void main(String args[]) { MyThread t = new MyThread(); t.start(); // 启动线程 } }实现Runnable接口:定义一个实现了Runnable接口的类。实现该接口的run()方法,在这个方法里放入你想在线程中运行的代码。创建该类的实例,并将它作为参数传递给Thread的构造函数来创建一个线程对象。调用线程对象的start()方法来启动线程。示例代码: class MyRunnable implements Runnable { public void run(){ System.out.println("通过Runnable接口创建线程"); } } public class TestRunnable { public static void main(String args[]) { MyRunnable myRunnable = new MyRunnable(); Thread t = new Thread(myRunnable); t.start(); // 启动线程 } }这两种方法本质上都是构建一个可以独立执行的代码块,并通过start()方法来让Java虚拟机调用这个代码块的run()方法。使用Runnable接口的方式更加灵活,因为Java不支持多重继承,所以当你的类已经继承了其他类时,只能选用实现Runnable接口的方式来创建线程。
前端阅读 12月7日 00:10

MySQL中NULL值和零值有什么区别?

在MySQL中,NULL值代表字段中没有数据,即该字段是空的。它用于表示未知或不适用的值。而零值是一个实际的数据值,表示数值0。在逻辑上,NULL与任何其他值(包括零)都不相等,甚至NULL与NULL之间也不相等。这意味着在进行比较时,任何包含NULL的计算或比较的结果也是NULL。而零值在比较时表现为具体的数值0,可以直接用于计算和比较。
前端阅读 02月7日 00:10

MySQL中有哪些不同的数据类型?

在MySQL中,数据类型主要可以分为以下几类:数值类型:整型:TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT浮点数和双精度:FLOAT, DOUBLE, DECIMAL日期和时间类型:DATE:仅日期TIME:仅时间DATETIME:日期和时间TIMESTAMP:时间戳YEAR:年份字符串类型:字符串:CHAR, VARCHAR文本:TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT二进制:BINARY, VARBINARY二进制文本:TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB枚举类型:ENUM集合类型:SET空间数据类型:GEOMETRY, POINT, LINESTRING, POLYGON, 等等。JSON数据类型:JSON每种数据类型都有其特定用途和存储需求,选择合适的数据类型可以优化数据库性能和存储效率。
前端阅读 02月7日 00:09

Python 对象名称前的单下划线和双下划线是什么意思?

在Python中,对象名称前加单下划线(_)和双下划线(__)有不同的含义:单下划线(_):作用:它通常用来指示变量或函数是“内部使用”的,或者说是“私有”的,虽然这只是一种约定,并不会真正阻止外部访问。约定:这是一个程序员之间的约定,意味着这样的属性或方法主要供类内部使用,不应该在类的外部被使用。Python并没有强制这样的属性或方法不能在类的外面访问。双下划线(__):作用:在Python中,以双下划线开头的属性或方法表示名称改写(name mangling)以避免在子类中被覆盖。名称改写:如果你在一个类中定义了一个以双下划线开头的属性,Python解释器会把这个属性的名称改写为_ClassName__AttributeName,这使得它在子类中更难被意外访问和修改。目的:主要用于在类中封装私有变量,防止在继承中由于变量名相同而造成覆盖。
前端阅读 02月7日 00:05

Solidity中assert和require有什么区别?

在Solidity中,assert 和 require 用于处理错误和异常条件,但它们的用途和行为有明显差异:require: 通常用于输入验证或满足合约执行前的条件。如果 require 的条件失败,交易将被撤销,所有状态修改将被回滚,并退还剩余的gas。require 很适合用来检查外部条件(如函数参数值、合约状态等)。assert: 用于检查代码逻辑不应该发生的内部错误。通常,assert 用于检测合约内部状态的错误或不一致。如果 assert 的条件失败,同样会导致交易被撤销,所有状态修改被回滚。但与 require 不同的是,assert 失败将消耗所有提供的gas。简而言之,require 用于输入或条件检查,而 assert 用于确保代码逻辑在执行过程中的正确性。
前端阅读 02月7日 00:04

Solidity中的回退功能是什么?

在Solidity中,回退函数(Fallback Function)是一种特殊的函数,它没有名称、不接受任何参数也不返回任何值。这个函数会在合约接收到以太币(Ether)但没有匹配到其他任何函数时被调用,或者当调用的函数签名与合约中的任何已定义函数都不匹配时被触发。它通常用于直接接收以太币的转账或作为一个通用的异常处理器。在Solidity 0.6.x之后的版本,为了使合约代码更清晰和更安全,分成了两种类型的回退函数:接收函数(Receive function) - 专门用来处理纯ETH发送(不带任何数据的ETH转账)。这个函数必须用receive() external payable来声明。回退函数(Fallback function) - 如果没有匹配到接收函数,或者调用了不存在的函数,或者发送了ETH但调用包含数据,那么回退函数会被触发。这个函数是用fallback() external payable来声明的。这两个函数的存在提供了灵活性和安全性,使智能合约能够根据发送的是纯ETH还是带数据的ETH调用来适当地响应。
前端阅读 02月7日 00:03

Solidity中有多少种类型的库?

在Solidity中,库(Libraries)主要分为两类:函数库(Functional Libraries):这种类型的库包含了一系列的静态函数,可以在智能合约中被调用,但不能存储状态变量。函数库的目的是为了代码复用,例如常见的数学运算或数据结构操作。数据类型库(Data Type Libraries):这种类型的库对特定的数据类型提供扩展的功能,通常通过使用using for语法。这允许库中的函数作为目标类型的方法被调用,可以看作是向现有数据类型添加新的方法或属性。
前端阅读 12月7日 00:01

TypeScript中的接口是什么?

在TypeScript中,接口(Interface)是一个重要的结构,用于定义对象的形状,也就是用来描述对象中应该包含哪些属性和方法以及它们的类型。接口主要用于类型检查,让开发者在编写代码时能确保满足特定的结构和类型约束。接口可以包括属性和方法的声明,但所有这些都是抽象的,没有具体的实现。使用接口后,任何实现了该接口的类都必须遵循接口中定义的结构。例子:interface Person { name: string; age: number; greet(phrase: string): void;}class User implements Person { name: string; age: number; constructor(n: string, a: number) { this.name = n; this.age = a; } greet(phrase: string) { console.log(phrase + ' ' + this.name); }}在上述代码中,Person 接口规定了一个类必须有 name 和 age 两个属性,并且有一个 greet 方法。User 类实现了这个接口,因此必须提供这些属性和方法的具体实现。这样的机制有助于保证TypeScript中的数据结构和行为的一致性。
前端阅读 02月6日 23:59

在TypeScript中使用泛型有什么好处?

在TypeScript中使用泛型主要有以下几个好处:类型安全:泛型可以帮助保持代码的类型安全性。通过使用泛型,可以在编译时期检查类型是否正确,从而减少运行时发生错误的可能性。代码复用:泛型允许我们编写可重用的代码组件。一个泛型类或函数可以用不同的类型参数来使用,这样就可以用同一套代码来处理不同类型的数据,增加了代码的复用性。灵活性和可扩展性:使用泛型可以使代码更加灵活和可扩展。你可以定义一个泛型接口或类,用户在使用时可以根据自己的需要来指定具体的类型,这样一来,代码库就可以更容易地适应未来的需求变化。更好的维护性:泛型让类型的使用更加明确,降低了因类型错误或不当使用而引起的问题,从而减少维护成本。集成开发环境(IDE)的支持:使用泛型还可以提高开发效率,因为大多数现代IDE都能够利用泛型提供更准确的代码自动完成、类型检查和文档提示。
前端阅读 12月6日 23:57

Vue中如何重用具有key属性的元素?

在Vue中,key属性主要用于Vue的虚拟DOM算法,以便跟踪可复用的元素。当你有一组元素,并且可能会动态地改变顺序或更新列表中的元素时,使用key可以帮助Vue准确地识别哪些元素是新的,哪些被重用了。这可以提高渲染性能并减少潜在的渲染错误。例如,如果你有一个列表,每个列表项都可能被更新或重新排序,你可以这样使用key:<div id="app"> <ul> <li v-for="item in items" :key="item.id"> {{ item.text }} </li> </ul></div>在这个例子中,每个li元素都被赋予了一个基于item.id的唯一key。当items数组发生变化时,Vue会使用key来确定哪些元素可以被保留,哪些需要重新创建。这种方法特别有用,比如在进行列表排序或替换列表中的项目时,因为Vue可以就地复用DOM结构和组件实例,避免不必要的元素重建和组件状态丢失。
前端阅读 12月6日 23:56

vue中如何在本地注册指令?

在Vue中,可以通过两种方式在组件中本地注册指令:全局注册和局部注册。局部注册指令要在单个组件中局部注册指令,你可以在组件的选项对象中使用 directives 属性。这里是一个基本的例子:<template> <div v-my-directive>我是一个有指令的元素</div></template><script>export default { directives: { 'my-directive': { bind(el, binding, vnode) { // 当指令第一次绑定到元素时调用 el.style.backgroundColor = 'yellow'; }, update(el, binding, vnode, oldVnode) { // 被绑定元素所在的模板更新时调用 if (binding.value !== binding.oldValue) { el.style.backgroundColor = binding.value; } } } }}</script>在上面的例子中:directives 对象中定义了一个名为 my-directive 的指令。bind 钩子在指令第一次绑定到元素时调用,这里用来设置元素的初始样式。update 钩子在包含该指令的组件的 VNode 更新时被调用,可以通过比较 binding.value 和 binding.oldValue 来决定是否需要更新元素的样式。这种方式的指令只能在声明它的那个组件内使用。
前端阅读 12月6日 23:56

vue中分组routes 到chunks中有什么优势?

在Vue中,将routes分组到chunks中主要有以下几个优势:性能优化:通过代码分割,只有在用户实际访问对应路由时,才会加载相应的chunk。这样可以减少应用初始加载时的文件大小,使得应用启动更快。按需加载:分组后的chunks可以实现按需加载,即按页面或功能模块加载资源,从而避免加载整个应用的所有脚本和资源,提升页面的响应速度和用户体验。缓存利用:将公共依赖和库分离到单独的chunks中,这些chunks可以被多个路由共享,并且可以被浏览器缓存起来。当用户访问其他页面时,若已缓存这些公共chunks,将不需要重新加载,这样可以减少网络请求,加快加载速度。简化调试:在开发过程中,如果每个路由的依赖都在独立的chunk中,当某个页面出现问题时,可以快速定位到对应的chunk,这样可以更加快捷和准确地进行bug修复和性能优化。更好的适应性和可维护性:随着应用规模的扩大,全部加载可能导致网页变得非常庞大。通过分组到chunks,可以将功能模块化,使得项目结构更清晰,便于管理和维护。
前端阅读 02月6日 23:55

在web应用程序安全测试期间可以执行哪些类型的安全测试?

在Web应用程序安全测试期间,可以执行以下几种类型的安全测试:静态应用程序安全测试(SAST):这种测试通过分析应用程序的源代码、字节码或二进制代码来发现安全漏洞,而不需要运行程序。动态应用程序安全测试(DAST):这种测试方法在应用程序运行时对其进行测试,模拟外部攻击以发现运行时的安全漏洞。交互式应用程序安全测试(IAST):结合了SAST和DAST的特点,通过在应用程序运行时进行分析以实时发现安全漏洞。渗透测试:模拟黑客的攻击行为,尝试从外部或内部进入系统,以发现可能被利用的安全漏洞。配置和部署管理测试:检查网络和应用程序的部署设置,确保安全配置措施得当,没有配置错误。漏洞扫描:利用自动化工具扫描Web应用程序的漏洞库,以发现已知的安全漏洞。API安全测试:专门测试API的安全性,检查认证、授权、数据加密等方面是否有缺陷。逻辑错误测试:测试应用程序的业务逻辑,确保逻辑设计没有导致安全问题。通过这些综合的测试方法,可以全面评估Web应用程序的安全性,从而确保在上线前发现并修复可能的安全漏洞。
前端阅读 02月6日 23:54

Yarn如何并行运行多个脚本

在Yarn中,并行运行多个脚本可以通过多种方式实现,常见的方法有使用concurrently、npm-run-all或者是简单的shell命令组合。使用concurrently:concurrently是一个npm包,可以同时运行多个命令。首先你需要安装这个包: npm install concurrently --save-dev然后在package.json的scripts部分,可以定义使用concurrently来运行多个脚本: { "scripts": { "start": "concurrently \"npm run script1\" \"npm run script2\"" } }这里script1和script2是你想要并行运行的脚本名。这行命令会启动这两个脚本,它们会在同一时间内运行。使用npm-run-all:另一个工具是npm-run-all,它同样可以用来并行或顺序执行多个npm脚本。首先安装这个工具: npm install npm-run-all --save-dev在package.json中使用它来并行运行脚本: { "scripts": { "start": "npm-run-all --parallel script1 script2" } }使用--parallel标志将使script1和script2并行执行。使用Shell命令:如果不想添加额外的依赖,可以使用Shell命令来并行运行脚本: { "scripts": { "start": "npm run script1 & npm run script2" } }使用&符号可以在Unix-like系统中并行运行命令。如果是在Windows中,可以使用start命令来达到相同的效果。以上这些方法都可以在Yarn中实现脚本的并行运行,具体选择哪一种方法可以根据项目需求和团队习惯来定。
前端阅读 02月6日 23:51

如何启动和停止MySQL服务器?

在不同的操作系统上启动和停止MySQL服务器的方法会有所不同。以下是一些常见系统的基本指令:在Linux系统上启动MySQL服务:sudo systemctl start mysqld停止MySQL服务:sudo systemctl stop mysqld在Windows系统上首先,打开命令提示符或PowerShell。启动MySQL服务:net start MySQL停止MySQL服务:net stop MySQL在macOS系统上启动MySQL服务:sudo /usr/local/mysql/support-files/mysql.server start停止MySQL服务:sudo /usr/local/mysql/support-files/mysql.server stop这些命令假设MySQL已正确安装在默认路径,并且服务名称没有被修改。如果你的安装和服务名称有所不同,你可能需要调整这些命令以适应你的具体情况。
前端阅读 02月6日 23:50

为什么在使用babel-loader时要排除node_modules?

在使用 babel-loader 时排除 node_modules 目录的主要原因是性能优化。node_modules 目录中通常包含了大量的第三方库,这些库大部分已经是预编译过的 JavaScript 代码,它们通常不需要再次通过 Babel 进行转换。如果 babel-loader 处理这些已经编译过的文件,会显著增加构建过程的时间,从而降低了构建效率。此外,处理这些不需要转换的文件还可能引入不必要的问题或错误,因为第三方库中的代码可能已经针对特定的环境或规范做了优化,再次用 Babel 转换可能会破坏这些优化。因此,通过排除 node_modules 目录,我们可以确保 babel-loader 只处理应用的源代码,从而提高构建效率并减少潜在的编译问题。
前端阅读 02月6日 23:33

编程中方法和函数有什么区别?

在编程中,方法和函数都是代码块,它们执行特定的操作,但主要区别在于它们的定义和调用上。函数是一段相对独立的代码,它可以接收输入(参数),执行特定任务,并返回输出(结果)。函数可以被定义在程序的任何地方,且它的调用通常不依赖于对象实例。函数的主要目的是为了封装代码以便复用和模块化。例如,Python中的函数定义:def add_numbers(x, y): return x + y方法则是与对象相关联的函数。它是定义在类内部的,并且通常用于执行和这个类的对象相关的操作。方法不仅可以访问到它的参数,还可以访问类中的其他属性和方法。方法的调用通常依赖于类的实例。例如,Python中的方法定义:class MathOperations: def add_numbers(self, x, y): return x + y总结来说,方法是类的一部分,依赖于类的实例;而函数则更为独立,可以在没有任何类的情况下执行。
前端阅读 02月6日 23:29

PostgreSQL中的外键是什么?

外键是一种数据库约束,用于建立两个表之间的关系。在PostgreSQL中,一个表中的外键引用另一个表的主键。这样的设定确保了数据的一致性和完整性。当表中的一列被指定为外键时,该列的值必须在被引用表的主键列中已存在,或者为NULL(如果允许的话)。这样可以防止在关联表中插入不存在的数据,确保数据间的逻辑关系合理正确。
前端阅读 02月6日 13:11

GraphQL 如何创建查询任务?

在GraphQL中创建查询主要涉及以下几个步骤:定义 Schema:首先你需要定义你的数据结构和类型,在GraphQL中这被称为schema。Schema 定义了查询和数据类型,告诉GraphQL服务器期望的数据结构。编写查询语句:在客户端,编写GraphQL查询语句。查询语句定义了你想从服务器获取哪些数据。一个基本的查询语句通常看起来像这样:query { users { id name email }}这个查询会请求所有用户的 id、name 和 email。发送查询: 使用HTTP请求把查询从客户端发送到GraphQL服务器。通常这可以通过使用一个HTTP POST请求来完成,其中查询语句被包装在请求的body中。处理查询:服务器接收到查询后会根据定义的schema处理查询,然后从数据库或其他数据源检索数据。返回响应:服务器处理完查询后,会将数据按照查询请求的格式返回给客户端。通过这些步骤,客户端能够获取到它请求的具体数据。这种方式使得数据的获取更加灵活和高效。