准备了三个实习:
1.百度质量部测试(要求JAVA 数据库 数据结构 相关知识)(一共三面 二面挂了)
2.去哪儿网java实习(要求只说了一个java 但面试问的很广 )(就一面 直接挂了)
3.360安全企业java实习(要求java SSM框架 MVC 数据库 最后去的这个 )(两面+hr面)
要求都是各公司招实习生时明确打出来的要求 跟面试问的有些出入 具体面试之后写
下面内容都是准备的时候从各个地方摘过来的 有的也许顺序比较乱 或者有错 有错请留言
其他准备面试的同学可以对着知识点看下有没有遗漏的~
三个面试的具体过程 之后会更新
MVC(Model-View-Controller)是软件工程的一种软件架构模式,把软件系统分为模型(model),视图(view)和控制器(controller)。
MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序的某一部分的重复利用成为可能。除此之外,此模式通过对复杂程度的简化,使程序结构更加直观。其中Model(javabean实现)模型,主要用来负责业务逻辑的处理,数据的保持,Model是MVC模式的核心部分,它也是一个应用需要实现的最主要的部分:进行业务逻辑的处理。View(jsp实现)视图,负责数据的输出,画面的显示。Controller(servlet)控制器,负责接收视图发送过来的数据,同时控制Model与View部分。
表现层(springMVC):Controller层(Handler层)
负责具体的业务模块流程的控制
Controller层通过要调用Service层的接口来控制业务流程,控制的
配置也在Spring配置文件里面。
业务层(Spring):Service层
负责业务模块的逻辑应用设计。
首先设计其接口,然后再实现他的实现类。
通过对Spring配置文件中配置其实现的关联,完成此步工作,我们
就可以通过调用Service的接口来进行业务处理。
最后通过调用DAO层已定义的接口,去实现Service具体的 实现类。
interface定义一些方法,并没有实现,需要implements来实现才可用。
extend可以继承一个接口,但仍是一个接口,也需要implements之后才可用。对于class而言,Extends用于(单)继承一个类(class),而implements用于实现一个接口(interface)。
持久层(Mybatis):Dao层(Mapper层)
负责与数据库进行交互设计,用来处理数据的持久化工作。
DAO层的设计首先是设计DAO的接口,
然后在Spring的配置文件中定义此接口的实现类,就可在其他模块中
调用此接口来进行数据业务的处理,而不用关心接口的具体实现类是
哪个类,这里用到的就是反射机制, DAO层的数据源配置,以及有
关数据库连接的参数都在Spring的配置文件中进行配置。
视图层:View层
负责前台jsp页面的展示。
此层需要与Controller层结合起来开发。
各层间的联系:
本来Controller层与View层是可以放在.jsp文件里一起开发的,但是为了降低代码的复杂提高其可维护性,将其分为了这两层,这也体现了MVC框架的特性,即结构清晰,耦合度低。度,
Service层是建立在DAO层之上的,建立了DAO层后才可以建立Service层,而Service层又是在Controller层之下的,因而Service层应该既调用DAO层的接口,又要提供接口给Controller层的类来进行调用,它刚好处于一个中间层的位置。每个模型都有一个Service接口,每个接口分别封装各自的业务处理方法。
controller->service->dao
用于从万维网服务器传输超文本到本地浏览器的传送协议。
基于TCP/IP通信协议来传送数据。
TCP UDP
TCP与UDP基本区别
1.基于连接与无连接
2.TCP要求系统资源较多,UDP较少;
3.UDP程序结构较简单
4.流模式(TCP)与数据报模式(UDP);
5.TCP保证数据正确性,UDP可能丢包
6.TCP保证数据顺序,UDP不保证
UDP应用场景:
1.面向数据报方式
2.网络数据大多为短消息
3.拥有大量Client
4.对数据安全性无特殊要求
5.网络负担非常重,但对响应速度要求高
三次握手
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
第一次握手:建立连接时,客户端发送syn(信号包)包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
http中的get、post、put、delete就对应资源的增删改查,get一般用于获取/查询资源信息,post一般用于更新资源信息。
POST的安全性要比GET的安全性高。
GET数据传输效率比POST高。
GET用来请求数据,POST用来修改数据。
B/S(浏览器/服务器)
• C/S(Client/Server),即客户端/服务端
使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。
读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。
servlet的运行机制,生命周期
比如在tomcat中, 当浏览器发送给服务器一个Servlet的请求时,如果这个Servlet是第一次被调用,那么服务器将会自动创建一个Servlet实例,并运行它;而如果这个Servlet已经被实例化,那么服务器只是会新启动一个线程来运行它
一个Servlet在服务器上最多只会驻留一个实例,在此期间会涉及到HttpServlet的方法, 在编写Servlet程序时,都是让它继承HttpServlet这个类,然后根据需要去覆盖HttpServlet中的方法。比较常用的方法有:init()、doGet()、doPost()、service()、destroy().
service()方法
如果客户端有一个对Servlet的请求发送过来,那么服务器端会产生一个新的线程,并且让它调用Servlet的service()方法。service()方法根据收到的客户端请求类型,决定调用doGet()还是doPost()还是其他的doXXX()方法
init()方法
对Servlet做一些初始化工作,这个方法只会被调用一次,不会对每次连接都调用,可以将一些初始化代码放在该函数中
(3)destroy()方法
如果要删除某个Servlet实例,那么在删除之前服务器会先调用destroy()方法。可以在这个方法中执行一些清理动作,比如释放数据库连接,关闭打开的文件等。
面向对象的三个基本特征是:封装、继承、多态(覆盖和重载)。
封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。无需关注细节。封装的目的:对外隐藏细节,便于维护;便于代码重用。
继承 子类继承父类,某个类型的对象获得另一个类型对象的属性和方法。
如何实现继承:类的继承和接口的继承。抽象类和接口。
抽象类和接口的相同点:
都不能直接实例化。
都可以继承实现一些方法属性等。
抽象类和接口的不同点:
很重要:抽象类继承方向是相同的物种/类别的抽象,接口是一种规范或者是相同的行为/动作/特性的抽象。这一点很大程度决定了选择抽象类还是接口,这可以作为一个基本的准则把。
抽象类只能继承一个,接口可以继承多个。
抽象类可以实现一些具体的方法,属性,接口不能。
接口可以很好地实现回调,抽象类有局限性。因为抽象类只能继承实现一个。
抽象类定义好以后,很容易修改;通常接口定义好后不能再修改,
多态就是不同类对象对同一消息做出响应。
封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!覆盖是父类与子类间,方法名和方法参数都相同,重载是同一类内,方法名相同,参数列表不一样,
比较粗糙的java内存区的划分是对内存和栈内存,因为这两块是与对象内存分配关系最密切的内存区。
栈:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出 StackOverflowError 异常;如果虚拟机栈可以动态扩展(当前大部分的 Java 虚拟机都可动态扩展,只不过 Java 虚拟机规范中也允许固定长度的虚拟机栈),当扩展时无法申请到足够的内存时会抛出 OutOfMemoryError 异常。
java堆:Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。 此内存区域的唯一目的就是存放对象实例
堆再划分为 新生代和老年代; 多个线程私有的分配缓冲。
可以细分为新生代、老年代和永久代,新生代里面又可以分为Eden Space、From Survivor Space和To Survivor Space。
Java 中的堆也是 GC 收集垃圾的主要区域。GC 分为两种:Minor GC、Full GC ( 或称为 Major GC )。
Minor GC 是发生在新生代中的垃圾收集动作,所采用的是复制算法。
新生代几乎是所有 Java 对象出生的地方,即 Java 对象申请的内存以及存放都是在这个地方。Java 中的大部分对象通常不需长久存活,具有朝生夕灭的性质。
当对象在 Eden ( 包括一个 Survivor 区域,这里假设是 from 区域 ) 出生后,在经过一次 Minor GC 后,如果对象还存活,并且能够被另外一块 Survivor 区域所容纳(上面已经假设为 from 区域,这里应为 to 区域,即 to 区域有足够的内存空间来存储 Eden 和 from 区域中存活的对象 ),则使用复制算法将这些仍然还存活的对象复制到另外一块 Survivor 区域 ( 即 to 区域 ) 中,然后清理所使用过的 Eden 以及 Survivor 区域 ( 即 from 区域 ),并且将这些对象的年龄设置为1,以后对象在 Survivor 区每熬过一次 Minor GC,就将对象的年龄 + 1,当对象的年龄达到某个值时 ( 默认是 15 岁,可以通过参数 -XX:MaxTenuringThreshold 来设定 ),这些对象就会成为老年代。
Full GC 是发生在老年代的垃圾收集动作,所采用的是标记-清除算法。
1.引用计数算法
这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称为引用链。当一个对象到GC roots没有任何引用链相连时,则证明此对象是不可用的。如下图所示,对象object5,object6,object7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。
标记——清除算法,复制算法,标记整理算法,分代收集算法
先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,它的标记过程其实就是上述的可达性分析算法中的标记过程。它是最基础的算法,后续的收集算法都是基于这种思路并对其不足进行改进而得到的。
复制算法出现了,它将可用内存按容量划分为大小相等的两块,每次只使用其中一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。
标记-整理算法(Mark-Compact)的标记过程与”标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存货的对象都向一端移动,然后直接清理掉端边界以外的内存
分代收集算法是当前商业虚拟机的垃圾收集机制都采用的算法。 分代收集算法并不是一种新的算法模型,它只是一种根据对象存活周期的不同特点而对不同收集算法的综合运用。具体来说就是对堆区所采用的垃圾收集方案。堆区分为新生代和老年代,新生代的特点就是,每次垃圾收集都会发现大批对象死去,只有少量存活,那么采用复制算法,只需要付出少量存活对象的复制成本就可以完成收集,这就是所谓的Minor GC 。老年代的特点就是对象存活率高,没有额外空间的对它进行分配担保,那么就必须使用 “标记-清除”或者”标记-整理”算法。
1.hashmap允许空键、值, HashMap是数组+链表+红黑树(链表长度大于8时转换为红黑树);
2.hashtable同步(线程安全),hashmap异步(线程不安全 多线程场合要手动同步) 什么是线程安全呢?简单的来说,就是当多个线程同时在使用一个Map的时候,至少有一个线程对Map的结构进行了修改,那么必须保证这个修改被立即同步到其他线程中去,避免其他线程获取到错误的值。
3. ConcurrentHashMap在每一个分段(相当于一个桶,里面存放数组,ConcurrentHashMap会进行分段)上都用锁进行保护,从而让锁的粒度更精细一些,并发性能更好,既ConcurrentHashMap不同步也是线程安全的
String 字符串常量 (不可变对象,经常改变内容的字符串最好不用string,因为引用对象多了后,JVM中GC工作,速度会很慢)
StringBuffer 字符串变量(线程安全)(改变的结果都是对stringbuffer对象本身进行操作,不会生成新对象 主要操作是 append 和 insert)
StringBuilder 字符串变量(非线程安全)
大部分情况下 StringBuilder >StringBuffer > String
toString()方法
toString()方法将对象转换为字符串
.append()函数将特定内容插入到每个匹配元素里面的最后面,作为它的最后一个子元素(last child), (如果要作为第一个子元素
这三种模式的不同之处如下:
BIO:
一个线程处理一个请求。缺点:并发量高时,线程数较多,浪费资源。
Tomcat7或以下,在Linux系统中默认使用这种方式。
NIO:
利用Java的异步IO处理,可以通过少量的线程处理大量的请求。
Tomcat8在Linux系统中默认使用这种方式。
Tomcat7必须修改Connector配置来启动:
connectionTimeout="20000" redirectPort="8443"/> APR: 即Apache Portable Runtime,从操作系统层面解决io阻塞问题。 Tomcat7或Tomcat8在Win7或以上的系统中启动默认使用这种方式。 线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。 线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。 一个程序至少有一个进程,一个进程至少有一个线程. 线程是进程的一个实体 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉, 什么是线程同步? 当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一数据导致数据不一致),所以我们用同步机制来解决这些问题。 实现同步机制的方法: 1.同步代码块: synchronized(同一个数据){} 同一个数据:就是N条线程同时访问一个数据。 2.同步方法:就是使用 synchronized 来修饰某个方法,则该方法称为同步方法。 进程间的通信方式 # 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。 # 有名管道 (namedpipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。 # 信号量(semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。 # 消息队列( messagequeue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。 # 信号 (sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。 # 共享内存(shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。 # 套接字(socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。 线程间的通信方式 # 锁机制:包括互斥锁、条件变量、读写锁 *互斥锁提供了以排他方式防止数据结构被并发修改的方法。 *读写锁允许多个线程同时读共享数据,而对写操作是互斥的。 *条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。 # 信号量机制(Semaphore):包括无名线程信号量和命名线程信号量 # 信号机制(Signal):类似进程间的信号处理 线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。 多线程实现方式: 继承Thread类(重写run方法,调用时使用start()函数) 实现Runnable接口(重写run方法) 实现Callable接口(runnable相似,但增加异常和返回值 使用ExecutorService、Callable、Future实现有返回结果的线程) 基于线程池的方式(线程和数据库连接这些资源都非常宝贵,那么每次需要的时候创建,不需要销毁非常浪费资源。线程池不需要使用者实现,jdk官方提供了API) // 创建线程池 ExecutorService threadPool = Executors.newFixedThreadPool(10); while(true) { threadPool.execute(new Runnable() { // 提交多个线程任务,并执行 这个机制就是Session.典型的场景比如购物车,当你点击下单按钮时,由于HTTP协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的Session,用用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几本书。这个Session是保存在服务端的,有一个唯一标识。 如何识别特定的客户?这个时候Cookie就登场了。 需要在 Cookie 里面记录一个Session ID,以后每次请求把这个会话ID发送到服务器,我就知道你是谁了。 Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中; Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式 区别:1.存取方式的不同(cookie-ASCII字符串;session-任意类型数据) 2.隐私策略不同(COOkie存储在客户端阅读器中,对客户端可见;session存储在服务器上,对客户端透明,不存在敏感信息泄露) 3.有效期不同(cookie持久,session关闭浏览器就拜拜) 4.服务器压力不同(session保存在服务器端, 每个用户都会产生一个Session。假如并发访问的用户十分多,会产生十分多的Session,耗费大量的内存。因而像Google、Baidu、Sina这样并发访问量极高的网站,是不太可能运用Session来追踪客户会话的。cookie保存在客户端) 5.浏览器支持不同(cookie需要浏览器支持,浏览器禁用就不行) SHA-1返回值是160bit,MD5返回值128bit (意思大概是SHA-1范围比MD5大) SHA-1 MD5都被称为哈希函数,之所以能加密: 1.都是不可逆函数,无法由哈希值倒算出原始信息。 2.原始信息任何一点改变都会导致哈希值的不同。 3.运算代价较低。 4.两段不同信息“碰巧”有一样的哈希值概率极低(基本不可能) SHA-1 MD5用处: 1.密码加密 2.文件校验(下载大尺寸文件时网站提供MD5值,下载后在文件基础上再计算MD5值,一样说明文件没有损坏或被网站恶意修改) 一种是比较排序,时间复杂度O(nlogn) ~ O(n^2),主要有:冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序等。 另一种是非比较排序,时间复杂度可以达到O(n),主要有:计数排序,基数排序,桶排序等。 排序算法稳定性的简单形式化定义为:如果Ai = Aj,排序前Ai在Aj之前,排序后Ai还在Aj之前,则称这种排序算法是稳定的。通俗地讲就是保证排序前后两个相等的数的相对顺序不变。 高并发解决: 1.缓存 2.底层优化 3.静态资源 4.集群和分布式 Java集合大致可以分为Set、List、Queue和Map四种体系,其中Set代表无序、不可重复的集合;List代表有序、重复的集合;而Map则代表具有映射关系的集合,Java 5 又增加了Queue体系集合,代表一种队列集合实现。 Java集合就像一种容器,可以把多个对象(实际上是对象的引用,但习惯上都称对象)“丢进”该容器中。从Java 5 增加了泛型以后,Java集合可以记住容器中对象的数据类型,使得编码更加简洁、健壮。 1.数组长度在初始联数组,键值对 key-value)。化时指定,意味着只能保存定长的数据。而集合可以保存数量不确定的数据。同时可以保存具有映射关系的数据(即关 2.数组元素即可以是基本类型的值,也可以是对象。集合里只能保存对象(实际上只是保存对象的引用变量),基本数据类型的变量要转换成对应的包装类才能放入集合类中。 Collection接口是Set,Queue,List的父接口。Collection接口中定义了多种方法可供其子类进行实现,以实现数据操作。由于方法比较多,就偷个懒,直接把JDK文档上的内容搬过来。 使用Iterator遍历集合元素 Iterator接口经常被称作迭代器,它是Collection接口的父接口。但Iterator主要用于遍历集合中的元素。 下面具体介绍Collection接口的三个子接口Set,List,Queue。 简介 Set集合与Collection集合基本相同,没有提供任何额外的方法。实际上Set就是Collection,只是行为略有不同(Set不允许包含重复元素)。 Set集合不允许包含相同的元素,如果试图把两个相同的元素加入同一个Set集合中,则添加操作失败,add()方法返回false,且新元素不会被加入。 简介 List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素 。List集合默认按元素的添加顺序设置元素的索引,例如第一个添加的元素索引为0,第二个添加的元素索引为1...... List作为Collection接口的子接口,可以使用Collection接口里的全部方法。而且由于List是有序集合,因此List集合里增加了一些根据索引来操作集合元素的方法。 除此之外,Java 8还为List接口添加了如下两个默认方法。 void replaceAll(UnaryOperator operator):根据operator指定的计算规则重新设置List集合的所有元素。 void sort(Comparator c):根据Comparator参数对List集合的元素排序。 简介 Queue用户模拟队列这种数据结构,队列通常是指“先进先出”(FIFO,first-in-first-out)的容器。队列的头部是在队列中存放时间最长的元素,队列的尾部是保存在队列中存放时间最短的元素。新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素。通常,队列不允许随机访问队列中的元素。 接口中定义的方法 Map用户保存具有映射关系的数据,因此Map集合里保存着两组数,一组值用户保存Map里的key,另一组值用户保存Map里的value,key和value都可以是任何引用类型的数据。Map的key不允许重复,即同一个Map对象的任何两个key通过equals方法比较总是返回false。 如下图所描述,key和value之间存在单向一对一关系,即通过指定的key,总能找到唯一的、确定的value。从Map中取出数据时,只要给出指定的key,就可以取出对应的value。 1.与Set集合的关系 如果 把Map里的所有key放在一起看,它们就组成了一个Set集合(所有的key没有顺序,key与key之间不能重复),实际上Map确实包含了一个keySet()方法,用户返回Map里所有key组成的Set集合。 2.与List集合的关系 如果把Map里的所有value放在一起来看,它们又非常类似于一个List:元素与元素之间可以重复,每个元素可以根据索引来查找,只是Map中索引不再使用整数值,而是以另外一个对象作为索引。 SPRING 两大特性 BeanFactory 是 Spring 框架的基础设施 IOC(控制反转) java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通常,每个对象在使用他的合作对象时,自己均要使用像new object() 这样的语法来完成合作对象的申请工作。你会发现:对象间的耦合度高了。而IOC的思想是:Spring容器来实现这些相互依赖对象的创建、协调工作。 控制的什么被反转了?就是:获得依赖对象的方式反转了。 依赖注入(di )IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。 AOP,面向切面编程(最常用的就是日志记录, 日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用 并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。。) IOC就是典型的工厂模式,通过sessionfactory去注入实例。 AOP就是典型的代理模式的体现。 在我们传统的 JDBC 中,我们除了需要自己提供 SQL 外,还必须操作 Connection、Statment、ResultSet,不仅如此,为了访问不同的表,不同字段的数据,我们需要些很多雷同模板化的代码,闲的繁琐又枯燥。 而我们在使用了 MyBatis 之后,只需要提供 SQL 语句就好了,其余的诸如:建立连接、操作 Statment、ResultSet,处理 JDBC 相关异常等等都可以交给 MyBatis 去处理,我们的关注点于是可以就此集中在 SQL 语句上,关注在增删改查这些操作层面上。 并且 MyBatis 支持使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。13.进程 线程
14.Session和cookie(最常见用处就是自动登录)
15.密码加密(安全散列算法)
16.算法
17.java集合框架
Java集合和数组的区别:
Collection接口:
简介
Set集合
List集合
Queue集合
Map集合
简介
Map集合与Set集合、List集合的关系
18.spring
19.为什么使用MYBATIS