java知识点

1. JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)

  • ​ 栈区:
  1. 每个线程包含一个栈区,栈中只保存方法中(不包括对象的成员变量)的基础数据类型和自定义对象的引用(不是对象),对象都存放在堆区中
  2. ​ 每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
  3. ​ 栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
  • ​ 堆区:
  1. ​ 存储的全部是对象实例,每个对象都包含一个与之对应的class的信息(class信息存放在方法区)。
  2. jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身,几乎所有的对象实例和数组都在堆中分配。
  • ​ 方法区:
  1. ​ 又叫静态区,跟堆一样,被所有的线程共享。它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

Stack 栈 先进后出
Queue 队列 先进先出
List 集合 有下标 存的顺序与取得的顺序一致
LinedList 类 是Queue的子类 存的顺序与取得的顺序一致

2. 面试官:您知道线程的生命周期包括哪几个阶段?

线程的生命周期包含5个阶段,包括:新建、就绪、运行、阻塞、销毁。

新建:就是刚使用new方法,new出来的线程;

就绪:就是调用的线程的start()方法后,这时候线程处于等待CPU分配资源阶段,谁先抢的CPU资源,谁开始执行;

运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run方法定义了线程的操作和功能;

阻塞:在运行状态的时候,可能因为某些原因导致运行状态的线程变成了阻塞状态,比如sleep()、wait()之后线程就处于了阻塞状态,这个时候需要其他机制将处于阻塞状态的线程唤醒,比如调用notify或者notifyAll()方法。唤醒的线程不会立刻执行run方法,它们要再次等待CPU分配资源进入运行状态;

销毁:如果线程正常执行完毕后或线程被提前强制性的终止或出现异常导致结束,那么线程就要被销毁,释放资源;

3. OSI 的七层模型都有哪些?

应用层:网络服务与最终用户的一个接口。
表示层:数据的表示、安全、压缩。
会话层:建立、管理、终止会话。
传输层:定义传输数据的协议端口号,以及流控和差错校验。
网络层:进行逻辑地址寻址,实现不同网络之间的路径选择。
数据链路层:建立逻辑连接、进行硬件地址寻址、差错校验等功能。
物理层:建立、维护、断开物理连接。

4. get 和 post 请求有哪些区别?

GET在浏览器回退时是无害的,而POST会再次提交请求。
GET产生的URL地址可以被Bookmark,而POST不可以。
GET请求会被浏览器主动cache,而POST不会,除非手动设置。
GET请求只能进行url编码,而POST支持多种编码方式。
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
GET请求在URL中传送的参数是有长度限制的,而POST么有。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
GET参数通过URL传递,POST放在Request body中。

5. 常见的异常类有哪些?

NullPointerException:当应用程序试图访问空对象时,则抛出该异常。
SQLException:提供关于数据库访问错误或其他错误信息的异常。
IndexOutOfBoundsException:指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。
NumberFormatException:当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
FileNotFoundException:当试图打开指定路径名表示的文件失败时,抛出此异常。
IOException:当发生某种I/O异常时,抛出此异常。此类是失败或中断的I/O操作生成的异常的通用类。
ClassCastException:当试图将对象强制转换为不是实例的子类时,抛出该异常。
ArrayStoreException:试图将错误类型的对象存储到一个对象数组时抛出的异常。
IllegalArgumentException:抛出的异常表明向方法传递了一个不合法或不正确的参数。
ArithmeticException:当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。
NegativeArraySizeException:如果应用程序试图创建大小为负的数组,则抛出该异常。
NoSuchMethodException:无法找到某一特定方法时,抛出该异常。
SecurityException:由安全管理器抛出的异常,指示存在安全侵犯。
UnsupportedOperationException:当不支持请求的操作时,抛出该异常。
RuntimeExceptionRuntimeException:是那些可能在Java虚拟机正常运行期间抛出的异常的超类

6. Redis有哪些数据结构?

字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。

7. BIO、NIO、AIO 有什么区别?

BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非阻塞 IO ,异步 IO 的操作基于事件和回调机制。

8. java重写和重载的区别?继承和接口的区别?

重载:同一个类中不同方法具有相同的名字,但是参数不一样,即参数的名称和参数的类型不一样。同类不同参

重写:子父类的,即子类与父类具有相同的方法名字还有参数参数相同和相同的返回类型。即同名同参同类型

子类不能重写父类中的final方法,必须重写父类的abstract(抽象)方法。

继承和接口的区别:
区别1:
不同的修饰符修饰(interface),(extends)
区别2:
在面向对象编程中可以有多继承!但是只支持接口的多继承,不支持'继承'的多继承哦
而继承在java中具有单根性,子类只能继承一个父类
区别3:
在接口中只能定义全局常量,和抽象方法
而在继承中可以定义属性方法,变量,常量等...
区别4:
某个接口被类实现时,在类中一定要实现接口中的抽象方法
而继承想调用那个方法就调用那个方法,毫无压力

接口是:对功能的描述 继承是:什么是一种什么

始终记者:你可以有多个干爹(接口),但只能有一个亲爹( 继承)

9. 简单描述mysql中,索引,主键,唯一索引, 联合索引的区明, 对数概库的性能有什么影响

索引是一种特殊的文件(InnoDB 数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。

普通索引 (由关键字 KEY 或 INDEX 定义的索引) 的唯一任务是加快对数据的访问速度。

普通索引允许被索引的数据列包含重复的值。如果能确定某个数据列将只包含彼 此各不相同的值,在为这个数据列创建索引的时候就应该用关键字 UNIQUE 把它 定义为一个唯一索引。

也就是说,唯一索引可以保证数据记录的唯一性。

主键,是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯 一标识一条记录,使用关键字 PRIMARY KEY 来创建。

索引可以覆盖多个数据列,如像 INDEX(columnA, columnB)索引,这就是联合索引

索引可以极大的提高数据的查询速度,但是会降低插入、删除、更新表的速度, 因为在执行这些写操作时,还要操作索引文件。

10. 外连接分为内连接、左连接、右连接

#内连接
select * from t_fn_person a   join t_fn_dept b on a.dept_id=b.dept_id;
#左连接
select * from  t_fn_person a   left join t_fn_dept b  on a.dept_id=b.dept_id;
#右连接
select * from  t_fn_person a   right join t_fn_dept b  on a.dept_id=b.dept_id;

11. 举例说明造成ConcurrentModificationException异常情况

当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。

public static void main(String[] args) {
    ArrayList<String> list=new ArrayList<String>();
    list.add("111");
    list.add("222");
    list.add("333");

    for(Iterator<String> iterator=list.iterator();iterator.hasNext();){
        String ele=iterator.next();
        if(ele.equals("111")) //(1)处
            list.remove("222"); //(2)处
    }
    System.out.println(list);

    /*
    public static void main(String[] args)  {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(2);
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            Integer integer = iterator.next();
            if(integer==2)
                list.remove(integer);
        }
    }*/
}

//分析代码:这个一个在使用Iterator迭代器遍历时,同时用使用remove()方法进行了删除的操作。
//当运行上述代码时,程序抛出了ConcurrentModificationException异常。

遍历一个集合时如何避免ConcurrentModificationException
API文档上也有说的! 在迭代时只可以用迭代器进行删除!

单线程情况:

(1)使用Iterator提供的remove方法,用于删除当前元素。

(2)建立一个集合,记录需要删除的元素,之后统一删除。

(3)不使用Iterator进行遍历,需要之一的是自己保证索引正常。

(4)使用并发集合类来避免ConcurrentModificationException,比如使用CopyOnArrayList,而不是ArrayList。

多线程情况:

(1)使用并发集合类,如使用ConcurrentHashMap或者CopyOnWriteArrayList。

12. hibernate是什么?及其工作基本原理(流程) (可以简单 描述)

Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,它将 pojo 与数据库表建立映射关系,是一个全自动的 ORM框架,Hibernate 可以自动生成 SQL 语句,自动执行,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。

1.通过Configuration config = new Configuration().configure();//读取并解析hibernate.cfg.xml配置文件
2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息
3.通过SessionFactory sf = config.buildSessionFactory();//创建SessionFactory
4.Session session = sf.openSession();//打开Sesssion
5.Transaction tx = session.beginTransaction();//创建并启动事务Transation
6.persistent operate操作数据,持久化操作
7.tx.commit();//提交事务
8.关闭Session
9.关闭SesstionFactory

13. 数据库中的事务是什么?

百度百科中解释:指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
简单的说,事务就是并发控制的单位,是用户定义的一个操作序列。
而一个逻辑工作单元要成为事务,就必须满足ACID属性。
A:原子性(Atomicity)
事务中的操作要么都不做,要么就全做。
C:一致性(Consistency)
事务执行的结果必须是从数据库从一个一致性状态转换到另一个一致性状态。
I:隔离性(Isolation)
一个事务的执行不能被其他事务干扰
D:持久性(Durability)
一个事务一旦提交,它对数据库中数据的改变就应该是永久性的

14. 查询一张表某个字段重复记录数大于1的sql语句(可以简单写出 sql语句)

select name from A group by name having count(name)>1

15. Struts2中的type类型有哪些?至少写4种

dispatcher:result type默认的类型,相当于servlet的foward方式跳转页面。客户端看到的是struts2中配置的地址,而不是真正页面的地址,一般用于跳转到jsp页面,页面能拿到值
redirect:页面重定向,客户端跳转,数据全部丢失,地址栏发生变化,页面不能拿到值
chain:将请求转发给一个Action,Action能通过getAttribute(“uname”)拿到值
redirect-action:一般用于跳转到Action,Action不能通过getAttribute(“uname”)拿到值

16. AJAX是什么?描述ajax的原理

  • Ajax = 异步 JavaScript 和XML。

  • Ajax是一种用于创建快速***页的技术。

  • 通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

  • 传统的网页(不使用 Ajax)如果需要更新内容,必需重载整个网页面。

Ajax的工作原理相当于在用户和服务器之间加了—个中间层(AJAX引擎),使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器。像—些数据验证和数据处理等都交给Ajax引擎自己来做,,只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。

image-20200619180423284

17. 在struts2中如何实现转发和重定向

<action name="Login" class="com.xxx">
<result name="success" type="dispatcher">index.jsp</result>
</action>

如果结果类型没声明,默认是 dispatcher (请求转发)

比较重要的几个类型:

  • dispatcher —— 请求转发到一个页面 (默认),不可以用这种方式转发到一个action
  • chain —— 一个action请求转发至另一个 action
  • redirect —— 响应重定向到一个页面
  • redirectAction —— 一个action响应重定向至另一个 action
  • stream —— 文件下载

18. ActionContext、ServletContext、 pageContext 的区别?

  1. ActionContext是当前的Action的上下文环境,通过ActionContext可以获取到request、session、ServletContext等与Action有关的对象的引用;

  2. ServletContext是域对象,一个web应用中只有一个ServletContext,生命周期伴随整个web应用;

  3. pageContext是JSP中的最重要的一个内置对象,可以通过pageContext获取其他域对象的应用,同时它是一个域对象,作用范围只针对当前页面,当前页面结束时,pageContext销毁, 生命周期是JSP四个域对象中最小的。

19. @Required @Autowired @Controler @RequestMapping注解作用分别是

@Required 注解作用于Beansetter方法上,用于检查一个Bean的属性的值在配置期间是否被赋予或设置

@Autowired 是一个注释,它可以对类成员变量、方法及构造函数进行标注,让 spring 完成 bean 自动装配的工作。

@RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。

@Controler 控制器类

20. 什么是Spring beans? 支持的几种bean的作用域

Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中 的形式定义。

Spring 框架定义的beans都是单件beans。在bean tag中有个属性”singleton”,如果它被赋为TRUE,bean 就是单件,否则就是一个 prototype bean。默认是TRUE,所以所有在Spring框架中的beans 缺省都是单件。

Spring容器中的bean可以分为5个范围:
(1)singleton:默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。

(2)prototype:为每一个bean请求提供一个实例。

(3)request:为每一个网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。

(4)session:与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。

(5)global-session:全局作用域,global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。全局作用域与Servlet中的session作用域效果相同。

21. 用自己的话简要描述Struts2的执行流程

(1)客户端提交一个HttpServletRequest请求

(2)请求被提交到一系列的过滤器(Filter),FilterDispatcher是控制器的核心,就是MVC的Struts 2实现中控制层(Controller)的核心。

(3)FilterDispatcher询问ActionMapper是否需要调用某个Action来处理这个(HttpServlet Request)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher则把请求的处理交给ActionProxy。

(4) ActionProxy通过Configuration Manager(struts.xml)询问框架的配置文件,找到需要调用的Action类

(5)ActionProxy创建一个ActionInvocation实例,同时ActionInvocation通过代理模式调用Action。但在调用之前,ActionInvocation会根据配置加载Action相关的所有Interceptor(拦截器)。

(6)Action执行完毕后,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果result

第一步:HttpServletRequest进入到StrutsPrepareAndExecuteFilter(图上ActionContextCleanUp这个类在集成SiteMesh才有用的其余时候可以不管)

第二步:StrutsPrepareAndExecuteFilter调用dispatcher类的serviceAction创建ActionProxy

第三步:通过ActionProxy对象调用Actioninvocation的invoke方法执行所有的拦截器

第四步:执行HttpServletRequest对应的Action方法并返回Result

22. 什么是Spring的依赖注入?实现方式

Spring 能有效地组织J2EE应用各层的对象。不管是控制层的Action对象,还是业务层的Service对象,还是持久层的DAO对象,都可在Spring的 管理下有机地协调、运行。Spring将各层的对象以松耦合的方式组织在一起,Action对象无须关心Service对象的具体实现,Service对 象无须关心持久层对象的具体实现,各层对象的调用完全面向接口。当系统需要重构时,代码的改写量将大大减少。

依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者 实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。在运行期间,有外部容器动态地将依赖对象注入到组件中(构造方法和set方法)
好处:

  • 接口注入
  • set注入
  • 构造注入

23. 说说AOP和I0C的概念以及在spring中是如何应用的

IOC就是一个生产和管理bean的容器就行了,原来需要在调用类中new的东西,现在都是通过容器生成,同时,要是产生的是单例的bean,他还可以给管理bean的生命周期。

控制反转:将控制实体bean的动作交给spring容器进行管理。

AOP面向切面编程--将程序中的交叉业务逻辑(比如安全,日志,事务),封装成一个切面,然后注入到目标业务逻辑中去。

spring有三种注入方式:

1)根据属性注入也叫set方法注入

2)根据构造方法注入

3)根据注解进行注入(推荐)

Spring的AOP和IOC都是为了解决系统代码耦合度过高的问题,使代码重用度高,易于维护。

24. 给你一组字符串如: iu7i8hy4jnb2;让你编程输出里面的数字

//1.
   String   s   =   "iu7i8hy4jnb2";
   String newStr = s.replaceAll("[a-zA-Z]", "");
   System.out.println(newStr);


//2.
        String s = "abc1fff9aaa8rr4";
        StringWriter w = new StringWriter();
        for (char c : s.toCharArray()) {
            if (Character.isDigit(c)) { //如果要输出字母 则条件改为Character.isAlphabetic(c)
                w.write(c);
            }
        }
        System.out.println(w.toString());

25.项目里redis的作用

  1. 手机验证码存入redis中,可以限制什么时候有效
  2. 防止接口请求频率过高,例如一分钟只能请求5次
  3. 做缓存用,公司抓取股票基金的数据,存入redis进行缓存使用
  4. 进行队列,应对并发请求
  5. 消息订阅推送

26.进程和线程的主要区别

根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位

在开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。

所处环境:在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)

内存分配方面:系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源。

包含关系:没有线程的进程可以看做是单线程的,如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。