总结(2)

一、http----->后台返回数据的流程

1、浏览器发送http请求

1)http与tcp、socket的关系

http即超文本传送协议,是应用层协议,定义的是传输数据的内容的规范,主要解决如何包装数据。http的特点是客户端每次发送的请求都需要服务器端回送响应,在每次请求结束后,会主动释放连接,从建立连接到关闭连接的过程称为“一次连接”。http连接是“短连接”,需要不断向服务器发起连接请求,即使不需要获得任何数据,客户端也保持一段固定的时间向服务器发送一次“保持连接”的请求。

tcp即传输控制协议,对应于传输层,主要解决数据如何在网络中传输。tcp协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络上。建立一个tcp需要经过“三次握手”(请求、响应、连接)。tcp连接一旦建立,在通信双方中的任何一方主动关闭连接之前,tcp连接都就将被一直保持下去。

socket即套接字,是对tcp/ip协议的封装和应用。socket是在应用层和传输层之间的一个抽象层。socket本身不是一个协议,是一个调用接口,通过socket才能使用tcp/ip。tcp是单纯的建立连接,不涉及任何需要请求的实际数据,简单的传输。http是用来收发数据,即实际应用上的。http要基于tcp连接的基础。

(2)web socket例子

2、tomcat服务器

3、tomcat根据配置文件找到对应的web.xml

4、tomcat将请求交给web项目

5、监听器

6、过滤器

7、servlet

8、controller(控制器)

(1)@Controller:类级别上的注解,标注一个类是Spring controller对象。

(2)@RequestMapping:可以是类级别上的(不是必须的),也可以是方法上的。如果出现在类上,则请求的url为:类上的@RequestMapping+方法上的@RequestMapping,否则直接取方法上的@RequestMapping。在方法级别上使用@RequestMapping,可以指定两个参数:method和param。

(3)@Controller的实现过程

spring mvc配置文件中定义controller的bean对象(例:<bean class="com.controller"/>)或在spring mvc配置文件中告诉spring应该去哪里找controller(例:<context:component-scan base-package= "com.controller" >)----->分发处理器扫描使用了@Controller注解的类----->检测是否使用了@RequestMapping注解

9、service(业务逻辑)

(1)@Service:用于标注业务层组件

(2)@Service的实现过程

spring mvc配置文件中定义<context:component-scan base-package="com.service"/> ----->将带了@Service注解的类自动注册到spring容器。

10、dao(数据处理)

(1)@Repository:用于标注数据访问组件。

(2)@Repository的实现过程

spring mvc配置文件中定义<context:component-scan base-package="com.dao"/> ----->将带了@Repository注解的类自动注册到spring容器。

(3)使用jdbc

加载jdbc驱动----->与数据库建立连接----->创建Statement或PrepareStatement对象----->执行sql语句,返回结果----->处理返回结果----->释放资源

(4)使用mybatis

配置mybatis----->实体类与mybatis配置文件映射----->执行sql语句,返回结果----->处理结果

二、请描述Java HashMap与ConcurrentHashMap的区别,它们是如何工作的;

1、HashMap与ConcurrentHashMap的区别

(1)ConcurrentHashMap在每一个分段上都用lock锁进行保护,并发性能好,是线程安全的(ConcurrentHashMap使用了分段锁技术来保证线程安全)。HashMap没有锁机制,不是线程安全的。

(2)HashMap的键值对允许有null,ConCurrentHashMap不允许键值对为null。

(3)分段锁技术:首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。

2、HashMap工作原理

HashMap是基于hashing的原理,使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。给put()方法传递键和值时,先对键调用hashCode()方法,返回的hashCode用于找到bucket(桶)位置来储存Entry对象。

3、ConcurrentHashMap工作原理

一个ConcurrentHashMap由多个segment组成,每一个segment都包含了一个HashEntry数组的hashtable, 每一个segment包含了对自己的hashtable的操作,比如get,put,replace等操作,这些操作发生的时候,对自己的hashtable进行锁定。由于每一个segment写操作只锁定自己的hashtable,所以可能存在多个线程同时写的情况,性能好于只有一个hashtable锁定的情况。

三、请描述Java ClassLoader的机制,并以使用广泛的JDBC为例说明JVM是如何通过ClassLoader机制加载第三方数据库驱动;

1、ClassLoader机制

ClassLoader是JVM实现的一部分,ClassLoader包括bootstrap ClassLoader(启动类加载器),ClassLoader在JVM运行时加载Java革新的API,以满足Java程序最基本的需求,其中就包括用户定义(通过Java程序实现的来年改革ClassLoader)的ClassLoader:一个是ExtClassLoader,它的作用是用来加载Java的扩展API,也就是/lib/ext中的类;第二个是AppClassLoader,它是用来加载用户机器上CLASSPATH设置目录中的Class,通常在没有指定ClassLoader的情况下,程序员自定义的类就由该ClassLoader进行加载。

ClassLoader加载流程:当运行一个程序时,JVM启动,运行bootstrap ClassLoader,该ClassLoader加载Java核心API(ExtClassLoader和AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class。

ClassLoader具备层次关系,不同类装载器分别创建的同一个类的字节码数据属于完全不用的对象,没有任何关联,通过Class.forName(String classNme)能够动态加载一个类。

2、JVM是如何通过ClassLoader机制加载第三方数据库驱动(JDBC)

class.forName()方法默认对加载的类进行了连接操作----->将com.mysql.jdbc.Driver注册到DriverManager,DriverManager也在这时被加载----->根据ClassLoader的双亲委托机制,DriverManager由bootstrap ClassLoader加载

(1)Class.forName("com.mysql.jdbc.Driver"); //加载驱动

(2)DriverManager.getConnection("url", "user", "password");//建立连接

四、Java中有没有内存溢出?Java中GC机制?

1、Java中存在内存溢出。

常见的Java内存溢出:

(1)java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出

(2)java.lang.OutOfMemoryError: PermGen space ---- PermGen space(内存的永久保存区域)溢出

(3)java.lang.StackOverflowError ---- 栈溢出

解决内存溢出:设置tomcat的启动内存

2、GC机制

(1)概念

GC即垃圾回收机制,是指JVM用于释放那些不再使用的对象所占用的内存。Java语言并不要求JVM有GC,也没有规定GC如何工作。不过常用的JVM都有GC,而且大多数GC都使用类似的算法管理内存和执行收集操作。Java的垃圾回收机制是为所有的Java应用进程服务的,而不是为某个特定的进程服务的。因此,任何一个进程都不能命令垃圾回收机制做什么,怎么做或做多少。在JVM垃圾收集器收集一个对象之前,Java提供了默认机制终止化该对象来释放资源,这个方法就是finalize()。它的原型为protected void finalize() throws Throwable(throws Throwable表示它可以抛出任何类型的异常)。在finalize()方法返回之后,对象消失,垃圾收集开始执行。

GC是JVM对内存(实际上就是对象)进行管理的方式。 Java的内存管理实际就是对象的管理,其中包括对象的分配和释放。

对象的释放是由GC决定和执行的。GC为了能够正确释放对象,必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。

垃圾收集器是自动运行的,一般情况下,无法显式的请求垃圾收集器。程序运行时,垃圾收集器会不时检查对象的各个引用,并回收无引用对象所占用的内存。调用System类中的静态gc()方法可以运行垃圾收集器,但这样并不能保证立即回收指定对象。

(1)配置参数

-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。

-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。

-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。

-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间。

-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)。

-XX:+PrintGC

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-Xloggc:filename

-XX:+UseSerialGC:设置串行收集器。

-XX:+UseParallelGC:设置并行收集器。

-XX:+UseParalledlOldGC:设置并行年老代收集器。

-XX:+UseConcMarkSweepGC:设置并发收集器。

-Xms:初始堆大小。

-Xmx:最大堆大小。

-XX:NewSize=n:设置年轻代大小。

-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4。

-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5。

-XX:MaxPermSize=n:设置持久代大小。

五、  通常Java对象Clone有几种?Java深拷贝又有几种实现方式?

1、 通常Java对象Clone有2种:深拷贝(深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象)、浅拷贝(浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象)。

2、Java深拷贝的实现方式

(1)通过覆盖Object类的clone()方法实现

(2)通过序列化(Serialization)的方式实现

六、 语句String s=new String(“helloworld”);创建了几个字符串对象?

2个。

七、 构造器(constructor)是否可被重写(override)

不能被重写,可以被重载。

八、 两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对

如果此对象重写了equals方法,那么可能出现这两个对象的equals相同,而hashcode不同。

如果此对象继承Object,没有重写equals方法,那么就使用Object的equals方法,Object对象的equals方法默认是用==实现的,那么如果equals相同,hashcode一定相同。

九、 Synchronized与java.util.concurrent.locks.Lock的异同?

1、并发量小的时候使用synchronize,并发量大的时候使用Lock。

2、synchronize是自动释放锁,Lock是主动释放锁

3、Lock可以设定所等待的时间,有些操作不会发生冲突现象,需要用Lock解决,比如同时读文件。

4、synchronized 是Java 语言层面的,是内置的关键字;Lock 则是JDK 5中出现的一个包,在使用时,synchronized 同步的代码块可以由JVM自动释放;Lock 需要程序员在finally块中手工释放,如果不释放,可能会引起难以预料的后果(在多线程环境中)。

十、 java访问修饰符public,private,protected,以及不写(默认)时的区别?

public:公共的,所有类都可以访问。

private:私有的,只有自身可以访问。

protected:保护的,子类及同一个包下的类可以访问。

不写:默认为default,同一个包下的类可以访问。

 

十一、 int和Integer有什么区别

1、int 是基本类型,直接存数值,进行初始化时变量初始为0。 
integer是对象,用一个引用指向这个对象,Integer的变量初始化为null。

2、Integer是int的包装类。

3、声明为Integer的变量需要实例化,声明为int的变量不需要实例化。

另:

1、两个通过new生成的Integer变量永远是不相等的,因为new生成的是两个对象,其内存地址不同。

2、Integer变量和int变量比较时,只要两个变量的值是向等的,则结果为true。因为包装类Integer和基本数据类型int比较时,java会自动拆包装为int,然后进行比较,实际上就变为两个int变量的比较。

3、new生成的Integer变量和new Integer()生成的变量比较时,结果为false。因为非new生成的Integer变量指向的是java常量池中的对象,而new Integer()生成的变量指向堆中新建的对象,两者在内存中的地址不同。

4、对于两个非new生成的Integer对象,进行比较时,如果两个变量的值在区间-128到127之间,则比较结果为true,如果两个变量的值不在此区间,则比较结果为false。(valueOf():值在区间-128到127之间会进行缓存)

十二、 java编写多线程程序有几种实现方式

1、继承Thread类,重写run方法(单继承,无返回值)

2、实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target(多继承,无返回值)

3、实现Callable接口通过FutureTask包装器来创建Thread线程(有返回值)

4、通过线程池创建线程(有返回值)

5、继承Thread类和实现Runnable接口都必须用Thread(如果是Thead子类就用它本身)产生线程,然后再调用start()方法。

6、继承Thread类必须如果产生Runnable实例对象,就必须产生多个Runnable实例对象,然后再用Thread产生多个线程;而实现Runnable接口,只需要建立一个实现这个类的实例,然后用这一个实例对象产生多个线程,实现了资源的共享性。

十三、 spring事务的传播级别和数据隔离级别

1、7种事务的传播级别:

(1) PROPAGATION_REQUIRED :默认的spring事务传播级别。如果上下文中已经存在事务,那么就加入到事务中执行;如果当前上下文中不存在事务,则新建事务执行。这个级别通常能满足处理大多数的业务场景。

(2)PROPAGATION_SUPPORTS :如果上下文存在事务,则支持事务加入事务;如果没有事务,则使用非事务的方式执行。并非所有的包在transactionTemplate.execute中的代码都会有事务支持。通常是用来处理那些并非原子性的非核心业务逻辑操作。

(3)PROPAGATION_MANDATORY:该级别的事务要求上下文中必须要存在事务,否则就会抛出异常。配置该方式的传播级别是有效的控制上下文调用代码遗漏添加事务控制的保证手段。比如一段代码不能单独被调用执行,但是一旦被调用,就必须有事务包含的情况,就可以使用这个传播级别。

(4)PROPAGATION_REQUIRES_NEW :,每次都会新建一个事务,并且同时将上下文中的事务挂起,执行当前新建事务完成以后,上下文事务恢复再执行。

(5)PROPAGATION_NOT_SUPPORTED :上下文中存在事务,则挂起事务,执行当前逻辑,结束后恢复上下文的事务。可以帮助你将事务极可能的缩小。

(6)PROPAGATION_NEVER :要求上下文中不能存在事务,一旦有事务,就抛出runtime异常,强制停止执行。

(7)PROPAGATION_NESTED :嵌套级别事务。如果上下文中存在事务,则嵌套事务执行,如果不存在事务,则新建事务。

2、4种数据隔离级别:

(1)Serializable :事务串行执行,资源消耗最大;

(2)REPEATABLE READ :保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。

(3)READ COMMITTED :大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。

(4)Read Uncommitted :保证了读取过程中不会读取到非法数据。


十四、 spring @Transactional 注意事项

1、@Transactional可以被用在接口定义、接口方法、类定义和类的public方法上。只有被配置在public方法上,且是被外部调用时才有效。

2、设置rollbackFor属性:rollbackFor = {Exception.class},默认只有RuntimeException会触发回滚。

3、数据库表引擎为InnoDB,否则不支持事务。

4、在接口上使用@Transactional注解,只有设置了基于接口的代理它才生效,注解是不能被继承的,如果正在使用基于类的代理时,那么事务的设置将不能被基于类的代理识别,而且对象也将不会被事务代理所包装。

5、@Transactional事务开启,或者是基于类的或者是基于接口的代理被创建,所以在同一个类中一个方法调用另一个有事务的方法,事务不起作用。

6、@Transactional注解不足以开启事务行为,必须在配置文件中使用配置元素,才可以开启事务行为。

7、带锁的事务方法最好不要放在事务里面。

8、@Transactional注解标注的方法尽量不要出现网络调用、比较耗时的处理程序,因为事务连接中数据库是不会释放的,消耗数据库连接资源。

9、通过元素的 "proxy-target-class" 属性值来控制是基于接口的还是基于类的代理被创建。

十五、@Transactional事务的实现过程(为什么加了这个注解之后Spring就会把该函数放到一个事务中)。

1)事务开始时,通过AOP机制,生成一个代理connection对象,并将其放入DataSource实例的某个与DataSourceTransactionManager相关的某处容器中。在接下来的整个事务中,客户代码都应该使用该connection连接数据库,执行所有数据库命令(不使用该connection连接数据库执行的数据库命令,在本事务回滚的时候得不到回滚)

2)事务结束时,回滚在第(1)步骤中得到的代理connection对象上执行的数据库命令,然后关闭该代理connection对象。

十六、MySQL的默认事务隔离级别是什么?如何配置?

1、MySQL的默认事务隔离级别是REPEATABLE READ。多数的数据库系统的默认事务隔离级别都是READ COMMITTED。

2、配置

(1)查看当前会话隔离级别:select @@tx_isolation;

(2)查看系统当前隔离级别:select @@global.tx_isolation;

(3)设置当前会话隔离级别:set session transaction isolatin level repeatable read / read commited / serializable / read uncommited ;

(4)设置系统当前隔离级别:set global transaction isolation level repeatable read / read commited / serializable / read uncommited ;

十七、READ COMMITTED与REPEATABLE READ的区别。

1、READ COMMITTED

读取提交的数据可能多次读取的数据结果不一致(不可重复读,幻读)。读取的行数据可以写。

2、REPEATABLE READ

可以重复读取,但有幻读。读取的数据行不可写,但是可以往表中新增数据。在MySQL中,其他事务新增的数据,看不到,不会产生幻读。采用多版本并发控制(MVCC)机制解决幻读问题。

注:

脏读:事务 A 读取了事务 B 未提交的数据,并在这个基础上又做了其他操作。

不可重复读:事务 A 读取了事务 B 已提交的更改数据。

幻读:事务 A 读取了事务 B 已提交的新增数据。

一、Spring实现aop

1、aop概念

AOP,面向切面编程。将影响了多个类的公共行为封装到一个可以重用的模块。目的是将横切关注点与业务逻辑处理分离。

一个应用程序分为核心关注点和横切关注点。核心关注点和具体应用的功能相关,而横切关注点存在与整个系统的范围内。在AOP里,每个关注点的实现并不知道是否有其他关注点关注它,组合的流向是从横切关注点到主关注点。

2、aop的作用

日志记录,性能统计,安全控制,事务处理,异常处理等。

3、Spring实现AOP

(1)基于XML配置

创建需要被代理的类----->创建AOP中需要使用到的通知类----->配置容器初始化时需要的XML文件(配置被代理对象、通知、aop配置:切面、切点、连接通知方法与切点)

(2)使用注解

创建需要被代理的类,为了实现IOC扫描在类上注解@Service并命名bean----->创建通知类(@Component表示该类的实例会被Spring IOC容器管理;@Aspect表示声明一个切面;@Before表示before为前置通知,通过参数execution声明一个切点)----->配置XML(aop:aspectj-autoproxy节点,Spring框架会自动为与AspectJ切面配置的Bean创建代理,proxy-target-class="true"属性表示被代理的目标对象是一个类,而非实现了接口的类,主要是为了选择不同的代理方式。)

(3)Aspect切点函数

切点函数可以定位到准确的横切逻辑位置。

@AspectJ使用AspectJ专门的切点表达式描述切面,Spring所支持的AspectJ表达式可分为四类:
方法切点函数:通过描述目标类方法信息定义连接点。
方法参数切点函数:通过描述目标类方法入参信息定义连接点。
目标类切点函数:通过描述目标类类型信息定义连接点。
代理类切点函数:通过描述代理类信息定义连接点。

常见的AspectJ表达式函数:
execution():满足匹配模式字符串的所有目标类方法的连接点
@annotation():任何标注了指定注解的目标方法链接点
args():目标类方法运行时参数的类型指定连接点
@args():目标类方法参数中是否有指定特定注解的连接点
within():匹配指定的包的所有连接点
target():匹配指定目标类的所有方法
@within():匹配目标对象拥有指定注解的类的所有方法
@target():匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解
this():匹配当前AOP代理对象类型的所有执行方法

最常用:execution(<修饰符模式>?<返回类型模式><方法名模式>(<参数模式>)<异常模式>?)

例:@Before("execution(* com..Spring.aop.Math.*(..))")

(4)Aspect通知注解

前置通知@Before、后置通知@After、返回通知@AfterReturning、异常通知@AfterThrowing、环绕通知@Around

二、Spring实现IoC

1、IoC概念

IoC,控制反转。IOC容器控制对象的创建,由容器进行对象注入,对象是被动接收依赖的对象。由Spring容器创建,当需要使用时,自动注入。

IoC解决了一般业务对象之间、业务对象与持久层之间存在的各种依赖关系,降低耦合度。控制反转是指在应用程序中对象的创建、销毁等不再由程序本身的编码实现,而是由外部的Spring容器在程序运行时根据需要注入到程序中,也就是对象的生命周期不是由程序本身来决定,而是由容器来控制,称为控制反转。


2、IoC作用

降低对象之间的耦合度,便于程序单元测试和后期升级、维护; 实现资源的可配置和易管理。

3、IOC的注入方法

1)构造方法注入:在被注入对象可以通过在其构造方法中声明依赖对象的参数列表,让外部IoC容器知道它需要依赖哪些对象。

2)setter 方法注入: 当前对象只要为其依赖对象所对应的属性添加setter方法,就可以通过setter方法将相应的依赖对象设置到被注入对象中。

3)接口注入:被注入对象如果想要IoC为其注入对象,就必须实现某个接口,这个接口提供一个方法,用来为其注入依赖对象。

4、Spring实现IoC

Spring就是通过工厂+反射将bean放到它的容器中的,当想用某个bean的时候,只需要调用getBean("beanID")方法即可

原理说明:

Spring容器的原理:通过解析xml文件,通过反射创建出所需要的bean将这些bean挨个放到集合中,然后对外提供一个getBean()方法,以便获得这bean




 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值