面试题答案
一键面试性能优化
- 网络I/O优化
- 使用NIO(New I/O):Java NIO提供了基于通道(Channel)和缓冲区(Buffer)的I/O操作,是非阻塞式的,能有效提高网络I/O性能。例如,在服务器端处理大量并发连接时,使用
Selector
配合ServerSocketChannel
和SocketChannel
实现多路复用I/O,减少线程开销。
Selector selector = Selector.open(); ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.socket().bind(new InetSocketAddress(port)); serverSocketChannel.configureBlocking(false); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { int readyChannels = selector.select(); if (readyChannels == 0) continue; Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> keyIterator = selectedKeys.iterator(); while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (key.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel client = server.accept(); client.configureBlocking(false); client.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { SocketChannel client = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); client.read(buffer); buffer.flip(); // 处理数据 } keyIterator.remove(); } }
- 连接池:对于频繁的网络连接操作,如数据库连接、远程服务调用等,使用连接池技术。例如,使用HikariCP作为数据库连接池,它具有高性能和低资源消耗的特点。
<dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>4.0.3</version> </dependency>
HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/yourdatabase"); config.setUsername("username"); config.setPassword("password"); HikariDataSource dataSource = new HikariDataSource(config); Connection connection = dataSource.getConnection();
- 使用NIO(New I/O):Java NIO提供了基于通道(Channel)和缓冲区(Buffer)的I/O操作,是非阻塞式的,能有效提高网络I/O性能。例如,在服务器端处理大量并发连接时,使用
- 内存管理
- 分析内存使用情况:使用工具如VisualVM或YourKit Java Profiler来分析内存使用,找出内存泄漏或频繁的内存分配/回收区域。例如,通过VisualVM连接到运行中的Java应用程序,查看堆内存使用情况、对象实例数量等。
- 优化对象创建:尽量减少不必要的对象创建。如果对象创建开销较大且需要频繁使用,可以考虑对象池技术。例如,使用Apache Commons Pool2实现对象池。
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.8.1</version> </dependency>
GenericObjectPoolConfig<MyObject> config = new GenericObjectPoolConfig<>(); config.setMaxTotal(100); ObjectPool<MyObject> pool = new GenericObjectPool<>(new MyObjectFactory(), config); MyObject obj = pool.borrowObject(); // 使用obj pool.returnObject(obj);
- 调整堆内存大小:根据应用程序的实际需求,合理调整Java堆内存的大小。可以通过
-Xms
(初始堆大小)和-Xmx
(最大堆大小)参数来设置。例如,java -Xms512m -Xmx1024m -jar yourApp.jar
。
- 算法优化
- 分析算法复杂度:对应用中使用的关键算法进行复杂度分析,找出性能瓶颈。例如,如果使用了暴力搜索算法,可以考虑替换为更高效的搜索算法,如二分搜索(适用于有序数据)。
- 缓存优化:对于频繁计算且结果不经常变化的数据,可以使用缓存。例如,使用Guava Cache实现本地缓存。
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>31.0.1 - jre</version> </dependency>
LoadingCache<String, Integer> cache = CacheBuilder.newBuilder() .maximumSize(1000) .expireAfterWrite(10, TimeUnit.MINUTES) .build( new CacheLoader<String, Integer>() { @Override public Integer load(String key) throws Exception { // 计算值 return calculateValue(key); } }); Integer value = cache.get(key);
安全加固
- 防止SQL注入
- 使用预编译语句:在Java中,使用JDBC的
PreparedStatement
代替Statement
。例如:
String sql = "SELECT * FROM users WHERE username =? AND password =?"; PreparedStatement statement = connection.prepareStatement(sql); statement.setString(1, username); statement.setString(2, password); ResultSet resultSet = statement.executeQuery();
- ORM框架:使用如Hibernate或MyBatis等ORM框架,它们在一定程度上可以防止SQL注入。例如,在Hibernate中,使用HQL(Hibernate Query Language)进行数据库查询:
String hql = "FROM User WHERE username = :username AND password = :password"; Query<User> query = session.createQuery(hql, User.class); query.setParameter("username", username); query.setParameter("password", password); List<User> users = query.list();
- 使用预编译语句:在Java中,使用JDBC的
- 防止XSS(跨站脚本攻击)
- 输入验证和过滤:对用户输入的数据进行严格的验证和过滤,只允许合法字符通过。可以使用正则表达式进行验证。例如,验证邮箱格式:
String emailRegex = "^[A - Za - z0 - 9+_.-]+@[A - Za - z0 - 9.-]+$"; if (email.matches(emailRegex)) { // 合法 }
- 输出编码:在将数据输出到前端页面时,对特殊字符进行编码。例如,使用
StringEscapeUtils
类(来自Apache Commons Lang库)对HTML进行转义:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons - lang3</artifactId> <version>3.12.0</version> </dependency>
String escaped = StringEscapeUtils.escapeHtml4(userInput);
- 防止其他常见攻击(如CSRF - 跨站请求伪造)
- CSRF Token:在前端页面生成一个随机的CSRF Token,并在每次表单提交或AJAX请求时将其发送到服务器。服务器验证Token的有效性。例如,在Spring Boot中,可以通过配置开启CSRF保护:
@Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); } }
- 安全头设置:设置一些HTTP安全头,如
Content - Security - Policy
(CSP),限制页面可以加载的资源来源,防止恶意脚本注入。例如,在Spring Boot中,可以通过配置设置CSP头:
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addHeaderWriter(HeaderWriterRegistry registry) { registry.addHeaderWriter(new StaticHeaderWriter("Content - Security - Policy", "default - src'self'")); } }