小迈科技可能的面试问题

目录

 1.JVM调优

2.mysql调优

三:创建线程的方式

四:线程间通信的几种方式

五:索引的作用

六:创建索引的原则

七:SpringIOC SpringAop加载流程

八:Redis类型

九:ArrayList、Vector、LinedList的对比.

十:servlet的生命周期


1.JVM调优

2.mysql调优

首先,我们必须对explain有一定的了解

(1)如何定位并优化慢查询SQL?
一般有3个思考方向
1.根据慢日志定位慢查询sql
2.使用explain等工具分析sql执行计划
3.修改sql或者尽量让sql走索引

(2)打开查询日志 
此处我们要注意的就是设置慢查询阈值

set global long_query_time=1;
只要你的SQL实际执行时间超过了这个阈值,就会被记录到慢查询日志里面。

这个阈值默认是10s,线上业务一般建议把long_query_time设置为1s,如果某个业务的MySQL要求比较高的QPS,可设置慢查询为0.1s。
 

(3)索化表结构,让查询走索引

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引,避免无索引行锁升级为表锁


2.最左前缀法则

如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。

1 EXPLAIN SELECT * FROM employees WHERE name = 'Bill' and age = 31;
2 EXPLAIN SELECT * FROM employees WHERE age = 30 AND position = 'dev';
3 EXPLAIN SELECT * FROM employees WHERE position = 'manager';


3.不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描 

因为你操作后得到得字符,到索引B+树里面去找,是找不到得!

 4.存储引擎不能使用索引中范围条件右边的列

例如这个图,查找name=Bill,age>29 and position=“dev”  中这个dev不会走索引,因为age已经根据大小排好了,那么下一列得position肯定是无序得,只能全表扫描

5.尽量使用覆盖索引(只访问索引的查询(索引列包含查询列)),减少 select * 语句

6.mysql在使用不等于(!=或者<>),not in ,not exists 的时候无法使用索引会导致全表扫描 < 小于、 > 大于、 = 这些,mysql内部优化器会根据检索比例、表大小等多个因素整体评估是否使用索引

7.is null,is not null 一般情况下也无法使用索引

8.like以通配符开头('$abc...')mysql索引失效会变成全表扫描操作

一般通配符在前面走不了索引,在后面可以

问题:解决like'%字符串%'索引不被使用的方法?

a)使用覆盖索引,查询字段必须是建立覆盖索引字段

1 EXPLAIN SELECT name,age,position FROM employees WHERE name like '%Lei%';、

b)如果不能使用覆盖索引则可能需要借助搜索引擎

9.字符串不加单引号索引失效

10.少用or或in,用它查询时,mysql不一定使用索引,mysql内部优化器会根据检索比例、表大小等多个因素整体评 估是否使用索引,详见范围查询优化
 

三:创建线程的方式

  • 继承Thread
  • 实现runnable
  • 实现callable
  • 使用Executors关键字

四:线程间通信的几种方式

(1)使用voliatle关键字或者synchronized关键字

使用voliatle可以使多个线程同时监听一个变量,当一个变量发生改变时,他对应的共享内存的值也会相应发生改变

synchronized关键字保证被修饰的方法或者代码块保证只能被一个线程获取

(2)使用wait和notify/notifyAll

wait()/notify()/notifyAll() 必须配合 synchronized 使用,wait 方法释放锁,notify 方法不释放锁。wait 是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify()notify并不释放锁,只是告诉调用过wait()的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放,调用 wait() 的一个或多个线程才会解除 wait 状态,重新参与竞争对象锁,程序如果可以再次得到锁,就可以继续向下运行。

 (3)CountDownLatch

CountDownLatch 基于AQS框架,相当于也是维护了一个线程间共享变量 state。

(4)使用ReentrantLock结合 Condition

(5)基本 LockSupport 实现线程间的阻塞和唤醒
        

五:索引的作用

  1. 创建唯一索引,可以保证数据库中每一行数据的唯一性
  2. 可以加速表和表之间的连接
  3. 根据索引查询可以快速定位到我们想要查询到的数据,加快数据的检索速度
  4. 在使用分组和排序 子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 

六:创建索引的原则

  1. 主键自动创建索引
  2. 经常需要查询的条件创建索引
  3. 经常用在连接的键上,尤其是外键,创建索引
  4. 经常需要范围查找的列创建索引
  5. 经常需要使用where字句的列上创建索引

七:SpringIOC SpringAop加载流程

八:Redis类型

String

List

set

scort set

hash

九:ArrayList、Vector、LinedList的对比.

ArrayList, LinkedList 不是线程安全的,而 Vector 是线程安全的。

ArrayList 和 Vector 都是使用 Object的数组形式来存储的,LinkedList 使用双向链表实现存储

十:servlet的生命周期

Servlet的生命周期
servlet的生命周期顾名思义就是从servlet出现到消亡(销毁)的全过程。

主要分为以下几个阶段:
加载类—>实例化(为对象分配空间)—>初始化(为对象的属性赋值)—>请求响应(服务阶段)—>销毁

servlet生命周期三个方法:

  • init()初始化阶段
  • service()处理客户端请求阶段
  • destroy()终止阶段
  • ​ 容器(tomcat等)装载servlet

实例化阶段
1.1 当客户端首次发送第一次请求后,由Servlet容器去解析请求,根据请求找到是否有对应的servlet。
1.2 判断是否有Servlet实现类的对象存在?存在则直接使用,不存在则先创建一个servlet实现类的对象。

初始化阶段
Servlet 初始化是其生命周期的第一个阶段,也是其他阶段的基础。只有完成了初始化,Servlet 才能处理来自客户端的请求。

Servlet 初始化阶段分为 2 步:

加载和实例化 Servlet;
调用 init() 方法进行初始化
1.加载和实例化
Servlet 容器负责加载和实例化 Servlet。

当容器启动或首次请求某个 Servlet 时,容器会读取 web.xml (配置load-on-startup=1,默认为0)或 @WebServlet 中的配置信息,对指定的 Servlet 进行加载。加载成功后,容器会通过反射对 Servlet 进行实例化。

2.调用 init() 方法进行初始化
加载和实例化完成后,Servlet 容器会创建一个servlet对象并调用servlet的init方法(在servlet生命周期内只能调用一次init方法)去初始化 Servlet 实例。

请求响应阶段
初始化完成后调取service()方法,由service()判断客户端的请求方式。
3.1 如果是get请求,则执行doGet()方法。
3.2 如果是post请求,则执行doPost()。
3.3 处理方法完成后会作出相应的结果返回给客户端,单次请求处理完毕。

当用户发送第二次以后的请求时,会判断对象是否存在,但是不再执行init(),而直接执行service方法调取doGet() / doPost()方法。
 

服务终止阶段
当服务器关闭,重启或移除 Servlet 实例时Servlet调取destroy()方法进行销毁,宣告生命周期的结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值