记录面试中遇到的问题,希望可以帮助到大家!
1.使用数据库的批处理功能来执行多个 SQL 语句。这可以减少每个 SQL 语句的通信开销。JDBC 中的 addBatch()
和 executeBatch()
方法可以用来执行批处理操作。
在程序开始时候设置禁止自动提交事务,将所有的sql语句添加到preparedStatement中,在程序执行过程中如果报错的话就回滚数据库事务。
public static void main(String[] args) { String jdbcUrl = "jdbc:mysql://localhost:3306/your_database"; String username = "your_username"; String password = "your_password"; try (Connection connection = DriverManager.getConnection(jdbcUrl, username, password)) { // 关闭自动提交,启用事务 connection.setAutoCommit(false); String sql = "INSERT INTO your_table (column1, column2) VALUES (?, ?)"; try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { // 添加多条 SQL 语句到批处理中 for (int i = 0; i < 1000; i++) { preparedStatement.setInt(1, i); preparedStatement.setString(2, "Value " + i); preparedStatement.addBatch(); } // 执行批处理 int[] updateCounts = preparedStatement.executeBatch(); // 提交事务 connection.commit(); } catch (SQLException e) { // 回滚事务 connection.rollback(); e.printStackTrace(); } } catch (SQLException e) { e.printStackTrace(); } }
2.使用多线程的方式处理,创建一个含有五个线程的线程池,逐个提交所有的sql语句,在线程的run方法中执行sql语句
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MultiThreadSQLExecution { public static void main(String[] args) { String jdbcUrl = "jdbc:mysql://localhost:3306/your_database"; String username = "your_username"; String password = "your_password"; String sqlFilePath = "path_to_your_sql_file.sql"; int numThreads = 5; // 指定线程数 ExecutorService executorService = Executors.newFixedThreadPool(numThreads); try { Connection connection = DriverManager.getConnection(jdbcUrl, username, password); BufferedReader reader = new BufferedReader(new FileReader(sqlFilePath)); String line; while ((line = reader.readLine()) != null) { // 提交每一条 SQL 语句给线程池 executorService.submit(new SQLExecutionTask(connection, line)); } // 等待所有线程完成 executorService.shutdown(); while (!executorService.isTerminated()) { Thread.sleep(100); } reader.close(); connection.close(); } catch (SQLException | IOException | InterruptedException e) { e.printStackTrace(); } } static class SQLExecutionTask implements Runnable { private Connection connection; private String sql; SQLExecutionTask(Connection connection, String sql) { this.connection = connection; this.sql = sql; } @Override public void run() { try (Statement statement = connection.createStatement()) { statement.execute(sql); System.out.println("Executed SQL: " + sql); } catch (SQLException e) { e.printStackTrace(); } } } }
1xx - 信息性状态码(Informational)
2xx - 成功状态码(Successful)
3xx - 重定向状态码(Redirection)
4xx - 客户端错误状态码(Client Errors)
5xx - 服务器错误状态码(Server Errors)
使用双指针的方法,快指针比慢指针先走n步,然后快慢指针同时出发,最后快指针到达尾部时慢指针就是答案
public class ListNode { int val; ListNode next; ListNode(int val) { this.val = val; } } public int findNthFromEnd(ListNode head, int n) { ListNode slow = head; ListNode fast = head; // 将fast指针向前移动n个节点 for (int i = 0; i < n; i++) { if (fast == null) { return -1; // 处理n大于链表长度的情况 } fast = fast.next; } // 同时移动slow和fast指针,直到fast指针到达链表末尾 while (fast != null) { slow = slow.next; fast = fast.next; } // 此时slow指向倒数第n个节点 return slow.val; }
HTTP(Hypertext Transfer Protocol)是一种用于传输数据的协议,它定义了客户端和服务器之间的通信规则。在HTTP中,GET和POST是两种常见的请求方法,它们在使用和请求体内容方面有一些区别。
GET 请求:
POST 请求:
GET 和 POST都是http请求方式, 底层都是 TCP/IP协议;通常GET 产生一个 TCP 数据包;POST 产生两个 TCP 数据包(但firefox是发送一个数据包),对于 GET 方式的请求,浏览器会把 http header 和 data 一并发送出去,服务器响应 200
(返回数据)表示成功;而对于 POST,浏览器先发送 header,服务器响应 100, 浏览器再继续发送 data,服
务器响应 200 (返回数据)。
POST请求通常将数据放在请求体中传输,而不是像GET请求那样将数据附加在URL中。这是POST请求的典型用法,因为POST请求通常用于传输较大量的数据,如表单提交、文件上传等。虽然理论上你可以将数据附加在URL中,但这不是POST请求的标准做法,而且由于URL长度限制,可能会导致数据丢失或不完整。
1、所有的写操作以数据库为准,只要到达缓存过期时间,缓存删除
2、如果后面还有读请求的话,就会从数据库中读取新值然后回填缓存
在写库前后都进行redis.del(key)操作,并且设定合理的超时时间。
1、先删除缓存2、再写数据库3、休眠xxx毫秒(根据具体的业务时间来定)4、再次删除缓存
1、涉及到更新的数据操作,利用Mysql binlog 进行增量订阅消费
2、将消息发送到消息队列
3、通过消息队列消费将增量数据更新到Redis上
4、操作情况
在CPU指令中,有些指令是非常危险的,如果错用将导致系统崩溃,比如清内存、设置时钟等,所以CPU将指令分为特权指令和非特权指令。对于危险指令,只允许操作系统及其相关模块使用,普通应用程序只能使用不危险的指令。
存储位置:Cookie:Cookie是存储在用户浏览器中的小型文本文件。每当用户访问一个网站时,服务器都可以向用户的浏览器发送一个或多个Cookie,然后浏览器将这些Cookie保存在用户的本地计算机上。Session:Session数据通常存储在服务器端。服务器会为每个会话(通常对应一个用户的一次访问会话)创建一个唯一的标识符,然后将相关数据存储在服务器的内存中或持久化到数据库中。
安全性:Cookie:Cookie存储在用户的浏览器中,因此可以被用户修改或删除。虽然可以使用加密技术增强Cookie的安全性,但仍然容易受到跨站脚本攻击(XSS)等攻击。Session:Session数据存储在服务器上,用户无法直接访问或修改。这使得Session通常比Cookie更安全,但服务器端的安全性仍然至关重要。
存储容量:Cookie:浏览器对Cookie的存储容量有限制,通常每个Cookie的大小不应超过几KB。这限制了Cookie可以存储的数据量。Session:服务器端的存储通常比较大,可以存储更多的数据,不受浏览器限制。
有效期:Cookie:可以设置Cookie的过期时间。可以是会话Cookie(浏览器关闭后失效)或持久Cookie(在一段时间后失效)。Session:会话数据通常在用户关闭浏览器时自动失效,但也可以通过设置过期时间来延长其有效期。
用途:Cookie:主要用于跟踪用户的身份、记录用户偏好设置、购物车信息等。它们通常用于客户端状态管理。Session:用于在服务器端维护用户的会话状态,通常用于身份验证、授权、购物车管理等服务器端状态管理。
跨页面传递:Cookie:可以在不同页面之间传递数据,因为它们存储在浏览器中,可以被不同页面的JavaScript代码读取。Session:Session数据通常存储在服务器上,可以在服务器上的不同页面之间共享,但需要通过会话标识符进行访问。
具体来说,文件锁通常分为两种类型:
安全性:HTTP:HTTP是不安全的协议,所有数据以明文形式传输,容易被中间人攻击拦截和窃取敏感信息。HTTPS:HTTPS通过在HTTP协议上添加安全性特性,使用SSL/TLS协议对数据进行加密和认证。这意味着在HTTPS通信中,数据在传输过程中经过加密,不容易被窃取或篡改,从而提供了更高的安全性。
加密:HTTP:HTTP不提供数据加密功能,因此所有数据都是明文传输的。HTTPS:HTTPS使用SSL/TLS协议来加密通信数据,确保数据在传输过程中保持机密性。
认证:HTTP:HTTP不提供服务器身份验证机制,因此难以确保连接的终端是否与预期的服务器相连。HTTPS:HTTPS使用数字证书来验证服务器的身份,确保连接到的是正确的服务器。这可以防止中间人攻击。