- 给一个查询语句MySQL怎么建索引?
哈希索引无序,值不同但是哈希值相同,所以不能用哈希索引;
平衡二叉树不支持范围的查找,效率低;
B树高度低,但是不支持范围查找,具有回旋查找问题;
B+树在B树的基础上多了叶子节点之间的指针,叶子节点包含所有的值,非叶子节点只存储key,叶子节点既存key也存value,value即key的地址,
(0001和0010即是叶子节点也是非叶子结点)
索引:单值索引和联合索引(多个字段联合组成索引)
联合索引:存在失效情况
联合索引排序规则:
最佳左前缀法则:第一个有序,第二个在第一个相同的情况下有序。
如:select * from table where b=2 这种情况(a,b)联合索引就会失效。
MySQL存储引擎:InnoDB和MyISAM
InnoDB支持事务,MyISM不支持事务
InnoDB支持外键,MyISM不支持外键
InnoDB是聚集索引,MyISM是非聚集索引
InnoDB不支持全文索引(可以使用sphinx插件支持全文索引),MyISM支持全文索引
InnoDB最小的锁粒度是行锁,MyISM最小的锁粒度是表锁
InnoDB在磁盘上是两个文件:Frm文件(表的定义文件)和Ibd文件(数据和索引存储文件,数据以主键进行聚集存储,把真正的数据保存在叶子节点中)。
MyISM在磁盘上是三个文件:Frm文件(表的定义文件)、MYD(MYData)(数据文件)和MYI(MYIndex)(索引文件)。
Http是明文传输还是密文传输?HTTP(Hyper Text Transfer Protocol: 超文本传输协议) 是一种简单的请求 - 响应协议,被用于在 Web 浏览器和网站服务器之间传递消息。HTTP 使用 TCP(而不是 UDP)作为它的支撑运输层协议。其默认工作在 TCP 协议 80 端口,HTTP 客户机发起一个与服务器的 TCP 连接,一旦连接建立,浏览器和服务器进程就可以通过套接字接口访问 TCP。客户机从套接字接口发送 HTTP 请求报文和接收 HTTP 响应报文。类似地,服务器也是从套接字接口接收 HTTP 请求报文和发送 HTTP 响应报文。其通信内容以明文的方式发送,不通过任何方式的数据加密。当通信结束时,客户端与服务器关闭连接。
对称加密和非对称加密的却别?
(1)加密和解密的过程不同
对称加密过程和解密过程使用同一个秘钥,加密过程相当于用原文+秘钥可以传输出密文,同时解密过程用密文-秘钥可以推导出原文。但是非对称加密采用两个秘钥,一般使用公钥进行加密,使用私钥进行解密。
(2)加密解密速度不同
对称加密解密速度比较快,适合数据比较长时的使用。非对称加密和解密花费的时间更长、速度相对较慢,只适合对少量数据的使用。
(3)传输的安全性不同
对称加密的过程中无法保证秘钥被安全传递,密文在传输过程中是可能被第三方截获的,如果密码本也被第三方截获,则传输的密码信息将被第三方破获,安全性相对较低。
非对称加密算法中私钥是基于不同的算法生成的不同的随机数,私钥通过一定的加密算法推导出公钥,但是私钥到公钥的推到是单向的,也就是说公钥无法反推出私钥,所以安全性更高。
Https怎么加密?HTTP:默认用TCP协议的80端口(可以改),通信内容明文传输,不处理
HTTPS:(1)请求:443端口,支持算法,密钥长度
理解:两网友约定明天出去玩,玩什么呢?爬山,游泳,游乐园选一个吧
(2)响应:选择一种,将其密钥组件一起发给客户端
理解:我们去游乐园吧
(3)响应:数字证书
理解:为了证明我是个合法公民。给你看看我的身份证,身份证是XX公安局发的,身份证号是XX,10年后过期
(4)响应:协商完成
理解:OK,我同意去游乐园
(5)生成随机密码串,并使用证书公钥加密
理解:为了互相证明我们是协商的网友,每个句尾加个“喵”
(6)请求:尝试使用加密串加密
理解:我们试试,我是客户端喵
(7)响应:发送finish结束
理解:我说完了你试试
(8)响应:和客户端相同进行加密发送
理解:服务端喵
节点负载有哪些决定因素?
平均负载:平均进程数,不仅包括了正在使用的CPU的进程,还包括了等待CPU和等待I/O的进程;
CPU的使用率:单位时间内CPU繁忙情况的统计。
如果节点宕了该怎么办?- String == equals()
- Java的数据结构有哪些?
- 多线程怎么同步?
- Linux常用命令?
linux特点:免费开源、支持多线程多用户、安全性好、对内存和文件管理优越
关机命令:shutdown -h now(立即关机)、shutdown -r now(立即重启)、reboot(立即重启)
编辑器:vi。输入i,进入插入模式;输入Esc键,进入命令模式;输入冒号:wq表示退出保存;输入:q!表示退出不保存
显示当前路径:pwd
添加用户:useradd
设置密码:passwd
改变目录:cd
列出文件和目录:ls
新建目录:mkdir
删除目录:rmdir
建立空文件:touch
复制命令:cp
移动文件和改文件名:mv
删除文件和目录:rm
删除所有内容:rm -rf
显示文件内容分页:more
在特定目录下搜索并显示指定名称的文件和目录:find / -name ....
压缩解压:zip,tar -zxvf
修改权限:chmod
Http、Tcp协议?
- 亿万级数据量怎么快速查询?
- 怎么快速判断一个qq号是否被注册?
- redis分布式锁?
- Java实现同步的方式?
synchronized关键字:(monitorinter、monitorexit)(非公平锁),偏向锁--轻量级锁--重量级锁
volatile关键字:可见性(MESI总线一致性协议),有序性(load、store)
Lock:ReentrantLock(默认非公平锁),AQS抽象式队列同步器(state记录资源状态)
垃圾回收机制?
垃圾回收算法:标记清除、编辑整理、复制算法
如何判断对象可以被回收:引用计数法、可达性分析算法(GC Root)
JVM永久代(HotSpot虚拟机特有的概念):jdk1.7中方法区的一种实现,Java1.8中永久代被彻底移除,取而代之的是另一块与堆不相连的本地内存——元空间。
元空间:jdk1.8中,不在虚拟机内存中,而在本地内存。
垃圾回收机制:在Java中,程序员不需要显示的去释放对象的内存,而是由虚拟机自行执行。在Jvm中,有个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的。只有在虚拟机空闲或者当前堆内存不足时,才会触发执行,扫描那些没有被引用的对象,并将它们添加到要回收的集合中,进行回收。
JVM永久代会发生垃圾回收吗:不会发生,如果永久代满了或者超过临界值,会触发完全垃圾回收(Full GC),永久代的大小对于避免Full GC是非常重要的。
Minor GC和Full GC:新生代内存不够时发生Minor GC,JVM内存不够时发生Full GC
运行时常量池:jdk1.7之后,在堆内存,之前在方法区(永久代/元空间)。
HashMap 和ConcurrentHashMap?- Synchronized的升级过程?
- 重量级锁?
- 类加载的过程,类的生命周期?
加载过程:加载,链接(验证,准备,解析),初始化
准备:内存分配,为static变量分配内存,并设置初始值,不包含final的静态变量,因为final变量再编译时分配。
解析:将常量池中的符号引用替换为直接引用的过程,直接引用为直接指向目标的指针或者相对偏移量等。
初始化:完成静态块的执行以及静态变量的赋值,先初始化父类,再初始化当前类,只有对类主动使用时才会初始化。
对象的生命周期?
在JVM运行空间中,对象的整个生命周期大致可以分为7个阶段:创建阶段、应用阶段、不可视阶段、不可达阶段、可收集阶段、终结阶段、释放阶段。这7个阶段构成了JVM中对象的完整的生命周期。
1、创建阶段:new
2、应用阶段:对象至少被一个强引用持有
3、不可视阶段:程序的执行已经超出了该对象的作用域
4、不可达阶段:对象不在被任何强引用持有,这些对象通常是指所有线程栈中的临时变量,所有已经装载的类的静态变量或者对本地代码接口(JNI)的引用。
5、可收集阶段、终结阶段、释放阶段:对象生命周期的最后一个阶段,当对象处于三种情况:垃圾收集器发现该对象不可达,finalize方法已经被执行,对象空间已经被重用。对于这三种情况,虚拟机就可以直接将该对象回收了。
对象的创建过程?
JVM遇到一条新建对象的指令时先去检查这个指令的参数是否能在常量池定义到一个类的符号引用,然后加载这个类。
为对象分配内存,一种方法“指针碰撞”,一种方法“空闲列表”,最常用的办法“本地线程缓冲分配(TLAB)”。
将除对象头外的对象内存空间初始化为0。
对对象头进行必要设置。
程序计数器的作用?
保存着当前线程执行的字节码位置,每个线程都有私有的程序计数器,当cpu时间片切换时,从程序计数器记录的位置开始执行。
Spring Mvc的原理? 1、用户发送请求至前端控制器DispatcherServlet。
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、DispatcherServlet调用HandlerAdapter处理器适配器。
5、HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、Controller执行完成返回ModelAndView。
7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9、ViewReslover解析后返回具体的View。
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充到视图中)。
11、DispatcherServlet响应用户。
线程池的Excuter和submit的区别?
execute():用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功与否;
submit():用于提交需要返回值的任务。线程池会返回一个future类型的对象,通过这个future对象可以判断任务类型的对象,通过这个future对象可以判断任务是否执行成功,并且可以通过future的get()方法获取返回值,get()方法会阻塞当前线程知道任务完成,而使用get(long timeout, TimeUnit unit)方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完成。
线程的创建方式?- 线程池的创建方式?
ThreadPoolExecutor构造方法:自定义七大参数,避免资源耗尽的风险;
参数:CorePoolSize,MaximumPoolSize,KeepAliveTime,TimeUnit,BlockingQueue,ThreadFactory,handler。
Executors工具类:newFixedThreadPool(int)固定线程数量、newSingleThreadExecutor()单线程的线程池、 newCachedThreadPool(ThreadFactory)创建线程数不确定,肯能造成资源耗尽。
以上三种都是调用了ThreadPoolExecutor构造方法实现。
SQL题:Employee和Deployment连表查询?- 算法题:买卖股票的最佳时机?
- jdk和jre的区别?
- Collection集合类有哪些?
- String有哪些方法?
- File有哪些方法?
- List怎么遍历?
- Map怎么遍历?
- 序列化和反序列化?
- SpringBoot相比Tomcat有哪些优势?
- MySQL安装的时候默认时区是?
- Java操作MySQL的步骤?
- i++是原子操作吗?
- 怎么保证原子性?
- 同步机制?
- 可见性原理?
- HashMap的结构?
- 怎么避免哈希冲突?
- HashMap头插法有什么弊端?
- Tcp三次握手四次挥手?
- TIME-WAIT?
- MySQL索引,最左匹配原则?
- MapReduce的原理?
- Redis分布式锁实现?
- Redis数据类型?
- Redis的sortset的range操作的时间复杂度?
- 负载均衡策略?
- 亿万级数据查询最大的100条?
- 如何解决超买超卖?
- 分布式环境下如何保证用户访问某节点的一致性?
- 节点宕了怎么办(避免单点故障的方法)?
主从方式:一个Master节点,多个Slave节点,Master宕机之后,会从Slave节点中选举出新的Master节点。
主备方式:一个主节点,一个备用节点,主节点处理客户机请求时,备用节点同时从主节点同步数据,当主节点宕机时,备用节点处理客户机请求。
怎么监测某个子工作流是否成功(容错)?
心跳机制:定时向控制流发通知,若子工作流超时没有发送通知,则控制流认为该子工作流节点宕机,重新部署执行。
代理模式?
包括静态代理、动态代理、Cglib代理 1、静态代理:
需要定义接口或者父类,目标对象和代理对象一起实现相同的接口或者继承相同的父类。用户访问时需要先创建目标对象,然后将目标对象传给代理对象,通过调用代理对象的方法间接执行目标对象的方法。//接口 public Interface IUserDao{ void save(); }
//接口实现目标对象类 public UserDao implements IUserDao{ public void save(){ System.out.println("-----已保存数据-----"); } }
//代理类实现接口,静态代理 public class UserDaoProxy implements IUserDao{ private IUserDao target; //接收保存目标对象 public UserDaoProxy(IUserDao target){ this.target = target; } public void save(){ System.out.println("----开始事务----"); target.save(); //执行目标对象的方法 System.out.println("----提交事务----"); } }
/** * 测试类 */ public class App { public static void main(String[] args) { //目标对象 UserDao target = new UserDao(); //代理对象,把目标对象传给代理对象,建立代理关系 UserDaoProxy proxy = new UserDaoProxy(target); proxy.save();//执行的是代理的方法 } }
因为代理类和目标类都要实现接口,可能导致接口过多,实现类过多,难以维护。
2、动态代理
代理对象,不需要实现接口;
代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型);
动态代理也叫做:JDK代理,接口代理。/** * 创建动态代理对象 * 动态代理不需要实现接口,但是需要指定接口类型 */ public class ProxyFactory{ //维护一个目标对象 private Object target; public ProxyFactory(Object target){ this.target=target; } //给目标对象生成代理对象 public Object getProxyInstance(){ return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("开始事务2"); //执行目标对象方法 Object returnValue = method.invoke(target, args); System.out.println("提交事务2"); return returnValue; } } ); } }
/** * 测试类 */ public class App { public static void main(String[] args) { // 目标对象 IUserDao target = new UserDao(); // 【原始的类型 class cn.itcast.b_dynamic.UserDao】 System.out.println(target.getClass()); // 给目标对象,创建代理对象 IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance(); // class $Proxy0 内存中动态生成的代理对象 System.out.println(proxy.getClass()); // 执行方法 【代理对象】 proxy.save(); } }
总结:
代理对象不需要实现接口,但是目标对象一定要实现接口,否则不能用动态代理。
3、Cglib代理
上面的静态代理和动态代理模式都是要求目标对象是实现一个接口的目标对象,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候就可以使用以目标对象子类的方式类实现代理,这种方法就叫做:Cglib代理。/** * 目标对象,没有实现任何接口 */ public class UserDao { public void save() { System.out.println("----已经保存数据!----"); } }
/** * Cglib子类代理工厂 * 对UserDao在内存中动态构建一个子类对象 */ public class ProxyFactory implements MethodInterceptor{ //维护目标对象 private Object target; public ProxyFactory(Object target) { this.target = target; } //给目标对象创建一个代理对象 public Object getProxyInstance(){ //1.工具类 Enhancer en = new Enhancer(); //2.设置父类 en.setSuperclass(target.getClass()); //3.设置回调函数 en.setCallback(this); //4.创建子类(代理对象) return en.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("开始事务..."); //执行目标对象的方法 Object returnValue = method.invoke(target, args); System.out.println("提交事务..."); return returnValue; } }
/** * 测试类 */ public class App { @Test public void test(){ //目标对象 UserDao target = new UserDao(); //代理对象 UserDao proxy = (UserDao)new ProxyFactory(target).getProxyInstance(); //执行代理对象的方法 proxy.save(); } }
单例模式?
1、饿汉式:直接创建静态私有对象,构造方法私有,从类加载就创建了对象,如果从头到尾都不用,会造成资源浪费(线程安全,调用效率高,但是不能延时加载)。2、懒汉式:(线程安全,调用效率不高,但是能延时加载)public class ImageLoader{ private static ImageLoader instance = new ImageLoader; private ImageLoader(){} public static ImageLoader getInstance(){ return instance; } }
public class SingletonDemo2 { //类初始化时,不初始化这个对象(延时加载,真正用的时候再创建) private static SingletonDemo2 instance; //构造器私有化 private SingletonDemo2(){} //方法同步,调用效率低 public static synchronized SingletonDemo2 getInstance(){ if(instance==null){ instance=new SingletonDemo2(); } return instance; } }
- 数据库并发访问怎么解决?
- HashMap有什么问题?
- ArrayList扩容失败怎么办,可能会导致length错误,如何解决?
- Java锁类型有哪些?
- 给一个数组求它的top(n)个元素(堆排序)?
public static void heapSort(int[] arr) { // 构建初始大顶堆 buildMaxHeap(arr); for (int i = arr.length - 1; i > 0; i--) { // 将最大值交换到数组最后 swap(arr, 0, i); // 调整剩余数组,使其满足大顶堆 maxHeapify(arr, 0, i); } } // 构建初始大顶堆 private static void buildMaxHeap(int[] arr) { // 从最后一个非叶子结点开始调整大顶堆,最后一个非叶子结点的下标就是 arr.length / 2-1 for (int i = arr.length / 2 - 1; i >= 0; i--) { maxHeapify(arr, i, arr.length); } } // 调整大顶堆,第三个参数表示剩余未排序的数字的数量,也就是剩余堆的大小 private static void maxHeapify(int[] arr, int i, int heapSize) { // 左子结点下标 int l = 2 * i + 1; // 右子结点下标 int r = l + 1; // 记录根结点、左子树结点、右子树结点三者中的最大值下标 int largest = i; // 与左子树结点比较 if (l < heapSize && arr[l] > arr[largest]) { largest = l; } // 与右子树结点比较 if (r < heapSize && arr[r] > arr[largest]) { largest = r; } if (largest != i) { // 将最大值交换为根结点 swap(arr, i, largest); // 再次调整交换数字后的大顶堆 maxHeapify(arr, largest, heapSize); } } private static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; }
- MySQL表字段去重并取主键最小值?
- 二叉树翻转?
(LeetCode.226)public TreeNode invertTree(TreeNode root){ TreeNode x = root; t(x); return root; } public void t(TreeNode root){ if(root == null) return; TreeNode node = root.right; root.right = root.left; root.left = node; t(root.left); t(root.right); }
对象的生命周期?- 线程池的创建方式及参数?
- 哪些情况下会发生OOM?
1、Java堆(heap):Java堆内存主要用来存放运行过程中所有的对象,该区域OOM异常一般会有java.lang.OutofMemoryError:Java heap space,可以通过dump的内存快照就能分析,到底是由于程序原因导致的内存泄露,还是由于没有估计好JVM内存大小而导致的内存溢出。
2、栈溢出(stack):栈用来存储线程的局部变量、操作数栈、动态链接、方法出口等信息。如果请求栈的深度不足时跑出错误会包含类似下面的信息java.lang.StackOverflowError。
栈溢出的原因:递归里用到的局部变量存储在栈中,栈的访问效率高,速度快,但空间有限,递归太多变量需要一直入栈而不出栈,导致需要的内存空间大于栈的空间。
3、运行时常量池溢出(constant):运行时常量保存在方法区,存放的主要是编译器生成的各种字面量和符号引用,但是运行期间也可能将新的常量放入池中,比如String类的intern方法。
4、方法区溢出:方法区主要存储被虚拟机加载的类信息,如类名、访问修饰符、常量池、字段描述、方法描述等。理论上在JVM启动后该区域大小应该比较稳定,但是目前很多框架,比如Spring和Hibernate等在运行过程中都会动态生成类,因此也存在OOM风险。
自我介绍
我叫qsh,本科毕业于北方工业大学计算机科学与技术专业,研究生就读于北方工业大学大规模流数据集成与分析技术实验室,在这几年中主要做Java相关的开发和研究,在实验室主要做工作流分布式系统的项目,对于Java开发相关的知识比较熟悉,对于JVM和多线程的基本知识有一定的学习。
(自己对于岗位的匹配度,对于公司和岗位的了解,以及为什么来)
你的优势是什么?
吃苦耐劳:因为从小的生活环境,培养了这方面的精神和习惯。
钻研精神:遇到问题不会轻易放弃,直到弄懂为止。
做事希望做到完美:感觉自己有强迫症,做事有瑕疵的话总感觉缺点什么,会不断去优化。
愿意为团队牺牲:举例篮球等运动,喜欢传球。
你有没有遇到过特别困难的事,怎么处理?
项目过程中遇到的困难,以及任务紧困难多,经常感到焦虑和压力,没有办法,只能鼓励自己硬着头皮把困难解决,解决之后会非常有成就感,并且之前的负面情绪都随之消失。
你如何快速适应我们公司的工作?
及时熟悉上手相关的技术栈,对于不懂的地方请教同事,及时和同事进行交流,查开源社区等。
平时工作之余会做什么?
篮球乒乓球等运动,关注一些国际新闻,军事等,偶尔玩游戏。
还有什么要问的?
技术面:公司的Java开发岗位主要用哪些技术栈?如果可以来工作我还需要学习哪些知识?
hr面:入职后有没有岗位相关的培训?入职后公司会从哪些方面对员工进行考核?