面试流程
首先写道题,写一个分页器。
start = (pageSize*pageNun),end = in.length>(start+pageSize)?(start+pageSize):in.length
了解你能够实习的时长。
1、web接口太慢,怎么优化,有什么思路去优化?
- 数据库优化
- 代码优化
- 负载均衡
- 缓存优化
- 网络优化
2、怎么通过查看日志去排错和优化?
- 监控系统状态
- 调试和排错题。
- 性能优化
- 安全监控。
- 业务分析
3、redis储存了一个set集合,更新的时候存在并发问题,怎么解决?
- redis的乐观锁和悲观锁实现
- 这是一个项目中值得考虑改进的操作!!!!!!
4、了解过聚合索引吗?
- 聚合索引就是内容按一定顺序排序;非聚合索引索引和内容分开储存。
5、代码管理工具git的工作流,代码分支怎么使用?
- master、develop、feature、release、hotfix5种分支
此外,补充一些面试后的知识学习
1、为什么不可以用synchronize来限制同步客户端对服务器中的redis的数据更新请求?
-
虽然synchronize关键字可以用来在多线程程序中保证共享数据的同步和互斥访问,但在分布式系统中,synchronize并不能有效地限制同步客户端对Redis服务器中的数据更新请求。
-
这是因为在分布式系统中,Redis服务器可以被多个客户端同时访问和更新,而**不同客户端之间的线程并不共享内存。**因此,使用synchronize关键字在不同客户端之间进行同步是不可能的。
-
在分布式系统中,一般采用分布式锁或乐观锁等机制来限制并发访问和更新。Redis中支持的WATCH和MULTI命令可以用来实现基于版本号的乐观锁,而SETNX和EXPIRE命令可以用来实现基于锁的悲观锁。使用这些机制可以保证在多个客户端同时对Redis进行访问和更新时,数据的原子性和一致性。
2、单体web应用中更新redis中的数据存在并发问题,怎么解决?
在单体web应用中更新Redis中的数据存在并发问题时,可以考虑以下几种解决方法:
- 使用Redis的事务机制:Redis支持事务机制,可以将多个操作一起提交,从而确保操作的原子性。可以使用Redis的MULTI和EXEC指令来执行事务,确保在事务执行期间不会被其他客户端打断。
- 使用Redis的乐观锁机制:通过对Redis中的数据进行版本控制,当要更新某个数据时,首先检查该数据的版本号是否与自己持有的版本号一致,如果一致则执行更新操作,否则放弃更新。这种方式不会阻塞其他客户端对数据的访问,但是需要注意版本号的更新策略,以避免出现数据不一致的情况。
- 使用Redis的悲观锁机制:通过在更新数据时对数据进行加锁,确保同一时间只有一个客户端可以对数据进行修改。可以使用Redis的SETNX指令实现悲观锁,但是需要注意加锁时间过长会降低并发性能。
- 使用分布式锁:在集群环境下,可以使用分布式锁来确保并发更新的数据的一致性。可以使用ZooKeeper或者Redisson等开源框架实现分布式锁机制。
3、java分别实现一下redis的乐观锁和悲观锁操作
redis乐观锁
public boolean updateWithOptimisticLock(String key, String expectedValue, String newValue) {
Jedis jedis = null;
try {
jedis = pool.getResource(); //连接到redis
jedis.watch(key); //监视,保证同步
String currentValue = jedis.get(key);
if (currentValue != null && currentValue.equals( expectedValue )) {
Transaction tx = jedis.multi(); //redis事务
tx.set(key, newValue);
List<Object> result = tx.exec(); //执行结果
return result != null && !result.isEmpty();
}
return false;
} finally {
if (jedis != null) { //释放连接
jedis.close();
}
}
}
上述代码中,使用Jedis库建立与Redis服务器的连接,然后通过watch方法来监视key所对应的值,如果key的值在watch和exec方法之间没有被其他客户端修改,则可以执行更新操作。
这里应该加上,如果被修改了,那就应该重试。
- 基于版本号的乐观锁实现原子性更新数据:
- 客户端获取要更新数据的版本号和当前值。
- 客户端根据要更新的数据的版本号和当前值计算出新的值,然后通过Redis的WATCH命令监视要更新的数据。
- 如果被监视的数据在WATCH命令和UPDATE操作之间没有被其他客户端修改,那么客户端执行UPDATE操作并提交事务,否则客户端需要重试更新操作。
Redis悲观锁:
public boolean updateWithPessimisticLock(String key, String newValue) {
Jedis jedis = null;
try {
jedis = pool.getResource(); //链接
Long lock = jedis.setnx(key + "_lock", "1"); //枷锁
if (lock == 1) {
jedis.expire(key + "_lock", 10);
jedis.set(key, newValue);
jedis.del(key + "_lock");
return true;
}
return false;
} finally {
if (jedis != null) {
jedis.close();
}
}
}
上述代码中,使用setnx方法来对key加锁,如果加锁成功,则可以执行更新操作。在更新完成后,需要使用del方法释放锁。
需要注意的是,使用悲观锁可能会降低系统的并发性能,因此应该根据具体业务情况选择适当的锁机制。同时,在使用乐观锁时,需要根据具体的场景进行版本号的更新策略,以避免出现数据不一致的情况。
- 基于SETNX指令的悲观锁实现原子性更新数据:
- 客户端使用SETNX命令对要更新的数据进行加锁,如果加锁成功则进行更新操作,否则等待一段时间后重试。
- 客户端在完成更新操作后需要使用DEL命令释放锁。