Java中的集合框架用过哪些?
java中的集合分为单列集合和双列集合,单列集合顶级接口为Collection,双列集合顶级接口为Map。
Collection的子接口有两个:List和Set。
List接口的特点:元素可重复,有序(存取顺序)。
list接口的实现类:
ArrayList:底层实现是数组,查询快,增删慢,线程不安全,效率高;
LinkedList:底层实现是链表,增删快,查询慢,线程不安全,效率高;
Set接口的特点:元素唯一,不可重复,无序。
Set接口实现类:
HashSet:底层实现hashMap,数组+链表实现,不允许元素重复,无序。
TreeSet:底层实现红黑二叉树,实现元素排序
Map接口的特点:key-value键值对形式存储数据
Map接口实现类:
HashMap:底层数组+链表实现,线程不安全效率高;
TreeMap:底层红黑二叉树实现,可实现元素的排序;
LinkedHashMap:底层hashmap+linkedList 实现,通过hashmap 实现key-value 键值对存储,通过链表实现元素有序
说一下你对Spring的理解?
Spring这个框架做项目一直都在用吧,现在用的最多的是SpringBoot和SpringCloudAlibaba里那些组件。我先说一下Spring吧,Spring的核心主要的就三个点吧IOC,DI和AOP。
IOC控制反转,不用Spring框架的话如果想创建一个对象,就new一个。用了Spring以后就直接把类交给Spring来管理,让Spring给创建对象,Spring就是一个大工厂模式,底层创建对象的方式是通过配置文件+反射的方式.
DI就是依赖注入,把Spring框架创建好的对象注入到使用的地方,我们项目中都是用@AutoWired按照类型注入的方式,直接获取到这个类的对象。还有AOP,就是面向切面编程,它的原理的话,我看过它的底层代码,它实际上就是实现了动态代理机制,以前的话用这个做过事务的控制,现在的话我们都用@Transactionnal注解来控制事务,其实他底层实现还是aop那一套。
简单说一下SpringMVC与Spring是如何整合的?
j简单的说 springMVC在ssm中整合 就是 在 web.xml 里边配置springMVC的核心控制器:Dispatch-erServlet;它就是对指定后缀进行拦截;然后在springMVC.xml里边配置扫描器,可以扫描到带@control-ler注解的这些类,现在用springMVC都是基与注解式开发,像@service,@Repository @Requestmap-ping,@responsebody 啦这些注解标签 等等都是开发时用的,每个注解标签都有自己的作用;它还配置一个视图解析器,主要就是对处理之后的跳转进行统一配置,大致就是这些,如何使用springMVC获取表单里的数据?通过形参和表单里的name值保持一致就能获取到.
说一下SpringBoot吧?
SpringBoot:约定大于配置:同样通过自动配置,引入依赖后,加载默认配置文件,如果要自定义的话可以通过java类实现,
也可以在全局配置文件(application.properties,application.yml)中定义;
SpringBoot优点
- 快速创建独立运行的Spring项目以及与主流框架集成
- 使用嵌入式的Servlet容器应用无需打成WAR包 (jar)
- Starters(场景启动器)自动依赖与版本控制
- 大量的自动配置,简化开发,也可修改默认值
- 无需配置大量的XML,无代码生成,开箱即用
简单说一下sql语句是怎么优化的?
我们一般在开发的时候需要注意SQL规范,比如说最基本的不要用*查询所有字段,还要就是经常用表别名,经常commit提交事务尽量让及时释放回滚点,如果使用函数的话尽量使用内部的函数,还有一个优化的地方是项目上线后,产生大量数据后,由测试人员发现某些的功能点响应比较慢,反馈给我们开发人员,我们开发人员找到这个功能点对应的sql语句,如果这个sql语句写的比较复杂,我们就得用explain去分析一下SQL语句的执行计划,看下是不是索引失效了,或者是执行到某一个子查询的语句执行比较慢,然后我们去优化这些个sql,优化方式是什么?比如说加索引,或者创建视图.
哪些场景不适用索引?
大概分三种情况吧:
- 做查询的时候很少用到的列、某个列中包含的数据很少
- 数据类型的字段是TEXT、BLOB、BIT等数据类型的字段、
- 当在数据表中修改数据的频率大于查询数据频率时等,这些场景不适合创建索引,还有查询字段不会做为where 条件或者 order by 字段时也不适合创建索引
什么是死锁
打个比方,假设有P1和P2两个进程,都需要A和B两个资源,现在P1持有A等待B资源,而P2持有B等待A资源,两个都等待另一个资源而不肯释放资源,就这样无限等待中,这就形成死锁,这也是死锁的一种情况。给死锁下个定义,如果一组进程中每一个进程都在等待仅由该组进程中的其他进程才能引发的事件,那么该组进程是死锁的。竞争不可抢占资源引起死锁,也就是我们说的第一种情况,而这都在等待对方占有的不可抢占的资源。
mysql内部函数多了解一下
concat,trim,replace,substring,curdate()#返回当前日期,curtime()#返回当前时间,now()#返回当前日期+时间if(value,true,false)#如果value值为真,则返回true,否则,返回false
selectif (salary > 3000, 'Hight', 'Low') from salary;
selectid, salary, if (salary <=> NULL, 'NULL', 'NOT NULL') from salary;
2、ifnull(valuel, value2)#如果valuel不为空,则返回valuel,不然返回value2,
#可以用来进行空值替换
selectifnull(salary,0.00) from salary; 等等..
如果数据库误操作,如何执行数据恢复?
看你mysql有没有开启那个binlog,然后用mysql自带的mysqlbinlog工具找到最近误操作时间节点的bin log,重放到临时数据库里,然后选择误删的数据节点,恢复一下。
主库从库数据延迟的问题有遇到过吗?
主要原因:数据库在业务上读写压力太大,CPU计算负荷大,网卡负荷大,硬盘随机I0太高。次要原因:读写binlog带来的性能影响,网络传输延迟
MySql数据库从库同步的延迟解决方案:
架构方面
- 业务的持久层采用分库架构,mysql服务能力水平扩展,分散压力
- 单个库读写分离,一主多从,主写读从,分散压力。这样从库比主库压力高,保护主库
- 服务在业务和DB之间加入memcache 和 redis 的cache层,降低读的压力
- 不同业务的mysql放在不同的物理机,降低压力
- 使用比主库更好的硬件设备,Mqsq 压力小,延迟就减少了
使用Redis缓存有没有遇到什么问题?
你是说的那个缓存雪崩和缓存穿透,,我知道缓存雪崩是因为redis中多个key同时失效后,又遇到高并发后就会造成大量的请求直接请求数据库,导致数据库服务器宕机的情况,一般这种情况我们会给redis中的key设置不同的生命周期就能解决,或者是我们给使用分布式锁来解决;还有缓存穿透的话就是大并发请求过来,查询一个连数据库都没有的数据,频繁的请求数据库导致数据库宕机,这种解决方案是我们会存到redis一个key值value为nu!,给个失效时间,也可以避免这种问题.
说一下redis集群吗?
Redis本身就支持集群操作redis_cluster,另外redis还支持主从复制,以前的老版本中有一个哨兵模式,在主服务器宕机时,从服务器可以自动转换为主服务器。我们公司搭建的redis集群是用的ruby脚本配合搭建的,我们一共搭建了6台服务器,3主3备,他们之间通信的原理是有一个乒乓协议进行通信的,他们判断一个节点的状态是用投票选举机制判断的,半数以上判断一个接口是宕机了的话,备用节点就会启动,对,我再给你说下一他们往里存储数据的机制吧,其实这个redis搭建好集群以后每个节点都存放着一个hash槽,每次往里存储数据的时候,redis都会根据存储进来的key值算出一个hash值,通过这个hash值可以判断到底应该存储到哪一个哈希槽中,取的时候也是这么取的,这就是我了解的redis集群.
MQ用过哪些?了解哪些?
我们用过的消息队列有 ActiveMQ和RabbitMQ,我还知道有个kafka大数据里用的,这三种消息队列处理速度上来说 Kafka 大于 RabbitMQ 大于 ActiveMQ,从安全上来讲:ActiveMQ 大于 RabbitMQ大于
Kafaka,我知道银行也用的RabbitMQ挺安全的 我给你说下ActiveMQ和RabbitMQ他俩的区别吧,AC-
tiveMQ他发消息的方式有两种,一种是推拉式的Queue,还有一种是发布式的(Topic),区别在于推拉式的发送,只允许有一个消费端进行消费,如果不消费的话就一直存在队列中,订阅式的是发送一个消息,可以有多个消费端,如果没有消费的话,他也不会一直保留到消息队列中,这两种我开发的时候都用过.Rabbit-MQ有一个ACK消息确认机制,用起来比较方便一些
如何避免消息堆积?
RabbitMQ中有一个workqueue机制,可以有多个消费者同时监听消费同一个队列,接收到消息以后,通过线程池,异步消费。而且这种消费模式不会出现重复消费的情况,一条消息只会被消费一次,更像是银行排队,特别多人排队的时候需要有多个窗口进行办理业务,只要有一个人在一个窗口办理完业务,其他窗口就不会再叫到这个人。
介绍一下Nginx反向代理
他就是一个反向代理服务器,其实它的优点就是内存占用少,并发访问能力强,我知道的新浪,斗鱼,好这些大公司都使用这个技术,它底层实现是c语言实现的.我们主要用到nginx两大主要的功能吧,一个是反向代理,一个是负载均衡,先说一下这个反向代理,咱们还得先说一下正向代理,其实咱们平时调试开发都是正向代理,只不过我们不说这个词.比如吧,我们访问一台tomcat,默认端口号是8080,那我们访问的时候可能就是localhost:8080,这样顺着来呢,就可以理解成一个正向代理,就这样理解哈,这个时候,如果我们想要再来一台服务器呢,我们可以配一下,把端口号改成8081,通过访问不同的端口号来访问,但是当我们项目要上线的时候,如果需要把一个项目如果部署到两台服务器上,比如淘宝,这么大,它的主界面不可能是在一台服务器上放着,就不能是访问8080或者8081这些端口了,这个时候,需要有一个代理的服务器,能够给这两台服务器做一个代理,直接不需要进行标明,就可以访问到任意一台服务器,找到这个主界面。这里呢,这个代理就可以代理这些服务器了,这个时候这个代理,我们可以理解成反向代理。反向代理严格的概念是通过代理服务器来接收网路上的请求,然后将请求转发给内部网路的服务器。而nginx可以干这个活,做这个代理,我们可以在nginx中配置端口,ip或者域名指向这些不同端口,甚至不同ip的服务器。这就是反向代理这个概念