• 面试题


    spring模块

    一,什么是依赖注入,什么是控制反转(IOC),在spring中有几种依赖注入的方式

    控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。

    把由程序代码操控的对象的调用权交给容器,通过容器实现对象组件的装配和管理。所谓的"控制反转"就是对组件对象控制权的转移,从程序代码本身转移到了外部容器,由容器来创建对象并管理对象之间的依赖关系。

    其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)

    依赖注入(DI)是spring核心,依赖注入早期叫反向控制,因为spring将类主动的加载依赖的对象的任务交给了容器负责,而类只需要使用这些类就行,

    类也无需关心依赖对象的具体实现,实现了松耦合,方便进行模块测试。

    注入方式:

    构造函数注入。

    set注入。

    接口注入。

    二,Spring中有几种配置bean的方式

    基于XML的配置

    基于注解的配置

    基于java的配置

    三。spring中一个bean的生命周期。

    创建一个bean,首先需要实例化,然后设置属性值,设置bean的name,然后统通过一系列的初始化操作,bean就可以提供使用,当容器关闭时进行析构操作销毁bean。

    这是beanFactory中简单bean的装配过程,若这个bean在spring的引用上下文中,则会在初始化的过程中,再调用一下setApplicationContext方法。

    四,spring bean的作用。

    spring中bean的作用域默认为单例的,singleton 。

    prototype,与singleton相反,prototype是多例的,他为每一个bean请求单独创建一个实例,

    但是既然是单例的怎么保证线程安全呢,spring是使用单实例,多线程的方式,不同请求同时访问时,调用的是同一个实例,但是具体方法在不同线程中执行,就是说

    方法中的局部变量是线程安全的,类中的全局变量就需要进行线程安全的处理

    五,spring自动装配的几种方式

    1.no,spring 的默认装配方式,在该方式下,spring的自动装配功能是关闭的。

    2.byName:spring会自动寻找beanId与实例对象名称相同的的配置bean并自动注入,若没有则报错。

    3,.byType:spring会自动寻找与实例对象类型相同的配置bean并自动注入,若没有则报错

    4.constructor :构造器的自动装配和 byType 模式类似,但是仅仅适用于与有构造器相同参数的 bean ,如果在容器中没有找到与构造器参数类型一致的 bean ,那么将会抛出异常 。

    5.autodetect:spring会自动测试构造器自动装配或者 byType 类型的自动装配

    六,说说BeanFactory和applicationContext的区别

    beanfactory是底层的实例化接口,他只能提供简单的注入的功能,applicationContext则更多的提供了企业级的服务

    两者的区别:其中BeanFactory是延迟加载,也就是说知道代码中调用了getBean,bean才会被spring装配,

    而applicationContext则在项目启动时,就会装载所有的bean。当然,applicationContext它还可以为 Bean 配置 lazy-init=true 来让 Bean 延迟实例化。

    延迟实例化的优缺点

    优点:启动时占用资源较少,对于占用资源相对较多的应用比较有优势。

    缺点:速度会相对来说慢一些 。 而且有可能会出现空指针异常的错误,并且在项目启动时就加载bean方便更早的查找出bean的配置问题。

    web应用推荐启动时就把所有的bean都给加载了。

    七.spring 管理事务的方式

    编程式事务

    声明式事务

    其中声明式事务又被分为两类。

    基于xml的声明式事务

    基于注解的声明式事务

    八,spring中的代理方式有哪些

    1,若被代理对象是一个借口,则使用jdk中的java.long.reflect.proxy代理,生成实现它的实现类。

    优点。因为使用接口,所以使系统更加松耦合

    缺点。需要为每一个代理目标编写借口

    2.若代理对象是一个java类,则使用 CGLIB 库生成目标对象的子类 。

    优点。不需要接口的存在

    缺点。松散耦合度没有使用接口的好

    九,IOC容器的初始化过程

    1.rescourse定位。

    2.载入

    3.注册

    十,AOP的实现原理:动态代理,区别参考第八条

     十一,spring框架的事务管理的优点,支持声明式事务。

    总结:

    Spring框架优点:

    方便解耦,简化开发:

    Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理(代码没有入侵性)

    1.AOP编程的支持:

    Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能(便于功能扩展)

    2.声明式事务的支持:

    只需要通过配置就可以完成对事务的管理,而无需手动编程

    3.方便程序的测试:

    Spring对Junit4支持,可以通过注解方便的测试Spring程序

    方便集成各种优秀框架:

    数据库模块

    基本的增删改查sql语句

    select * from table where 

    update table set colum1=1,colum2=2...where...

    insert into table(colum1.2.3...)value(1.2.3..)

    delete from table where..

    CREATE TABLE `NewTable` (
    `id` int NOT NULL AUTO_INCREMENT ,
    `name` varchar(255) NULL ,
    PRIMARY KEY (`id`)
    )

    一,什么是存储过程,他的优缺点是什么

    存储过程是预编译的sql语句,优点是允许模块化的设计,就是说只需要创建一次,就可以在程序中可以使用存储过程名多次调用,如果程序中多次执行sql语句,存储过程比单纯执行sql语句效率高

    好处:因为是预编译的sql语句,所以执行效率高

       存储语句是直接放在数据库中,所以减少了网络通讯。

       使用需要权限,所以安全性高

       一次创建多次调用,减少了开发者的工作量

    缺点:移植性差

    二,为什么使用自增列作为主键。

    首先主键必须确保非空和唯一性。这两点自增列都能满足。

    并且当一页数据填满后,会自动开启新的一页

    第二,若使用类似身份证或者学号这种编号,生成记录是可以说是随机的,就是说有可能会插入数据到现有索引列的中间的某个位置,这样mysql会为了将数据插入到合适位置,不得不移动数据,

    这样增加了许多的开销

    三,什么叫视图

    视图是一种虚拟的表,他和物理表有一样的功能,都可以进行增删改查,视图通常包含一个或多个表中行或列的子集,对视图的修改会影响基本表,方便我们查询和修改数据库

    四,drop,delete,truncate的区别

    drop:直接删除整表,

    delete:仅删除表中的数据

    truncare:删除表中数据,并让自增列从1开始

    五,关系型数据库和非关系型数据库的区别

    非关系型数据库,通常采用键值对的形式存储数据,因此执行效率更快

    因为数据之间没有耦合,所以方便水平扩展,扩展性高。

    关系型数据库:安全新高,可以使用复杂的sql语句做复杂的数据查询

    六,什么是内连接,左外连接,右外连接,笛卡尔积等

    内连接:只查询匹配的行即可

    SELECT a.,b. FROM luntan as a, usertable as b ON a.username=b.username

    左外连接:包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表的匹配行
    SELECT a.,b. FROM luntan as a LEFT JOIN usertable as b ON a.username=b.username

    右外连接:包含右边表的全部行(不管左边的表中是否存在与它们匹配的行),以及左边表的匹配行

    SELECT a.,b. FROM luntan as a RIGHTJOIN usertable as b ON a.username=b.username

    全外连接:包含左右两表的全部行,不管另外一边的表中是否存在与它们匹配的行。

    SELECT a.,b. FROM city as a FULL OUTER JOIN user as b ON a.username=b.username

    交叉连接: 生成笛卡尔积(笛卡尔积,左边表中的每一行记录,匹配右边表的所有记录,当多表联查未做外键关联时,会自动做笛卡尔积)

    SELECT type,pub_name FROM titles CROSS JOIN publishers ORDER BY type

    七,什么是临时表

    当查询语句设计多个表时,都会生成一张中间临时表,再把这个临时表反馈给用户,临时表只在当前连接可见,当数据库连接关闭时,mysql会自动删除并释放所有临时表空间

    八,on和where的区别

    举个栗子,在left join中

    on:on是在生成临时表时使用的条件,不管on后面的条件是否为真,都会将左边的记录返回

    where:where是在临时表生成之后进行筛选的条件。

    java基础

    一,基础变量和引用变量

    基础变量:int char long double short float byte boolean

    引用类型是用类的编译器定义的,他用于访问对象

    二,Switch是否可以用String做参数

    因为String是引用数据类型

    在JDK1.7之前Switch只支持int,byte,short,chat这几个基本数据类型

    在1.7之后允许使用整形,枚举,字符串都可以

    三,equals和==的区别

    ==用于比较内存地址是否相同,equals用户比较内存中的值是否相同

    基础数据类型创建时会在常量池中寻找是否存在,若不存在则创建并返回引用,所以基础数据类型用==比较,而引用数据类型,类似String会在每次创建时生成新的引用对象,内存地址都不同,所以用equals比较值是否相同

    四,自动装箱和常量池

    常量池用于存放常量

    byte,short,char,float,int,double,long,boolean八大基础数据类型生成的变量都是常量

    首先会在常量池中寻找是否存在,若存在则返回引用,若不存在则创建并返回引用

    int a = 1;创建普通变量

    Integer b = a;自动装箱

    int c = b;自动拆箱

    Integer b = 100;自动装箱

    自动装箱是将一个java定义的基本数据类型赋值给相应封装类的变量。 拆箱与装箱是相反的操作,自动拆箱则是将一个封装类的变量赋值给相应基本数据类型的变量。

    五,java中多线程实现的方式,以及使用

    两种常见的实现方式,继承Thread类或者实现Runable接口

    继承Thread本质上就是一个实现了Runable接口的一个实例:

    重写run方法,并通过start执行run方法

    public class MyTthread extends Thread(){

      public void run(){

        system.out.printl("线程执行");

      }

    }

    MyThread thread1 = new MyThread();

    MyThread thread2 = new MyThread();

    thread1.start();

    thread2.start();

    实现Runable接口

    public class MyThread extends OtherClass implements Runable(){

      public void run(){

        system,out.printl("线程执行");

      }

    }

    MyThread myThread= new MyThread();

    Thread thread = new Thread(myThread);  

    thread.start();  

    在多线程中,不推荐使用循环创建线程然后start调用,因为创建和销毁线程非常的消耗资源,一般使用线程池

    https://www.cnblogs.com/wxd0108/p/5479442.html

    synchronized的使用

    synchronized通过锁,来保证一段代码或代码块只有一个线程在执行,是高并发实现的基础

    java中每一个对象都可以作为锁,

    不用static修饰的方法的锁叫普通同步锁,锁属于创建的对象

    用static修饰的锁叫静态方法锁,静态方法属于类,所以锁属于类

    六,java的四种引用类型,以及适用场景

    从高到低分别为强引用,弱引用,软引用,虚引用

    强引用:java中最常用的引用类型,直接使用=连接的引用, 只要强引用存在垃圾回收机制就不会销毁引用。

    弱引用:可以说是一种有用但是不是必须的引用对象,若内存够,则不会回收,若内存不会,则被回收,一般用于实现内存敏感的高速缓存

    软引用:软引用是只要被垃圾回收检测到,不管内存是否够,都会被回收。

    虚引用:虚引用和其他引用不同,不存在生命周期,虚引用就和没有引用一样,任何时候都有可能被回收,虚引用一般用来跟踪被垃圾回收器回收的活动。

    七,HashCode的理解

    hash,通常翻译成散列,是将任意长度的输出通过散列算法转化成固定长度输出,这个输出就是hashcode,hashcode相同,就会被放到同一个散列中。

    hashCode通常的作用是保证查找的快捷性,经常用于确定对象的存储地址

    在list和set中,list元素有序,并且可重复,但是set元素是无序并且不可重复的。

    若每次添加元素,都要调用equals判断是否相等,当元素一多,效率就变得非常慢。

    所以先调用hashcode若这个hashcode不相等,则直接添加,若相同,则说明两元素在同一个散列中,再调用equals判断是否相等。

    因此hashcode一般用于定位,equals用于判断是否相等,若hashcode重写,equals也最好重写。

    通常情况下是不需要重写hashcode方法的,当数据需要放在hashmap,hashtable中时,可能会根据业务需要重写hashcode和equals方法

    八,list的三个子类

    list的三个子类,ArrayList,LInkedList,Vector

    ArrayList:底层数据结构是数组,查询快,增删慢

    线程是不安全的,效率高

    LinkedList:底层数据结构是链表,查询慢,增删快。

    线程是不安全的,效率高

    Vector:底层数据结构是数组,查询慢,增删快

    线程是安全的,效率低

    Vector相比ArrayList查询更慢

    Vector相比LinkedList增删更慢

    ArrayList和LinkedList的区别:

    ArrayList查询更快,LInkedList增删更快

    ArrayList底层数据结构是数组,LinkedList底层数据结构是链表

    共同点:都是线程安全的

    ArrayList和Voctor的区别

    ArrayList是线程不安全的,Voctor是线程安全的

    ArrayList的效率比Voctor的效率更高

    共同点:底层的数据结构都是数组

    九,String,StringBuilder,StringBuffer三者的区别,

    三者之中,String的效率最低,原因是String的不可变性,每次修改值都需要创建新的引用,因此String适合少量操作的时候。

    StringBuilder适合单线程情况下需要大量数据操作的时候,因为他是线程不安全的

    StringBuffer适合多线程情况下需要大量数据操作的时候,因为他是线程安全的

    StringBuffer中的很多方法都带有synchronized关键字,而StringBuilder则没有

     十,inertface和abstract的区别

    inertface中只能有成员常量和方法的声明,abstract class可以拥有成员变量并且可以声明普通方法和抽象方法。

    inertface是接口,所有的声明默认前缀都是public static final 接口不能实例化自己

    abstract是抽象类,至少包含一个抽象方法的类叫抽象类,抽象类不能被自身实例化,并且需要被abstract修饰

    一个类遵循单继承,多实现。

    十一,描述Cookie和Session的作用,区别和各自的应用范围,Session工作原理

    Cookie是在客户端开辟的一块可长期存储用户信息的地方;Session是在服务器内存中开辟的一块存储用户信息的地方;

    当客户第一次访问服务器时,服务器在内存创建对应的Session给访问客户,当客户离开或时间过期时;服务器自动销毁Session; Session是由容器管理的

    十二,override和overload的区别

    override:重写,子类重写的方法必须 和父类的返回值,参数,方法名一样

    不能缩小父类方法的访问权限

    不能抛出比父类更多的异常

    若父类的方法被定义为了final,则不可以被重写

    overload:重载

    在同一个类中,方面名必须一致

    参数的类型,个数,顺序至少一个不同

    不能重载只有返回值不同的方法

    十三,java中xml的解析方式

    DOM,SAX这两种是系统自带的,还有JDOM和DOM4J需要导入jar包

    DOM通过层次结构(树)解析xml,将整个xml解析后以树的形式放在内存中。效率较低

    SAX,是使用流模型,每发现一个节点,效率较高

    十四,面向过程和面向对象的区别

    面向过程的性能由于面向对象,因为类再调用时需要实例化,消耗资源,因此如果性能是第一考量时,会选择面向过程开发,但是面向过程没有面向对象的易复用,易扩展,易维护的有点

    面向对象开发因为有封装,继承,多态的特性,可以开发出低耦合的系统。

    * 但是这个并不是根本原因,面向过程也需要分配内存,计算内存偏移量,Java性能较低的原因java是半编译语言,最后的执行代码并不是并不是cpu可以直接执行的二进制机械码。

    而面向过程语言大多直接编译成机器码在电脑上运行。

    https://blog.csdn.net/as6757uyy65uy75/article/details/79370686

  • 相关阅读:
    mogodb学习
    rman list incarnation
    Java创建对象的四种方式
    JAVA 8 函数式接口--Consumer
    Linux中VIM的使用
    JRE 和 JDK 的区别
    tengine-2.3.1 增加ngx_http_upstream_check_module 模块
    k8s的coredns 增加外部dns解析记录
    Dockerfile的CMD总结
    redis数据转移随笔
  • 原文地址:https://www.cnblogs.com/jinsheng1027/p/11615503.html
Copyright © 2020-2023  润新知