一.JAVA基础
1.面向对象的特征有哪几个方面
1)封装:将变量和方法包装起来,可以用private或abstract修饰类,然后提供对外公共操作的方法;
2)继承:从现有的类中派生出一个新的类,这个过程称为类继承,新类可以获得原始类的公开方法和实例变量;
3)多态:尽量屏蔽不同类的差异性,提供通用的解决方案,可分为:
向上造型:将子类对象统一看做父类型,可直接调用子类重写后的方法,但不能调用子类或父类的私有方法及属性;
向下造型:将父类型的子类对象重新转化为子类型,可调用子类独有的方法及属性;
2.抽象类和接口的异同点:
相同点:
1)都不能直接创建对象;
2)都可以有抽象方法;
区别:
1)抽象类中可以有普通方法或完全没有抽象方法,而接口在JDK1.8以前只有抽象方法,在JDK1.8之后可以有默认方法;
2)抽象类只能单继承,接口可以多实现;
3)抽象类中可以有各种类型成员变量或局部变量,而接口只有常量;
4)接口不含静态代码块和静态方法,而抽象类可以有;
5)抽象类含有构造方法,而接口没有构造方法;
6)抽象类是后天重构的结果,接口是先天设计的结果;
3.常见的数据结构
1)栈Stack:
仅允许在一端进行插入和删除操作,所以对元素的存取只能先进后出(钻死胡同)
压栈:就是存元素;
弹栈:就是取元素;
2.)队列queue:
仅允许在一端进行插入,在另一端进行删除,即先进先出(排队打饭)
3)数组Array:
有序的元素序列,在内存中开辟一段连续的空间,每段空间都有自己编号:当数据量大于五十万,增删位置靠近中段情况下查找快,增删慢;
4)链表LinkedList:
动态生成节点,无序,节点里存储数据和下一个节点及上一个节点的地址值:数据量大于五十万,增删位置靠近头尾的情况下查找慢,增删快;
5)红黑树:
本身是一颗二叉树,每个节点不超过2的有序树结构,每个节点上只能有2个子节点,树的键值是有序的,查找子元素最少和最多次数不多于二倍;
红黑树的特点:
①节点可以是红色或是黑色的
②根节点和叶子节点(空节点)是黑色的
③每个红色节点的子节点都是黑色的
④任何一个节点到其每一个叶子节点的所有路径上的黑色节点数量相同
4.基本类型及其包装类型:
1)byte:Byte:1字节:-128~127
2)short:Short:2字节:-2^15~2^15-1
3)int:Integer:4字节:-2^31~2^31-1
4)long:Long:8字节:-2^63~2^63-1
5)double:Doubel:8字节:双精度,小数后八位
6)float:Float:4字节:单精度,小数后四位
7)char:Character:2字节:0~65535
8)boolean:Boolean:1字节:true/false
5.HashMap:
1)数据结构:
现在用的JDK1.8中,HashMap底层是由"数组加链表加红黑树"组成
①整体是一个数组
②数组每个位置是一个链表或红黑树
③链表中的每个value就是我们存储的Object
④默认情况下是链表,当同一个索引位置的节点在新增后达到9个,若数组长度大于等于64,链表节点就会转换为红黑树,否则进行扩容(红黑树节点大小为链表的2倍,在节点太少时,红黑树的查找性能优势不明显,不值得付出两倍的空间代价);
⑤移除节点数据时,若同一索引位置的节点在移除后达到6个,并且该节点为红黑树,则该节点数据类型重新转化为链表(如果设置节点多于8个转红黑树,少于8个转链表,当节点数在8个徘徊时,就会频繁进行红黑树和链表的转换,造成性能的损耗)
2)工作原理:
hashMap的无参构造中,容器默认的数组大小为16,加载因子为0.75,扩容阈值即16*0.75=12,当数组中元素的数量达到阈值时,自动将数组扩容为原来的两倍,并将原来数组中的元素重新放入新数组中,容器在第一次插入数据时,才会进行初始化,避免空间浪费;
hashMap的有参构造中,会根据传入的容量计算出一个大于等于该容量的最小2的N次方:如,输入9,得到的容量为16;
6.HashMap和HashTable 的区别
1)hashTable默认容量11,对底层数组容量无要求,hashMap默认容量16,要求底层数组容量为2的N次方;
2)hashTable的key和value都不允许为null,而hashMap可以;
3)hashTable扩容时,将容量变为原来的2倍+1,hashMap将容量变为原来的2倍;
7.set和list的区别
1)list可以允许有重复的元素,set不允许
2)list可以插入多个null值,set只能有一个
3)list是一个有序容器,输出顺序就是插入顺序,set接口是无序的,treeSet是有序的
4)list的实现类为ArrayList/LinkedList/Vector,set的实现类为HashSet/LinkedHashSet/TreeSet;
8.String和StringBuilder的区别
1)string创建后长度不可变,每次拼接字符都会产生新的对象,stringBuilder长度可变,创建后,默认长度为16,拼接后,长度不够就扩容;
2)string的值如果是" "或字符串常量拼接的,则存储在常量池,new方式创建的,保存在堆中,stringBuilder的值都保存在堆中;
3)string对字符串的操作方法多,但拼接字符串效率低下,stringBuilder正好相反;
StringBuffer和StringBuilder的区别:stringBuffer线程安全,通过多线程操作字符串,任何对它指向的字符串的操作,都不会产生新的对象,速度相对stringBuilder较慢。
9.线程的几种状态
线程的生命周期有五个阶段:
1)新建状态:线程创建后的状态,new对象;
2)就绪状态:调用线程对象的start()方法后,线程所处的状态;
3)运行状态:就绪状态的线程被CPU调度后,线程开始执行时所处的状态;
4)阻塞状态:运行中的线程由于某种原因,暂时放弃对CPU的使用,如wait(),sleep()方法等,进入阻塞状态的线程重新进入就绪状态后,才会重新被CPU调用;
5)死亡状态:线程执行完任务或因异常退出run()方法后,就会结束生命周期,如stop()方法强行终止线程;
10.线程池的优点:
线程池:是一个容纳了多个线程的容器,其中的线程可以反复使用,无需反复创建线程而消耗过多资源;
1)降低资源消耗:减少了创建和销毁线程的此数,可执行多个任务;
2)提高响应速度:任务到达时,无需等待线程创建;
3)提高线程的可管理性:可以根据系统的承受能力,调整线程池中工作线程的数目,防止损耗过多内存;
11.创建线程的三种方式:
1)继承Thread类:
①继承Thread类并重写run()方法;
②创建子类的实例对象
③通过对象调用start()方法;
2)实现Runnable接口:
①实现Runnable接口,并重写run()方法;
②创建实现类的实例对象
③将该对象作为构造参数传入Thread类的实例对象中;
④通过Thread类的实例对象调用start()方法;
3)实现Callable接口:
①实现Callable接口,并重写call()方法;(call()方法有返回值,并可以抛出异常)
②创建实现类的实例对象;
③将实现类对象作为构造参数传入FutureTask类的实例对象中;(Callable接口与Runnable无关,Future接口被用来代表Callable接口中call()方法的返回值,而FutureTask类同时实现了Future接口与Runnable接口,所以Callable类型的对象可以通过FutureTask类传入到Thread的构造方法中)
④将FutureTask对象作为构造参数传入Thread的实例对象中;
⑤通过Thread对象调用start()方法启动线程;
⑥通过FutureTask对象调用get()方法获得线程执行结束后的返回值;
12.sleep和wait方法的区别:
1)sleep方法来自Thread类,wait方法来自Object类;
2)sleep方法没有释放锁,而wait方法释放了锁,使其他线程可以使用同步方法;
3)wait,notify只能在同步控制方法或同步控制块里面使用,而sleep方法可以在任何地方使用;
4)sleep方法在线程休眠时间到达后恢复线程执行,wait方法会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法,才会重新激活线程;
13:线程和进程的区别:
1)进程:运行中的程序;
2)线程:系统运行的最小单位;
14.Java内存的分配:
1)程序计数器:占用内存小,是当前线程所执行的行号指示器;
2)Java虚拟机栈:用于存放方法执行期间的局部变量表,方法出口等;
3)本地方法栈:用于为虚拟机使用到的本地方法服务;
4)Java堆:用于存放实例对象,被所有线程共享,可分为新生代和老年代;
5)方法区:用于存储类信息,常量,静态变量等;
15.static,final关键词的用处:
static:
1)static方法:静态方法可以直接通过类名调用,不需要先创建对象,静态方法中不能访问非静态方法和非静态成员变量;
2)static变量:静态变量被所有对象共享,在内存中只有一个;
3)static代码块:在类初次加载的时候执行一次,适合执行一些只需要进行一次的初始化操作,初始化的顺序:静态代码块 > 构造代码块 > 构造函数;
4)static内部类:创建静态内部类的对象时,无需创建外部类的对象,但不能通过内部类对象访问外部类的非静态成员变量及方法;
final:
1)final类:最终类,不可被继承;
2)final方法:最终方法,不能被重写,与abstract关键词冲突;
3)final变量:常量,不可重新赋值,值不可变;
16.final和finally的区别:
final用于修饰变量、方法及类;finally是异常处理机制的最后补充,可以保证其中的代码在虚拟机停止运行时仍会执行其中的操作;
17.方法的重写和重载:
重写:子类继承父类后,将父类方法重新塑造,需遵守两同两小一大原则,(子类无法重写父类的私有方法);
两同:方法名和参数列表相同;
两小:子类方法返回值类型和抛出异常类型小于等于父类方法;
一大:子类方法权限修饰符大于等于父类方法;
重载:同一个类中方法名相同而参数列表不同的方法构成重载;
18.什么是串行,并行,并发,分布式:
1)串行:多个任务依次在单个线程上执行;
2)并行:多个任务同时在多个线程上执行;
3)并发:多个线程在多个线程上轮流穿插执行;
4)分布式:在并行的基础上,分开正在执行任务的CPU;
19.hashCode和equals之间的关系:
在java的一些集合类的实现中,比较对象是否相等时,会先调用hashCode方法,hashCode值相等时,再调用equals方法来确定两个对象是否相等;
20.hash冲突:
hashCode可以将任意对象转化为固定长度的hash码值,无限的对象转化为长度有限的数值必然会有重复,所以,hash值不等的对象一定不等,hash值相等的对象也不一定相等;
21.常见设计模式:
1)单例模式:是一种对象创建型模式,确保某一个类只有一个实例,而且自行实例化,并向整个系统提供这个实例;
创建方式:私有化构造方法--->类里创建静态私有成员变量---->提供开放静态方法,判断成员变量值为空,就new一个对象进行赋值(懒汉式);
优点:
①可以严格控制客户可以怎样或何时访问他;
②节约系统资源,提高系统性能;
③可通过扩展使用与单例控制相似的方法来获得指定个数的实例对象;
缺点:
①单例模式没有抽象层,类扩展困难;
②职责过重,既充当工厂角色,又包含产品方法;
③实例化的共享对象长久不被使用,会被系统自动回收,下次使用还需要重新创建,导致共享对象状态丢失;
2)工厂模式:
①简单工厂:创建一个工厂类,可以根据参数的不同返回不同的实例对象,创建方法为静态方法;
②工厂模式:定义一个用于创建对象的接口,由子类来决定将哪一个类实例化;
③抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,无需指定他们具体的类;
二.数据库基础:
1.数据库常见操作:
1)对库的操作:
①查库名:show databases;
②建库:create database 库名;
③删库:drop database 库名;
④使用数据库:use 库名;
2)对表的操作:
①查表名:show tables;
②建表:create table 表名(字段名 字段类型(字段长度),字段名 字段类型(字段长度),字段名 字段类型(字段长度));
③改表:alter table 表名 add column 字段名 字段类型(字段长度);
④展示表:desc 表名;
⑤删表:drop table 表名;
3)对记录的操作:
①查询:select 查询目标 from 表名;
②新增:insert into 表名 values(字段值1,字段值2,字段值3......);
③修改:update 表名 set 字段名='字段值';
④删除:delete from 表名;
2.事务的四大特性:
1)原子性:事务里面的内容是不可分割的,要么一起成功,要么一起失败;
2)一致性:执行事务时,将事务与数据库保持一致;
3)持久性:指一个事务一旦提交后对数据库的改变是永久不变的;
4)隔离性:一个事务的执行不会被其他事务所干扰;
3.事务的隔离级别:
1)读未提交:事务可以读取其他事务未提交前的数据,容易产生脏读,读取到错误数据;
2)读已提交:事务只能读取其他事物提交后的数据,容易出现不可重复读,无法隔离其他事务提交的已修改数据;
3)可重复读:给事务操作的行数加锁,解决了不可重复读问题,但可能会产生幻读,无法隔离其他事务对表的增删操作;
4)串行化:给表加锁,解决了幻读问题,且不会产生其他问题,不会有多事务并发执行安全问题;
4.数据库优化的方案有哪些:
1)精确查询范围,尽量别用*;
2)每个表的索引控制在五个以内;
3)能用连接查询就别用子查询;
4)连接查询以小表驱动大表为原则;
5)尽量避免使用order by;
6)where子句后面的条件执行顺序是从右到左,所以尽量把能过滤大部分数据的条件放在最后;
7)查看慢查询日志,找出时间长的SQL进行优化;
5.索引:
1)什么是索引:在数据库中对某字段添加索引后,会对该列的字段值进行排序形成目录(以B+Tree的形式),从而提高查询效率;
2)索引适用的场景:
①当表中数据量大时,适用索引可以提高查询效率,数据量小时,创建索引消耗的时间反而比顺序查找更多;
②可以将经常作为查询条件的字段添加索引;
③会被频繁修改的字段值的字段不适合添加索引,每次增删改都会重建索引,反而降低效率;
④一个表中的索引最好不超过五个;
⑤字段的字段值重复性低;
3)索引的sql操作:
①查询:show index from 表名;
②创建:create index 索引名 on 表名(字段名);
③删除:drop index 索引名 on 表名;
4)索引失效的场景:
①查询范围过大,会导致引擎优先进行全表扫描而非使用索引;
②在where子句中对字段进行null值判断,使用!=,使用or作为连接条件,使用not in等词组;
③符合索引未用左列字段;
④like以%开头;
⑤where中索引列有运算;
⑥where中索引列使用了函数;
⑦数据少时,mysql会更倾向全表扫描;
6.什么是Spring IOC:
把一个类放入到spring容器中,对象的创建、初始化、销毁等工作交给spring容器来做,由spring容器来控制对象的生命周期;
7.Spring AOP:
AOP是面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,提高开发效率,常用于日志记录,性能统计,安全控制,事务处理,异常处理;
8.Spring MVC的处理流程:
1)客户端服务器向前端控制器发送request请求;
2)前端控制器请求处理映射器查找Handler并返回一个执行链;
3)前端控制器更具执行链请求处理器适配器执行Handler并返回ModelAndView;
4)前端控制器请求视图解析器解析并返回试图;
5)前端控制器将视图渲染并填充到request域中;
6)前端控制器返回Response响应客户端请求;
9.Mybatis的工作原理:
Mybatis实质上是封装了JDBC,简化了JDBC的操作;
1) mybatis应用程序通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件中构建出SqlSessionFactory;
2)SqlSessionFactory的实例直接开启一个SqlSession;
3)再通过SqlSession实例获得Mapper对象;
4)执行Mapper映射的SQL语句,完成对数据库的增删改查和事务提交
5)关闭SqlSession
10.Mybatis应用中#与$有什么区别:
#能够有效防止sql的注入攻击,会将传入的数值当成一个字符串,自动拼接字符串;
$会将传入的值直接显示在sql中,会有发生sql攻击的风险,且相对低效,不会拼接字符串;
11.jsp与servlet的区别与联系:
区别:
1)jsp是servlet的一种简化,经编译后就变成了servlet;
2)jsp更擅长表现页面显示,servlet擅长逻辑控制;
3)servlet没有内置对象,jsp中的内置对象都是要通过HttpServletRequest,HttpServletResponse和HttpServlet对象得到的;
联系:jsp是servlet技术的扩展,本质上就是servlet的一种简易方式;
12.视图和表的区别:
1)视图是编译好的sql语句,而表不是;
2)视图没有实际的物理记录,而表有;
3)视图是窗口,表是内容;
4)表占用物理空间,可以及时对表的数据进行修改,而视图只是逻辑概念的存在,只能通过创建语句进行修改;
5)视图是查看表数据的一种方法,只是一些sql语句的集合,可以不给用户接触数据表,避免表结构泄露;
6)表是全局模式的实表,视图是局部模式的虚表;
7)视图的建立和删除只影响视图本身;
8)不能对视图进行update或insert into操作;
13.innodb存储基本单位页结构:
innodb将数据划分为若干个页,页的默认大小为16kb,每次最少读取16kb的内容到内存中,一个页可以存储多个行记录;
14.mybatis的一二级缓存作用:
1)一级缓存自动开启,作用范围为session,当session提交或关闭后,缓存就会被清空;
2)二级缓存需手动开启,作用于sqlSessionFactory,映射语句中的所有select语句都会被缓存,所有增删改查操作都会刷新缓存,缓存会存储1024个对象,容易产生脏读数据;
文章评论