当前位置: 首页 > news >正文

网站会对特殊的ip做跳转上海市企业

网站会对特殊的ip做跳转,上海市企业,个人企业查询,长沙高端网站建设公司面试总结 注#xff1a;循序渐进#xff0c;由点到面#xff0c;从技术点的理解到项目中的使用#xff0c; ​ 要让面试官知道#xff0c;我所知道的要比面试官更多 一、Mybatis 为ORM半持久层框架#xff0c;它封装了JDBC#xff0c;开发时只需要关注sql语句就可以了… 面试总结 注循序渐进由点到面从技术点的理解到项目中的使用 ​ 要让面试官知道我所知道的要比面试官更多 一、Mybatis 为ORM半持久层框架它封装了JDBC开发时只需要关注sql语句就可以了不需要去花费精力去处理加载驱动创建连接等过程。mybatis的灵活度很高支持动态sql。mybatis还支持二级缓存机制优点为降低磁盘IO提高数据库性能。一级缓存为sqlSession下的缓存只针对当前sql会话层不能垮sqlSession访问。二级缓存为namespace下的缓存它的作用域范围为namespace下所以作用范围是大于一级缓存。通常执行查询语句时是先去查询二级缓存如不存在则在去寻找一级缓存。缓存的数据结构其实就是一个HashMap。mysql在默认情况下一级缓存是默认被开启的二级缓存需要手动配置开启。一般针对那种读多写少的情况我们可以开启二级缓存因为所有的增删改都会刷新二级缓存导致二级缓存失效所以适合在查询为主的应用中使用。SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder获得每一个mybatis实例都是已一个SqlSessionFactory对象为核心在运行期间都是存在的所以不需要重复创建是一种单例模式。另外SqlSessionFactory是SqlSession的创建工厂。mybatis支持sql预编译#{}为预编译所以可以防止sql注入保证数据库的安全二、SQL调优/MySQL 1.针对SQL优化我们可以配置借助工具记录慢查询日志等来记录哪些sql属于慢查询。2.首先查看慢查询的SQL是否有新建索引并且是否有使用到索引。比如在项目中where条件后面用到的比较多的字段我们可以设置为索引字段针对查询经常用到的字段并且唯一值比较多的可以设置为索引。对那种唯一值比较少的比如类型字段则没有必要设置索引如果设置了索引反而会影响到更新和新增的效率。3.使用MySQL的explain来查看慢sql的执行计划查看该sql是否有使用到索引有没有做全表扫描。我们可以根据执行计划中的访问类型type字段来判断SQL的访问效率。访问效率从最好到最坏依次为system const eq_ref ref fulltext ref_or_null index_merge unique_subquery index_subquery range index ALL 一般情况下访问类型至少要能达到range最好是达到ref以上。4.避免全量查询避免使用*争取降低IO提高查询效率。阿里开发手册规定禁止三张表以上的JOIN减少子查询。另外在数据库设计的时候对一些字段可以做适当的冗余不一定要遵循三范式的设计原则。5.避免索引失效的情况比如like模糊查询时模糊查询字段中开头用到‘%’会导致索引失效。6.隐式转换也会导致所以的失效比如数据库类型为int然后的时候传参为String。7.在使用表达式的情况下也会导致索引的失效。8.在组合索引下如果未按照最左匹配原则会导致索引失效。9.再就是MySQL的版本在搭建选型时可选择高一点的版本比如MySQL 5.6以上有索引下推的优化降低了网络IO。以及要注意在InoDB的聚合索引下需要知道回表和索引覆盖的情况等。10.当数据量很大时也会导致索引的失效可以考虑使用强制索引force index或者对数据量比较大的表可以做水平拆分、垂直拆分来提高查询效率。比如我们可以新建多个数据库实例通过中间件比如Mycat、sharding-jdbc来实现数据库集群来提高数据库的查询能力和容灾能力。如果单个mysql实例下我们也可以采用表分区的办法来提高查询性能像单表数据达到500W以上时就可以做表分区操作分区可以按照时间分片、取模分片、hash分片等。11.在分布式情况下可以使用雪花算法生成分布式id。因为B树下除了会维护一个从上到下的顺序还会维护一个从左到右的查询顺序。而雪花算法生成的分布式id是有序的所以更加符合B树的特性。12.查询条件中带有or,除非所有的查询条件都建有索引否则索引失效。随机主键会导致也分裂 主键顺序插入的话相对效率会更高一些因为在B树中只需要不断往后叠加即可。但是如果主键是非顺序插入效率就会低很多因为肯能会涉及到页分裂的问题假设现在多个节点有存多条数据每个节点存33条记录主键值分别为1、2、3、4、5…10等然后我们要插入一条主键值为4.5的记录那么就需要把主键值为5的记录向后移动进而导致主键为9的记录也要往后移动。页分裂会导致数据插入效率降低并且占用更多的存储空间。 MySQL的底层原理面试 1.mysql的空洞效应和页分裂如何产生如何优化 答因大量数据的前提下系统使用期间有数据的删除操作导致mysql的B树存储数据失去了从左到右的连续性形成空洞效应导致慢查询。Mysql5.6以上可以根据专门的sql定位到对应的空洞数据然后再来做相应的整理。 2.mysql的乐观锁和悲观锁 3.redo.log和undo.log已经mysql的bilong日志有哪几种类型主从模式下应该选择哪一种 答bilong日志类型有Statement、Row以及Mixed如果要支持主从复制在数据库服务器性能还可以的情况下可以选择使用RAW的数据格式。 4.mysql的MVCC概念间隙锁等 5. a、回表 是针对普通索引来说的。比如员工表主键为idname为普通索引。 select * from emp where name ‘张三’ 索引的执行过程为首先利用索引name到btree索引的叶子节点找到主键索引id主键索引id在到btree上查找相应的数据。简单来说就是name的索引在Btree上保存的数据是主键id。而主键id对应的btree的叶子节点保存的才是行数据。 b、覆盖索引 select id from emp where name1 查找的列正好是主键就不需要去btree上查找可直接返回 c、最左匹配 首先索引必须是组合索引。 索引name,ageselect * from emp where age 1 不会走索引 select * from emp where name‘张三’ 走索引 因此合理的索引应该建立两个一个是name,age一个是age; ​ d、索引下推 ​ select * from emp where name 1 and age 18 ​ 是指在数据返回server的时候数据引擎就讲name 1 和 age 18的数据进行了过滤。在版本5.7之前的数据引擎先过滤掉name 1的数据返回在server处过滤age18的数据。相比较之前的返回返回数据少减少io ​ 6.mysql 缓冲池buffer poolbuffer pool默认大小为128MB,InnoDB将buffer pool分为多个page页每个页的大小为16KB。 ​ 注意点预读失效buffer pool污染 ​ 避免每次访问都造成磁盘IO以提高性能加速访问的作用 ​ 缓冲池通常以page页的单位数据存在 ​ 缓冲池常用的算法为LRU ​ InnoDB对LRU进行了优化将缓冲池分为老生代和新生代老生代默认占3/8不过可以根据innodb_old_blocks_pct这个参数来调整比例优先会访问老生代才进入新生代。 数据库的三范式 1NF: 即表的列的具有原子性,不可再分解即列的信息不能分解, 只有数据库是关系型数据库 (mysql/oracle/db2/informix/sysbase/sql server)就自动的满足1NF 2NF: 表中的记录是唯一的, 就满足2NF, 通常我们设计一个主键来实现 3NF: 即表中不要有冗余数据, 就是说表的信息如果能够被推导出来就不应该单独的设计一个字段来存放. 比如下面的设计就是不满足3NF。 sql的执行顺序 执行顺序from… where…group by… having… select … order MySQL 8.0和MySQL 5.7的区别 1.隐藏索引MySQL 8.0中的隐藏索引可以被显示和隐藏如果索引被隐藏他是不会被查询优化器使用方便进行性能调式 2.用户创建修改和授权就是创建用户和授权时需要分开执行sql 3.UTF-8编码从MySQL 8.0开始数据库的缺省编码将修改为utf8mb4,这个编码包含了所有emoji字符(表情符号)。 4.性能提升官方表示性能要比5.7快2倍尤其是在高负载、高竞争时IO性能有很大提升。 MVCC乐观锁和悲观锁共享锁 1.MVCC理解多版本并发控制 当前读快照读undo.log 2.乐观锁和悲观锁共享锁 SELECT … LOCK IN SHARE MODE走的是IS锁(意向共享锁)即在符合条件的rows上都加了共享锁这样的话其他session可以读取这些记录也可以继续添加IS锁但是无法修改这些记录直到你这个加锁的session执行完成(否则直接锁等待超时) 当select …for update 锁住的是索引或者主键时只会锁住当前行为行锁。如果锁住的是其他普通字段的时候就是锁住整张表为表锁。 3.READ-COMMITTED和REPEATABLE-READ下的InnoDB快照读有何不同 在READ-COMMITTED的隔离级别下是每个快照读都会生成并获取最新的Read view。而在REPEATABLE-READ的隔离级别下是同一个事务下的第一个快照读才会创建Read view之后的快照读获取的都是同一个Read view。 事物传播机制 request request_new support no_support 事物的隔离级别 隔离级别有 READ-UNCOMMITTED READ-COMMITTED REPEATABLE-READ SERIALIZABLE ACID 原子性—要么都成功要么都失败 undo.log 一致性—最核心和最本质的要求 隔离性锁MVCC多版本并发控制 持久性redo.log Mycat、sharding-jdbc mycat、sharding-jdbc用来做读写分离分库分表 mycat主要有三个配置文件 server.xml—主要就是mycat的配置文件设置账号、参数以及端口 schema.xml—mycat对应的物理数据库和数据表的配置 rule.xml----mycat分片的规则主要分片规则hash范围取模日期等 mycat会有全量表或者叫广播表比如那些字典表在每一个库中都需要保证一份全量的数据父子表等。 sharding-jdbc 主要是通过jar的方式引入无需proxy代理层DBA也无需改变原来的运维方式然后通过在项目中配置.property的文件就可以实现分库分表操作。由阿里开源。 Sharding-JDBC直接封装JDBC API可以理解为增强版的JDBC驱动旧代码迁移成本几乎为零 。支持多种连接池比如DBCP、C3P0、Druid等。目前只支持mysql但已有支持sql server、Oracle的计划。 三、系统如何保证安全防止攻击 1.Sql注入2.有哪两种跨站攻击XSS跨站脚本Cross-site scriptingCSRF跨站请求伪造Cross-site request forgeryXSS跨站攻击本质上是注入攻击的一种其特点是不对服务器造成伤害。就是通过站内的正常交互途径发布一些JavaScrept脚本这时服务端没有过滤这些脚本例如发布评论中含有JavaScrept的内容把这个作为内容发布到页面上其他用户访问这个页面时关不掉这些窗口。例如while (true) {alert(你关不掉我~);}如何预防我们可以在HTML进行转义或者过滤来预防XSS攻击CSRF跨站请求伪造比如用户已经我们的网站并拿到了Token然后弹出一个钓鱼的链接然后用户点击后用户的cookie就会被盗用从而导致服务器被攻击。如何预防可以使用动态token并使用过滤器来校验Token。四、过滤器和拦截器的区别 1.Filter需要在web.xml中配置依赖于Servlet2.Interceptor需要在SpringMVC中配置依赖于框架3.Filter的执行顺序在Interceptor之前4.两者的本质区别拦截器Interceptor是基于Java的反射机制而过滤器Filter是基于函数回调。从灵活性上说拦截器功能更强大些Filter能做的事情都能做而且可以在请求前请求后执行比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验比较泛的比如登录不登录之类太细的话还是建议用interceptor。不过还是根据不同情况选择合适的五、JWT、Spring security jwt和spring security知识点 jwt只是一个生成token的机制而Spring Security、Shiro这两个框架是用来后台做权限认证管理筛选的框架JWT由Header、Payload、Signature组成Header由token的类型和算法名称组成json然后base64编码后的数据。Payload为声明部分通常就是一些用户信息和其他数据的声明然后base64编码后的数据。Signature为签名部分必要条件是具备Header和Payload然后再加一个秘钥根据Header中规定的算法生成签名。Spring security是一个能够为基于Spring应用系统提供的安全访问控制解决方案的框架充分利用了Spring IOC,Spring AOP功能为系统提供了声明式的安全访问控制能力不需要企业为了安全控制去重复编写代码一个轻量级的框架。可以基于角色的权限控制对用户的访问权限进行控制其核心思想是通过一系列的filter来进行控制。spring mvc的时代用shiro比较多然后springBoot用Spring security的比较多。向每次新建springBoot项目时都可以主动去选择关联Spring security来新建项目用起来很方便。Spring security对应有好多注解这里面DenyAll 和 PermitAll 相信就不用多说了 代表拒绝和通过。RolesAllowed({USER, ADMIN})代表标注的方法只要具有USER, ADMIN任意一种权限就可以访问*****详细可以查看面试Spring Sercurity专题--基于Spring Sercurity的用户角色权限token超时刷新策略 1字段参数 jwt(或者叫 accesstoken)用户正常访问接口时提交的token过期时间设置长一些, refreshJwt(或者叫 refreshtoken)刷新token 过期时间可以设置为jwt的两倍甚至更长用于动态刷新token时候提交后台验证 tokenPeriodTimetoken过期时间戳前端每次调用接口前需要主动判断是否已经过期如果过期则提交refreshJwt访问token刷新的接口进行刷新 2.动态刷新 前端检测到token过期后携带refreshJwt访问后台刷新token的接口服务端在拦截器中依然对refreshJwt进行解析鉴权 假如refreshJwt也过期了提示登录过期强制跳转登录页 假如refreshJwt还在有效期则签发新的token返回并且也会刷新refreshtoken的有效期前端使用最新的token进行接口请求 3.总结 如果是活跃用户那么允许他在refreshJwt过期时间与token过期时间的差值这段时间内不停的动态刷新token使其做到无感知的状态下一直保持登录状态 如果用户不活跃在refreshJwt过期时间到了依然没有使用系统那么将判定为不活跃用户此时应当重定向到登录页了 六、Spring (待完成)、SpringBoot SpringBoot简化spring应用开发约定大于配置去繁化简。SpringBoot内置了各种servelt容器Tomcat/jetty等所以不需要打war到容器中去运行。直接打jar就可以直接运行。SpringBoot主要有三部分组成:pom.xml主要定义项目的构建、打包方式、以及引入类库和类库的版本控制配置文件yml相比propertiesyml类型的配置文件更强大。properties只支持key value的键值数据格式yml支持的更加广泛除了支持key value还支持对象、数组等多种数据格式所以yml配置文件更加灵活启动类和注解SpringBootApplication以及它对应的三大注解1.SpringBootConfiguration标记该类为一个配置类2.EnableAutoConfiguration开启自动配置扫描3.ComponentScan具体扫码哪些包哪些类另外SpringBoot有集成多种标准得模板类使用起来很方便。比如RestTemplate、RedisTemplate、RibbitMqTemplate、ElasticsearchTemplate等SpringBoot还默认性能很好的额连接池为HikariCP。如果为了监控也可以替换为国内优秀的连接池Druid。redis的客户端工具可以选择性能更好非阻塞I/O的Letture、RedisSon不去使用阻塞IO的Jedis客户端等。Jedis的方法调用是同步阻塞I/O的方式需要等待sockets执行完成才能执行性能先对较差。Letture、RedisSon是基于Netty框架其方法调用是非阻塞I/O所以可以用单个Letture或RedisSon连接完成各种操作。spring AOP和Spring IOCspringAOPJDK动态代理和CGlib动态代理springAOP可能会问到事务然后事务失效有哪些场景比如同方法中没有通过对象来调用方法或者非RuntimeException需要在 Transactional(rollbackFor Exception.class)因为默认为RuntimeException才会回滚spring bean 的生命周期 spring 事务传播机制 spring 如何解决依赖循环的问题 spring 中涉及到的设计模式 七、设计模式以及设计模式在项目中的使用 1.单例模式 2.工厂模式 3.代理模式 4.适配器模式 5.观察者模式八、微服务Spring Cloud 微服务的优点降低耦合、独立部署、选型灵活、容错机制、灵活扩展微服务项目用到的五大组件Eureka/Zookeeper/Nacos、Zuul/Getaway、Hystrix、Robbin、Feign其他的比如全局配置Spring Cloud ConfigSpring Cloud Bus 消息总线比如在更改ConfigServer服务端全局配置后需要触发消息总线来通知其他的Config客户端同步全局配置Spring Cloud Sleuth 链路追踪 注册与发现 注册中心主要有:Eureka、Zookeeper、NacosEureka属于C一致性A可用性P分区容错性定理中的AP。并且Eureka可集群部署支持高可用和高性能。Eureka集群中是没有主从之分的每个节点都是平等。Eureka的心跳续约机制默认为30s钟会发起续约Renew然后将注册信息同步到Eureka自己的缓存中registry、readWriteCacheMap、readOnlyCacheMap如果90s都未被续约的节点会被移除掉。心跳续约可以自行设置调整。Eureka自我保护机制在最近15分钟收到心跳续约renew低于85%(阈值可调整)则会触发自我保护机制Eureka就会认为客户端与注册中心出现了网络故障Eureka Server就会进入自我保护机制。会有以下几种情况1.此时Eureka就不会移除因长时间有没收到心跳而过期的服务2.Eureka Server依然可以接受新的服务注册但是无法同步到其他节点3.当网络恢复稳定时新的注册信息会自动同步到其他节点。Eureka自我保护机制默认打开状态建议生产环境打开此配置测试环境频繁发版本的情况下可以关闭掉。Zookeeper属于CAP定理中的CP如果追求系统的强一致性可以选择Zookeeper作为注册中心。并且ZK遵循Paxos算法中一致性协议的轻量级实现ZAB原子广播。Zookeeper集群模式下有三种角色Leader、Follower、Observer其中Observer不参与选主只提供性能上的增强。Nacos为阿里开源项目性能强大同时支持AP和CP模式并且Nacos还可以做全局配置中心。 Hystrix Hystrix 熔断降级组件它内部提供了两种执行逻辑信号量、线程池。默认情况下使用的为线程池隔离。线程池模式通过下游调用之间的线程分离来达到资源隔离的作用。当线程被打满来不及处理新的请求时可以快速失败避免扩散到其他的服务防止雪崩发生。因为线程池模式会有大量线程上下文的切换所以会导致负载过高的情况。信号量模式优点在于不存在上下文之间的切换导致的性能开销为同步执行不支持异步。并且信号量模式不支持超时。所以针对并发量大并且耗时长的采用线程池策略并发量大并且耗时短的采用信号量策略降级设置一个阈值当请求量达到规定值后可以快速失败执行降级逻辑。网关Zuul、Getaway Getaway基于Netty的NIO调用方式为非阻塞式的更加符合高并发的场景。Zuul是微服务中的网关为奈非公司产品使用BIO阻塞调用方式相比Getaway性能要差。网关主要是做鉴权和限流的控制。网关底层源码就是过滤器其中过滤器类型共分为4大类pre、routing、post、error。限流算法漏桶算法可以很好的控制容量池的大小防止流量的暴增。如果漏桶溢出数据包就会被丢弃。漏桶算法可以控制端口的流量输出速率可以提供稳定的流量令牌桶算法根据限流大小往桶中添加令牌令牌桶中存在令牌则允许发送流量而如果令牌桶中不存在令牌则不允许发送流量。 Ribbon Ribbon使用的是客户端负载均衡像Nginx、F5都是属于服务端的负载均衡所以不能混淆了。如果客户端之间的调用使用的RestTemple则在RestTemple添加一个LoadBalanced就可以实现负载均衡。Feign调用的时候默认是有集成Ribbon的所以不用手动去添加。Ribbon的几种负载均衡策略随机策略、轮询策略、加权策略、重试策略、区域权衡策略、最低并发策略等默认使用的是区域内轮询策略。Feign 声明式的调用方式内部有集成Ribbon九、分布式锁 redis分布式锁的底层实现主要是根据setNx的方法演变而来执行setNx(key, value, expre)如果返回true表示加锁成功返回false表示加锁失败。在高并发的场景下直接使用setNx加锁会导致提前释放别个人锁的问题。比如setNx中的有效时间expre设置为10s但是加锁的业务代码确执行了15s因为自己的锁在10s的时候已经失效了所以15s时释放的是其他人的锁。redis官网对分布式建议是直接使用redisSon客户端工具里面有内置一个看门狗的监听程序假如加锁key的有效期为15s当加锁时间达到1/35s时间的时候看门狗会判断当前业务代码是否有执行完成如果没有执行完成则将key的有效期直接再加5s延长1/3的时间让锁的有效时间重新变为15s这样就可以防止提前释放别个锁的操作。另外在集群情况下要保证高可用redisSon还支持红锁的操作假如redis集群下共有5个节点其中过半以上的节点加锁成功3个节点以上时红锁才会生效但是红锁性能会比较差可根据实际场景使用。一般在工作中分布式锁可以结合SpringAop使用可以直接通过注解的方式加锁优点使用代码更简洁、无侵入。在使用分布式锁的时候加锁会导致业务串行化会代码影响性能所以一般分布式时是分段加锁类似于HasnMap源码中的锁分段只对当前桶加锁不去影响其他桶的操作。zookeeper的分布式锁zookeeper中有永久、临时两种类型的节点而分布式锁底层所使用的就是临时节点的特性。当临时节点生效时就会触发await通知事件然后执行下一个逻辑。zookeeper遵循cap中的cpzk在集群环境下的节点共有三种角色Leader、Follower、Observer其中Observer不参与选主只提供性能上的增强所以在强一致性的前提下也可以保证高性能。可以根据使用场景选择分布式锁的种类如果业务代码比较追求一致性可以选择ZK作为分布式锁。十一、秒杀总结 具体秒杀的架构设计可以参考黄老师讲的内容。1.这里只是对秒杀中分布式锁性能提升做对应的总结对分布式锁由串行化修改为并行化需要修改为分段加锁去实现类似于hashMap的槽位锁分段技术例如一千件商品分为10等份每份商品对应一把锁哪个线程抢到锁就去执行对应业务逻辑其他线程为等待状态就不会有超卖的发生。但是想想应该会有另一种异常情况出现客户抢不到秒杀商品、商家的商品咩有卖完的情况。因为有可能10等份的商品中其中一部分可能先被抢完后面客户端的请求会命中到没有商品的锁所以这边需要在代码层面写一个for循环去判断当该把锁下对应的商品被抢完后应该去抢其他锁下的商品。2.扣库存时也要注意如何防止超卖的发生因为数据库的事务隔离级别一般都不是串行化serializable根据事务的特性在并发的情况下可能会导致写覆盖的问题所以我们一般会使用select 。。for update 的悲观锁机制完成扣除库存时再提交事务只是在分布式系统中来说对数据库的压力会比较大。也可以选择使用乐观锁的机制如果客户A和客户B同时读取到100的库存在更新的时候会有一个操作失败这种方式可以大大提高并发性另外我们在代码中做好重试次数和重试时间的控制可以防止过多的重试带来的数据库压力。 十二、分表分库总结 1、mycat的几个xml的配置文件①.schema.xml配置逻辑库表分片和读写分离②.rule.xml具体的分片规则和分片算法③.配置默认的数据库和用户表权限另外就是全量表等等并不是所有的表都需要进行分表分库2.shareding-jdbc比较新的工具已经开放到apche顶级项目十三、redis(待完成) 1.redis面试的知识点 Redis中有序集合zset需要使用skiplist作为存储数据结构跳表的结构是怎么样的Redis的String类型中的bitmap位图是用一个bit位来标记某个元素对应的Value在Java中int占4字节1字节8位1 byte 8 bit节省存储空间统计用户每天的登陆情况下游用到布隆过滤器也有用到如何保证redis和mysql的双写一致性比如可以说下阿里的开源中间件canal通过开启mysql的bilong日志由canal同步,redis开启发布订阅来进行接收redis的冷热备份AOF和RDB的区别LRU和LFU删除策略以及过期key删除的方式定时删除和惰性删除 redis的雪崩、穿透、击穿。 布隆过滤器/布谷鸟过滤器如何防止穿透redisson的分布式锁以及看门狗机制等redis的主从高可用集群saveof psync 全量同步 增量同步 2.缓存和数据库一致性问题 关于缓存和数据库一致性的问题需取得两点共识 1.缓存必须要有过期时间 2.保持跟数据库的最终一致性即可不必追求强一致性一般都会有四种方案按照分析套路①.假如第一次成功第二次失败 ②.分别判断异常和高并发会造成什么问题③.同时A线程和B线程去更新高并发下线程有快有慢 1.先更新缓存再更新数据库 2.先更新数据库再更新缓存 3.先删除缓存再更新数据库 4.先更新数据库在删除缓存分析上面四种方案是否可行不需要死记硬背只需要记住下面两个场景会不会带来严重的问题即可 1.其中第一个操作成功第二个失败会导致什么问题 2.在高并发情况下会不会造成数据读取不一致的问题分析 第一种先更新缓存再更新数据库如果更新缓存成功更新数据库失败就会导致缓存为最新数据数据库为旧数据两者数据不一致那缓存就是脏数据。 第二种先更新数据库再更新缓存;如果更新数据库成功更新缓存失败数据库为最新数据缓存为旧数据两者数据也不一致和第一种类似。 第三种先删除缓存再更新数据库如果删除缓存成功再更新数据库失败。假设有两个线程写请求A和读请求B。首先写请求A先删除缓存成功在更新数据库的时候发生卡屯就会导致数据库依然是旧值。然后读请求B进来发现缓存没有值就会去数据库中查询得到旧值然后再把旧值set到缓存中。这时写请求A不卡了就会继续去更新数据库更新数据成功后也会导致缓存和数据库不一致。 第四种先更新数据库在删除缓存假如更新数据库成功删除缓存失败怎么办 --- 我们可以把这两步放在一个事务下面如果删除缓存失败就回滚。可是高并发环境下这种方案就不变太合适容易出现大事务导致死锁。我们可以使用重试机制比如删除缓存时我们可以重试三次如果三次都失败则记录日志到数据库然后使用XXL-JOB高并发场景之下重试应当采用异步方式比如可以使用MQ来进行异步解耦来处理。或者使用Canal框架来订阅MySQL bilong日志监听对应的更新请求执行删除对应缓存的操作。读取MySQL bilong日志异步删除:1.更新数据库2.数据库会把操作信息记录到bilong日志中3.使用Canel订阅bilong获取目标数据和key4.缓存删除系统获得Canel的数据解析目标key并进行删除操作5.如果删除缓存失败则将消息发送到MQ消息队列6.然后缓存删除系统仔从消息队列获取数据继续进行删除操作。 以上为了尽可能是的保持数据一致性除了重试机制还可以结合延迟双删的策略先删除缓存在更新数据然后休眠500ms再删除缓存。正常情况下这样子最多只会出现500ms的脏数据这500ms还是要根据各自项目的读请求的具体耗时来确定。##如果非要保持缓存和数据库的一致性我们可以先给出结论没有办法做到绝对的一致性这是由CAP理论决定的缓存系统使用的场景就是非强一致的场景所以他属于CAP中的AP。所以我们就得委曲求全可以做到BASE理论中的最终一致性尽可能的使缓存和数据库保持一致。3.redis是单线程还是多线程待完成 redis是在6.0及以上版本才正式引入多线程 4.redis其他面试点待完成 介绍一下 Redis 的线程模型 单线程的 Redis 怎么执行内存淘汰策略 redis 的全量同步和增量同步 redis master 宕机后怎么在 slave 中选举出一个作为新的 master redis 的哨兵模式master 的选举机制 十四、MQ(待完成) 14.1MQ的特性异步解耦削峰问的深一点就是如何防止消息的丢失和重复消费、以及消息的堆积等MQ之间的对比差异Rabbitmq Rocketmq kafka等防止消息的丢失:confom ack offset14.2rabbitMq通常都是topic模式由生产者发送消息到交换机然后交换机找到对应的队列。confirm模式来确保生产者不丢消息一旦消息被投递到所有匹配的队列之后rabbitMQ就会发送一个Ack给生产者14.3Rocketmq的延迟队列和事务消息角色Producer、Broker、ConsumerRocketmq如何防止消息的丢失①.生产者将消息发送到Broker需要Broker的响应响应回来的消息都需要做好try-catch妥善的处理好响应。如果Broker返回写入失败则需要做好重试发送当多次失败后需要做好报警和日志记录。这样生产者阶段就不会丢失消息。②.存储消息的阶段需要在消息刷盘成功后再给生产者响应加入消息收到就直接写入缓存然后就响应给生产者那么机器突然断电消息就会丢失掉而生产者以为发送成功了。如果broker是集群部署那消息不仅要保证当前broker已经刷盘还要保证副本也要刷盘成功才可以响应给生产者消费成功。③.消费消息阶段可能有些同学在消息者拿到消息后就放入内存队列中然后就直接给broker发送响应消费成功这是不对的。你需要去考虑如果消费消息的机器宕机了应该怎么办。所以我们应该在消费者真正执行完业务后再发送给Broker消费成功。只是说有可能因为网络抖动导致Broker端没有收到消费成功的响应Broker就不会剔除该条消息导致消息重复消费的问题这些就需要做幂等校验了。14.4kafka pattion 零拷贝 顺序写 kafka的角色分为broker:一台kafka服务器就是一台broker,一个broker可以对应多个topicbroker就是接受生产者的消息为消息设置偏移量并保存到磁盘broker为消费者提供服务对读取分区的请求作出响应返回给消费者曾经生产者已提交到磁盘的消息。produerConsumer:Topickafka的消息通过Topic来进行分类。主题Topic就好比数据库里面的表Partition分区一个Topic可以分为多个Partition每个Partion都是一个有序的队列并且保证先后读取的顺序Offset偏移量Zookeeper:Kafka使用 Zookeeper保持集群的元数据信息和消费者信息来保证集群的可用性kafka集群中只有一个lead其他的都是follower这都需要Zookeeper来保证。十五、BIO NIO Netty(待完成) liunx系统下一切接文件所以每次调用都是系统调用外部请求由用户态发起后都会切换为内核态因为内核态速率要比用户态处理速度要慢当请求量大的时候就会出现阻塞的情况。所以就有BIO阻塞性的IO。以及非阻塞IO就是NIO注在java被称为new IO,和liunx不一样。多路复用器epollepoll主要为三个函数epoll_create(size):创建一个epoll的句柄size用来告诉内核这个监听的数目一共有多大,epoll_ctle:poll的事件注册函数,epoll_await等待事件的产生和两个数据结构(红黑树和链表)提高了效率时间复杂度为O(1),不会随着系统访问的增大而成正比的增大面试上用的比较多的NIO的框架为NettyNetty包括三部分channel读取数据,ByteBuffer缓冲,Selector就是epoll。有很多工具和中间件有集成Netty,比如通信框架RPCreids的客户端工具Redissonletty,tomcat8.5以上Getaway网关等。epoll不负责数据的读写只是负责读书的事件。内存IO网络IO磁盘IO 用户空间应用层、表示层、会话层 内核空间传输控制层、网络层、链路层、物理层 NioEventLoopGroup事件循环组 shell中查看端口22服务netstat -natp | grep 22 十六、安全、防止攻击XSS等 除了最基本的sql攻击预编译可以解决 1.跨站脚本攻击 2.跨站请求攻击token盗用等以及还有涉及到的加密算法 对称加密/非对称加密 openJDK精简版本中涉及的加密可能需要坐下增强比如JCE下面需要引入Security的一些jar包十七、JVM 一.ClassLoader 类加载器明细 1.BootstrapClassLoader C类String,Object 等 2.ExtensionClassLoader 加载Java\jdk1.8.0_144\jre\lib\ext下的文件 扩展类库 3.App 加载classPath下的文件 4.customClassLoader 自定义加载器二、面试点双亲委派机制作用 打破双亲委派机制--可以重写loadClass() load-默认-初始值 (对象申请内存-赋初始值) 三、JMM cache line 缓存行 64字节(bytes)缓存行中的伪共享---使用缓存行对齐来解决伪共享 DCL要加volatitle 四、GC 引用计数法 、Root Searching 根可达算法 GC的常用算法 1.标记清除(Mark-Sweep) : 容易产生碎片 扫描两次 2.复制算法(copying) 空间浪费适用对象存活较少的区域 3.标记整理压缩 扫描两次需要移动对象不会产生碎片 ZGC之前至少在逻辑上都是分代回收算法 G1是逻辑分代物理不分代STW serial serialOld pspo JDK1.8默认 并行处理垃圾 CMSperNow CMS的缺点浮动垃圾内存碎片化CMS有用到标记清理 CMS分为四个阶段初始标记、并发标记、重复标记、并发清理 G1为并发处理垃圾和应用线程交替执行有别于pspo的并行执行CMS的并发标记阶段三色标记算法incremental Update G1用到三色标记算法SATB JDK1.9默认的是G1CMS和G1的清理垃圾流程 1初始标记 2并发标记 3重新标记 4并发清除五、垃圾收集器跟内存大小的关系 Serial --- 十几兆 PS ---- 几个G CMS---20G G1---上百G ZGC--- 4T六、GC调优参数配置 -Xmn10M -Xms40M -Xmx60M -XX:PrintCommandLineFlags -XX:PrintGC HelloGC PrintGCDetails PrintGCTimeStamps PrintGCCauses七、G1 分而治之、Rset、Region 三色标记会有漏标的情况 为什么G1用SATB十八、线程池 线程池分为哪两大类 Threadpool和FrokjoinPool 线程池分为哪两大类 Threadpool和FrokjoinPool Threadpoool的具体实现类总共有四个是哪些 1newCachedThreadPool 可缓存的线程池 2newFixedThreadPool 定长的线程池可控制线程的最大并发数超出则在队列中等待 3newScheduledThreadPool 支持定时及周期的线程池 4newSingleThreadExecutor 单线程化的线程池它会用唯一的线程来执行任务它可以按照指定顺序执行线成池里面的七大参数 阿里规范建议使用线程池时我们一般都是重写ThreadPoolExecutor它里面有七大参数 1corePoolSize 核心线程池大小 2maximumPoolSize 最大线程池大小 3keepAliveTime 线程最大空闲时间 4unit 时间单位 5workQueue 线程工作队列 6threadFactory 线程创建工厂线程池中参数的线程生成工厂threadFactory可以命名线程的名称方便其他后面的排查比如知道线程池中线程的名称后面在jvm调优的时候方便快速定位到对应的具体的代码位置 7handler 拒绝策略线程池的拒绝策略 在前面提到过当工作任务队列达到最大值并且线程池的容量也达到了最大线程数时当有新的任务进来时则会触发拒绝策略在JDK中一共提供了4种拒绝策略分别如下 1、CallerRunsPolicy 该策略下在调用者线程中直接执行被拒绝任务的run方法除非线程池已经shutdown则直接抛弃任务。 2、AbortPolicy 该策略下直接丢弃任务并抛出RejectedExecutionException异常。 3、DiscardPolicy 该策略下直接丢弃任务什么都不做。 4、DiscardOldestPolicy 该策略下抛弃进入队列最早的那个任务然后尝试把这次拒绝的任务放入队列 线程工作队列分类 在jdk中一共提供了4种工作任务队列分别如下所示 1、ArrayBlockingQueue通过名字我们可以推测出当前队列是基于Array数组实现的数组的特性是初始化时需要指定数组的大小也就是指定了存储的工作任务上限ArrayBlockingQueue是一个基于数据的有界的阻塞队列新加入的任务放到队列的队尾等待被调度如果队列已经满了则会创建新线程如果线程池数量也满了则会执行拒绝策略 2、LinkedBlockingQuene通过名字我们可以推测出当前队列是基于Linked链表来实现的链表的特性是没有初始容量也就意味着这个队列是无界的最大容量可以达到Integer.MAX。也由于LinkedBlockingQuene的无界特性当有新的任务进来会一直存储在当前队列中等待调度任务来进行调度在此场景下参数maximumPoolSize是无效的LinkedBlockingQuene可能会带来资源耗尽的问题 3、SynchronousQuene同步队列一个不缓存任务的阻塞队列生产者放入一个任务必须等到消费者取出任务直接被调度任务调度执行当前任务如果没有空闲的可用线程则直接创建新的线程进行处理当线程池数量达到maximumPoolSize时则触发拒绝策略 4、PriorityBlockingQueue优先考虑无界阻塞队列优先级可以通过Comparator来实现 ThreadLocal弱引用使用不当会导致内存泄漏 ThreadLocal 线程的局部变量 内存泄露 ectry数组 key是只向对应的ThreadLocal所以是弱引用value是类似Map的具体对象值所以强引用JVM垃圾回收的时候弱引用会被直接回收value是强引用就会有内存泄漏的情况 ThreadLocal其实有在Spring声明式事务中使用保证多线程环境下的安全问题。线程池的使用场景 首先线程的使用率提升后线程的创建和销毁都会浪费服务器的使用资源。 ① 任务数多但资源占用不大。比如电商环境下的发送短信的或消息推送通知对于该场景下所需要处理的消息对象内容比较简单占用资源少但是再高并发环境下面可能会瞬间产生大量的任务数并且里面每个任务的处理速率都比较高因此重点在于控制并发的线程数不要因为大量的线程使用以及线程的上下文频繁切换导致内存和CPU的使用率过高系统宕机的情况。通常都是设置大点的队列数最大线程数设置为CPU的2-4倍即可。 ② 任务数不多但资源占用量大。比如批量数的处理、日志收集、文件流等。像这种场景如果使用单线程就会导致资源的损耗过大。因此就可以适当的加大最大线程数减少任务列队的长度来节省不必要的开销。十九、HashMap 1.haspMap在1.7中是数组链表的组合1.8中变为数组链表红黑树数组里面每个地方都存的是key-value的实例在jdk7中叫Entryjdk8中叫Node 2.hashMap初始容量为16为2的整数次方扩容的负载因子为0.75每次扩容后的长度都是原来长度的2倍为位运算效率最高。扩容resize分为两步①.扩容先创建一个新的Entry空数组长度是原数组的2倍②.Rehash遍历原来的Entry数组把所有的Entry重新hash到新的数组中。注意点因为hash值的计算公式和数组的长度有关所以每次扩容之后hash都会重新计算。 3.当产生hash冲突的时候就会生成链表jdk7时插入链表的方式为头插法jdk后修改为尾插法是为了防止死循环因为修改为尾插法后原先链表里面的元素顺序是没有变化的新增的元素只要在尾部新增插入即可。 4.链表的长度大于8时链表就会转换为红黑树红黑树相比链表链表的查找方式为从头到尾或从尾到头的一个个查找时间复杂度为O(n)。红黑树其实是对二叉树和AVL(平衡树)的一种优化为二分化查找其时间复杂度为O(logn)器查询效率要优于链表的O(n),从而可以降低IO提高查询效率。注意点:那为什么不使用二叉树、平衡树而是选择使用红黑树①在理想情况下二叉树的时间复杂度为O(logn)最坏的情况下为O(n),导致最坏的情况是因为二叉树中所有的数据都集中在左子树或者右子数一侧。②.AVL平衡树是更加严格的平衡从根节点到叶子节点的最短路径和最长路径之差最多为1而红黑树中最多为2倍。因此AVL平衡树更适合查询密集型任务但AVL平衡树为了保持平衡通常需要经过多次复杂的旋转红黑树最多需要2次旋转就可以达到平衡红黑树插入和修改的效率要比AVL平衡树更高。③.为什么链表长度大于8时就会转换为红黑树呢---因为根据统计学中的泊松分布。 5.那HashMap是如何保证线程安全呢面对线程安全的使用场景我们一般都会想到HashTable和CurrentHashMap或者通过Collections.synchronizedMap得到一个线程安全的MapHashTable都是通过get和push直接加synchronized锁的方式效率不高synchronizedMap里面是维护一个map对象通过排他锁是锁对象当有线程操作Map进行上锁ConcurrentHashMap在进行put操作的还是比较复杂的大致可以分为以下步骤①根据 key 计算出 hashcode 。②判断是否需要进行初始化。③即为当前 key 定位出的 Node如果为空表示当前位置可以写入数据利用 CAS 尝试写入失败则自旋保证成功。④如果当前位置的 hashcode MOVED -1,则需要进行扩容。⑤如果都不满足则利用 synchronized 锁写入数据。⑥如果数量大于 TREEIFY_THRESHOLD 则要转换为红黑树6.Arraylist底层为数组Object[] elementData初始长度为10扩容后15的长度;HashSet的底层实现逻辑其实就是HashMap。7.一致性hash算法传统hash算法和节点个数有关hash(object)%N。如果节点数增加和减少就会导致hash映射的公式产生变化hash(object)%N1和hash(object)%N-1导致之前所有的缓存失效产生雪崩。优点加入和删除节点只是会影响顺时针方向的节点如果最初有3台后面又增加一台则只会影响0-33%的数据准确性防止雪崩。所以扩容时只会影响哀悼少部分chan节点。缺点数据的分布和节点位置有关数据并不会均匀分布再节点上所以新增节点并不会缓解所有节点的压力。针对数据分布不均匀的问题一致性hash算法有做升级引入虚拟节点均匀分布在哈希环上从而尽可能的让数据更加均匀。 十八、ETCD对比redis 十九、文档数据库mongoDB(待完成) 二十、 Spark与hadoop Fink 1.Hadoop有两个核心模块分布式存储模块HDFS和分布式计算模块Mapreduce 2.spark本身并没有提供分布式文件系统因此spark的分析大多依赖于Hadoop的分布式文件系统HDFS 3.Hadoop的Mapreduce与spark都可以进行数据计算而相比于Mapreducespark的速度更快并且提供的功能更加丰富二十一、进程和线程 ​ 进程是操作系统分配资源的单位线程是调度执行的基本单位线程之间共享进程资源 二十二、分布式事务 1.2PC也叫二阶段提交是一种强一致性设计2PC引入了一个事务协调者的角色来协调管理各个事务的参与者的提交和回滚二阶段提交分为准备和提交两个阶段准备阶段是协调者给各参与者发送准备命令注意提交阶段不一定是提交事务也有可能是回滚事务。2PC为同步阻塞协议像第一阶段协调者会等待所有参与者响应后才会进行下一步操作当然如果因为网络原因导致一直收不到参与者的响应所以第一阶段会有一个超时机制如果超时事务就会回滚操作。第二阶段因为没有超时机制所以当协调者和参与者出现单点故障后事务资源处于锁定状态很可能会导致资源锁定阻塞还会锁定一些公共资源导致其他系统操作阻塞。2PC是一种尽量保持强一致性的分布式事务因此它是同步阻塞的同步阻塞会导致资源锁定的问题总体来说效率低下并且单点故障下会存在数据不一致的风险。2.3PC为三阶段提交它的出现是为了解决2PC的一些问题相比2PC它在参与者中引入了超时机制新增了一个阶段来统一各个参与者的状态3PC分为准备阶段、预提交阶段、提交阶段。准备阶段只是询问各个参与者是否已经准备好了和2PC的准备阶段不同2PC的准备阶段是除了事务的提交其他搞作的都做了。3PC相比2PC引入了参与者的超时机制并且增加了一个预提交阶段使得故障恢复后协调者的决策复杂度降低但整体交互时间更长了性能还有所下降极端情况下也会有数据不一致的情况。并且3PC只是纯理论上的东西好像市面上也没有具体的实现。3.2PC和3PC都是数据库DB层面的而TCC则是业务层面的分布式事务。TCC分为三个操作try--confrim--cancel。TCC对业务的入侵性比较大和业务高度耦合需要根据特定的场景和业务来设计所以TCC的开发量也更大代码上也更不好写。4.RocketMq的事务消息 Haif Message,是指暂不能被Consumer消费的消息。Producer已经把消息成功发送到Broker端但此消息暂不能投递状态处于此种状态就被称为半消息需要Producer对消息进行第二次确认后Consumer才能去消费它。消息回查由于网络抖动生产者重启导致Producer端一直没有对Haif Message消息进行第二次确认这时Broker的服务器中的定时器扫描那些长期处于半消息状态的消息主动去问询Producer端然后再根据Producer端的回查结果确定是commit或rollback,该过程称为消息回查。5.RabbitMq本地消息表,保存一条状态为未发送的消息到本地事务表中并保证和当前业务的原子性然后再定义一个定时器来扫描本地事务表将状态为未发送的消息推送到MQ。消息发送成功执行confirm回调修改表状态为已发送。 然后消息者手动ack进行相应来保证消息的一致性不丢失。二十三、代码层面优化总结 1.各种工具的选择zuul/gateway,redisson/letty,tomcat8.5以上mysql8.0以上 二十四、各种锁 AQS、 synchronized 、CAS、 ReentrantLock 公平锁和非公平锁 Volatile关键字 吞吐量为程序执行时间的总量 二十五、运维面试点 谷歌三剑客grepsedawk 杀进程的命令kill -9 kill -15 CentOS6和CentOS7的区别 1.部分命令不一样查看IP 命令CentOS6为ip aCentOS7为 ifconfig 2.CentOS6里面有vimCentOS7里面需要自己安装包 3.最主要的区别是内核不一样CentOS6的内核版本为2.xx版本如果集成docker就比较麻烦。 liunx里面修改文件权限的命令chmod、chgrp、chown 1.chmod一般用于改变文件或目录的访问权限。用户用它来控制文件或目录的权限 ​ 比如chmod -R 777 /opt/activepivot/dataset/env1 2.chgrp改变文件或目录的所属组。 3.chown更改文件或目录的属主和属组。例如root用户把自己的一个文件拷贝给用户yusi为了让用户yusi能够存取这个文件所以root应该把这个文件的属主设为yusi否则用户yusi无法存取这个文件。 在liunx中根据关键字grep到进程号并kill掉进程 ps -ef|grep %s|grep -v grep|awk ‘{print $2}’|xargs kill -9 使用command启动service su - trvcradm -c “cd /opt/activepivot/dataset/uat/datasetmanager;./startup.sh” 在liunx中更新.sh文件为unix格式(比如在window修改sh文件后copy到liunx则需要设置格式) ​ set ffunix
http://www.w-s-a.com/news/275324/

相关文章:

  • 新闻播报最新网站优化外包费用
  • wordpress分页出现404最专业的seo公司
  • 连云港网站建设电话连云港市建设局网站
  • 平面设计网站有哪些比较好drupal网站建设 北京
  • 健康资讯网站模板网页价格表
  • 2008发布asp网站宝安建网站的公司
  • 郑州市城市建设管理局网站制作公司网站 优帮云
  • 网站开发 瀑布结构普陀网站建设
  • 12380网站建设情况汇报plone vs wordpress
  • c 网站开发数据库连接与wordpress类似的都有哪些
  • 状元村建设官方网站长春做网站seo的
  • 做金融资讯网站需要哪些牌照海珠营销型网站制作
  • 学做网站需要买什么书手机网络
  • 寻找做电影网站团队合作西宁网站建设君博首选
  • 兴仁县城乡建设局网站爱站关键词查询
  • 漳州网站建设公司推荐wordpress更改主机
  • c2c商城网站建设方案英文网站注册
  • 电子商务网站的运营一般需要做哪些准备宣传片拍摄思路
  • 网站建设网页制作百度怎么做自己网站
  • 建设设计网站公司巴州建设局网站
  • 淘宝建设网站的好处韶关市网站建设招标
  • 佛山高端网站免费招聘网站建设
  • 申请网站就是做网站吗wordpress tag 优化
  • 建站系统排行榜菏泽机关建设网站
  • 网站群建设费用科技通信网站模板下载
  • 网站开发的流程是怎样的自己做自媒体在哪个网站比较好
  • 网站的html代码在哪网页线上开发制作
  • 免费商用自媒体图片网站做网站好的公司有哪些
  • 阿雷网站建设公司中国建筑考试网官网首页
  • 厦门网站制作网页无法跳转到建设银行网站