四、StringBufferStringBuilderString区别5
五、Hashtable与HashMap的区别5
六、九大隐式对象5
七、Forword(请求转发)与Redirect(重定向)6
八、JQurey总结6
九、XML和Json的特点6
十、request.getSession()、reqeust.getSession(false)和request.getSession(true)7
十一、Page和PageContext的区别7
十二、Ajax总结7
十三、JSP9大隐视对象中四个作用域的大小与作用范围7
十四、List,Set,Collection,Collections8
十五、java的基本数据类型8
十六、冒泡排序8
十七、二分查找法9
十九、阶乘10
二十、UE和UI的区别10
二十一、osi七层模型10
二十二、线程和进程的区别11
二十三、jvm的内存结构11
二十四、内存泄露和内存溢出11
二十五、单例11
二十六、解析xml文件的几种技术12
二十七、项目的生命周期13
二十八、OSCache的判断14
二十九、经常访问的技术网站14
三十、项目团队中交流的工具14
三十一、平时浏览的书籍14
三十二、javaException体系结构15
三十三、session和cookie的区别15
三十四、字节流与字符流的区别16
三十五、final,finally,finalize三者区别16
三十六、Io流的层次结构16
三十七、JAVA:18
三十八、JavaSEJavaEEJavaME区别18
三十九、JDKJREJVM的区别:19
四十、报错的状态码:20
四十一、协议以及默认的端口号20
四十二、抽象类与接口的区别20
四十三、修饰符的作用20
框架篇21
一、Struts1的运行原理21
二、Struts2的运行原理21
三、struts2的体系结构21
四、SpringMVC运行原理22
五、Struts1.x与Struts2.x的区别23
六、SpringMVC、struts1和struts2区别23
七、Struts2中result中的type类型23
八、Struts2标签24
九、SSI整合24
十、SSH整合24
十、SpringMVC整合25
十一、Hibernate中get和load的区别25
十二、Hibernate、Ibatis、Jdbc三者的区别25
十三、Hibernate的运行原理26
十四、Hibernate五大核心(类/接口)简述26
十五、Hibernate与JDBC的区别26
十六、Hibernate中的两大配置文件26
十七、Hibernate事务处理27
十八、Hibernate的三种状态以及状态的转换27
十九、分页步骤27
二十、hibernate缓存概述27
二十一、Ssh的概述:28
二十二、防止表单重复提交28
二十三、JSP标签:29
二十四、过滤器29
二十五、拦截器的理解30
二十六、Spring融入框架30
数据库篇31
一、JDBC连接数据库步骤(以MYSQL为例)31
二、数据库连接池32
三、mysql的数据库导入导出32
四、jdbc分段批量提交的时候出现异常怎么处理33
五、jdbc批量处理数据33
六、Oracle分页33
七、Oracle的基本数据类型33
八、id、rowid、rownum的区别34
九、主键和唯一索引的区别?34
十、Preparedstatement和statement的区别35
十一、数据库三范式35
十二、视图概述35
十三、存储过程概述35
十四、索引概述36
十五、必背的sql语句37
业务场景篇39
一、Spring的概述39
二、事务概述41
三、权限概述41
四、OSCache业务场景42
五、线程概述42
六、Ajax请求Session超时问题43
七:java线程池概述43
八、OSCache概述44
九、OSCache+autocomplete+单例业务场景44
十、缓存概述45
十一、实现页面静态化业务场景45
十二、servlet线程安全描述45
十三、(jbpm4)工作流引擎描述:46
十四、JPBM业务场景47
十五、Ant描述47
十六、FreeMarker描述47
十七、webService描述48
十八、oracle索引概述49
十九、oracle存储过程49
二十、Junit业务场景50
二十一、Apache+Tomcat实现负载均衡及seesion复制50
二十二、Ant业务场景50
二十三、maven业务场景51
二十四、Servlet的概述:51
优化篇52
一、代码优化52
二、业务优化52
三、sql优化53
四、防sql注入53
java.lang:这个是系统的基础类,比如String、Math、Integer、System和Thread,提供常用功能。
java.io:这里面是所有输入输出有关的类,比如文件操作等
java.net:这里面是与网络有关的类,比如URL,URLConnection等。
java.util:这个是系统辅助类,特别是集合类Collection,List,Map等。
java.sql:这个是数据库操作的类,Connection,Statememt,ResultSet等
1.get是从服务器上获取数据,post是向服务器传送数据,
2.get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。
3.get安全性非常低,post安全性较高。但是执行效率却比Post方法好。
4.在进行文件上传时只能使用post而不能是get。
面向对象编程有四个特征:抽象,封装,继承,多态。
多态有四种体现形式:
1.接口和接口的继承。
2.类和类的继承。
3.重载。
4.重写。
其中重载和重写为核心。
重载:重载发生在同一个类中,在该类中如果存在多个同名方
法,但是方法的参数类型和个数不一样,那么说明该方法被重
载了。
重写:重写发生在子类继承父类的关系中,父类中的方法被子
类继承,方法名,返回值类型,参数完全一样,但是方法体不
一样,那么说明父类中的该方法被子类重写了。
String字符串常量不可变使用字符串拼接时是不同的2个空间
StringBuffer字符串变量可变线程安全字符串拼接直接在字符串后追加
StringBuilder字符串变量可变非线程安全字符串拼接直接在字符串后追加
1.StringBuilder执行效率高于StringBuffer高于String.
2.String是一个常量,是不可变的,所以对于每一次+=赋值都会创建一个新的对象,StringBuffer和StringBuilder都是可变的,当进行字符串拼接时采用append方法,在原来的基础上进行追加,所以性能比String要高,又因为StringBuffer是线程安全的而StringBuilder是线程非安全的,所以StringBuilder的效率高于StringBuffer.
3.对于大数据量的字符串的拼接,采用StringBuffer,StringBuilder.
HashMap不是线程安全的,HashTable是线程安全。
HashMap允许空(null)的键和值(key),HashTable则不允许。
HashMap性能优于Hashtable。
Map
1.Map是一个以键值对存储的接口。Map下有两个具体的实现,分别是HashMap和HashTable.
2.HashMap是线程非安全的,HashTable是线程安全的,所以HashMap的效率高于HashTable.
3.HashMap允许键或值为空,而HashTable不允许键或值为空.
HashMap是非同步的,没有对读写等操作进行锁保护,所以是线程不安全的,在多线程场景下会出现数据不一致的问题。而HashTable是同步的,所有的读写等操作都进行了锁(synchronized)保护,在多线程环境下没有安全问题。但是锁保护也是有代价的,会对读写的效率产生较大影响。
HashMap结构中,是允许保存null的,Entry.key和Entry.value均可以为null。但是HashTable中是不允许保存null的。
HashMap的迭代器(Iterator)是fail-fast迭代器,但是Hashtable的迭代器(enumerator)不是fail-fast的。如果有其它线程对HashMap进行的添加/删除元素,将会抛出ConcurrentModificationException,但迭代器本身的remove方法移除元素则不会抛出异常。这条同样也是Enumeration和Iterator的区别。
输入/输出对象:requestresponseout
作用域通信对象:sessionapplicationpageContext
Servlet对象:pageconfig
错误对象:exception
1、从数据共享上
Forword是一个请求的延续,可以共享request的数据
Redirect开启一个新的请求,不可以共享request的数据
2、从地址栏
Forword转发地址栏不发生变化
Redirect转发地址栏发生变化
jquery是一个轻量级的js框架,具有跨浏览器的特性,兼容性好,
并且封装了很多工具,方便使用。
常用的有:选择器,dom操作,ajax(ajax不能跨域),特效,工具类
Xml特点:
1、有且只有一个根节点;
2、数据传输的载体
3、所有的标签都需要自定义
4、是纯文本文件
Json(JavaScriptObjectNotation)特点:
json分为两种格式:
json对象(就是在{}中存储键值对,键和值之间用冒号分隔,
键值对之间用逗号分隔);
json数组(就是[]中存储多个json对象,json对象之间用逗号分隔)
(两者间可以进行相互嵌套)数据传输的载体之一
区别:
传输同样格式的数据,xml需要使用更多的字符进行描述,
流行的是基于json的数据传输。
xml的层次结构比json更清晰。
共同点:
xml和json都是数据传输的载体,并且具有跨平台跨语言的特性。
getSession()/getSession(true):当session存在时返回该session,否则新建一个session并返回该对象
getSession(false):当session存在时返回该session,否则返回null
Page是servlet对象;使用this关键字,它的作用范围是在同一页面。
PageContext是作用域通信对象;通常使用setAttribute()和getAttribute()来设置和获取存放对象的值。
AJAX全称:异步JavaScript及XML(AsynchronousJavaScriptAndXML)
Ajax的核心是JavaScript对象XmlHttpRequest(XHR)。
Ajax的优点:
提高用户体验度(UE)
提高应用程序的性能
进行局部刷新
AJAX不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。
2.通过AJAX,我们的JavaScript可使用JavaScript的XMLHttpRequest对象来直接与服务器进行通信。通过这个对象,我们的JavaScript可在不重载页面的情况与Web服务器交换数据,即可局部刷新。
3.AJAX在浏览器与Web服务器之间使用异步数据传输(HTTP请求),这样就可使网页从服务器请求少量的信息,而不是整个页面,减轻服务器的负担,提升站点的性能。
AJAX可使因特网应用程序更小、更快,更友好,用户体验(UE)好。
异步:多线程,不会造成阻塞,会继续执行下面代码,提升用户体验
同步:单线程,会阻塞
sync默认是true:即为异步方式,$.ajax执行后,会继续执行ajax后面的脚本,直到服务器端返回数据后,触发$.ajax里的success方法
若要将其设置为false,则所有的请求均为同步请求,在没有返回值之前,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以
四个作用域从大到小:appliaction>session>request>page
application:全局作用范围,整个应用程序共享.生命周期为:应用程序启动到停止。
session:会话作用域,当用户首次访问时,产生一个新的会话,以后服务器就可以记住这个会话状态。
request:请求作用域,就是客户端的一次请求。
page:一个JSP页面。
以上作用范围使越来越小,request和page的生命周期都是短暂的,他们之间的区别就是:一个request可以包含多个page页(include,forward)。
1.List和Set都是接口,他们都继承于接口Collection,List是一个有序的可重复的集合,而Set的无序的不可重复的集合。Collection是集合的顶层接口,Collections是一个封装了众多关于集合操作的静态方法的工具类,因为构造方法是私有的,所以不能实例化。
2.List接口实现类有ArrayList,LinkedList,Vector。ArrayList和Vector是基于数组实现的,所以查询的时候速度快,而在进行增加和删除的时候速度较慢LinkedList是基于链式存储结构,所以在进行查询的时候速度较慢但在进行增加和删除的时候速度较快。又因为Vector是线程安全的,所以他和ArrayList相比而言,查询效率要低。
3、Set:循环,迭代器,foreach
不允许重复对象,无序,只允许一个null元素
如果你想保证插入元素的唯一性,也就是你不想有重复值的出现,那么可以选择一个Set的实现类,比如HashSet、LinkedHashSet或者TreeSet
数据类型大小
byte(字节)1(8位)-128~127
shot(短整型)2(16位)
int(整型)4(32位)范围:-2147483648~2147483647
long(长整型)8(32位)
float(浮点型)4(32位)
double(双精度)8(64位)
char(字符型)2(16位)
boolean(布尔型)1位
附加:
String是基本数据类型吗(String不是基本数据类型)
String的长度是多少,有限制(长度受内存大小的影响)
publicclassSort{
publicstaticvoidsort(){
Scannerinput=newScanner(System.in);
intsort[]=newint[10];
inttemp;
System.out.println("请输入10个排序的数据:");
for(inti=0;i sort[i]=input.nextInt(); } for(inti=0;i for(intj=0;j if(sort[j] temp=sort[j]; sort[j]=sort[j+1]; sort[j+1]=temp; System.out.println("排列后的顺序为:"); System.out.print(sort[i]+""); publicstaticvoidmain(String[]args){ sort(); publicclassDateFormat{ publicstaticvoidfun(){ SimpleDateFormatsdf=newSimpleDateFormat("yyyy年MM月dd日"); StringnewDate; try{ newDate=sdf.format(newSimpleDateFormat("yyyyMMdd") .parse("20121115")); System.out.println(newDate); }catch(ParseExceptione){ e.printStackTrace(); publicstaticvoidmain(Stringargs[]){ fun(); publicclassMultiply{ publicstaticintmultiply(intnum){ if(num<0){ System.out.println("请输入大于0的数!"); return-1; }elseif(num==0||num==1){ return1; }else{ returnmultiply(num-1)*num; System.out.println(multiply(10)); UE是用户体验度 UI界面原型(用户界面)(相当于买房时用的模型) 设计UI的作用: 1、帮助程序员工作(界面已由美工设计完成) 2、提前让用户对项目有个宏观的了解,知道效果是什么样子。 第一层:物理层 第二层:数据链路层 第三层:网络层 第四层:传输层 第五层:会话层 第六层:表示层 第七层:应用层 1.线程(Thread)与进程(Process) 进程定义的是应用程序与应用程序之间的边界,通常来说一个进程就代表一个与之对应的应用程序。不同的进程之间不能共享代码和数据空间,而同一进程的不同线程可以共享代码和数据空间。 2.一个进程可以包括若干个线程,同时创建多个线程来完成某项任务,便是多线程。 3.实现线程的三种方式:继承Thread类,实现Runable接口,实现Callable接口 java虚拟机的内存结构分为堆(heap)和栈(stack),堆里面存放是对象实例也就是new出来的对象。栈里面存放的是基本数据类型以及引用数据类型的地址。 对于所谓的常量是存储在方法区的常量池里面。 堆:存放值 栈:存放地址 本地方法栈:本地一些方法库 程序计数器:遇到多线程或者其他事物时,记录当时执行位置 元空间: 线程栈: 栈帧: 局部变量表 操作数栈 动态链接 方法出口 垃圾回收机制:老年代和年轻 年轻代:扩大初始内存大小,8/1/1 老年代:年轻代轮回在15个回合 Tomcat的优化: B-tree结构,表结构还是数据源datasource(url)stream和public和private 初始的结果是否处于一致性的,事物的回滚 内存泄露(memoryleak),是指应用程序在申请内存后, 无法释放已经申请的内存空间.一次内存泄露危害可以忽略, 但如果任其发展最终会导致内存溢出(outofmemory). 如读取文件后流要进行及时的关闭以及对数据库连接的释放。 内存溢出(outofmemory)是指应用程序在申请内存时, 没有足够的内存空间供其使用。 如我们在项目中对于大批量数据的导入,采用分段批量提交的方式。 单例就是该类只能返回一个实例。 单例所具备的特点: 1.私有化的构造函数 2.私有的静态的全局变量 3.公有的静态的方法 单例分为懒汉式、饿汉式和双层锁式 饿汉式: publicclassSingleton1{ privateSingleton1(){}; privatestaticSingleton1single=newSingleton1(); publicstaticSingleton1getInstance(){ returnsingle; 懒汉式: publicclassSingleton2{ privateSingleton2(){} privatestaticSingleton2single=null; publictaticSingleton2getInstance(){ if(single==null){ single=newSingleton2(); 线程安全: publicclassSingleton3{ privateSingleton3(){} privatestaticSingleton3single; publicstaticSingleton3getInstance(){ if(null==single){ synchronized(single){ single=newSingleton3(); 参考: 通过双重判断来保证单列设计模式在多线程中的安全性, 并且它在性能方面提高了很多。 synchronized在方法上加锁(同步锁) synchronized在代码块内部加锁(同步代码块) synchronized(同步锁) 使用synchronized如何解决线程安全的问题? 1.synchronized在方法上加锁 2.synchronized在代码块内部加锁 1.懒汉2.饿汉3.双重判断 1、解析xml的几种技术 1.dom4j 2.sax 3.jaxb 4.jdom 5.dom dom4j是一个Java的XMLAPI,类似于jdom,用来读写XML文件的。dom4j是一个非常优秀的JavaXMLAPI,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。 SAX(simpleAPIforXML)是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。而且相比于DOM,SAX可以在解析文档的任意时刻停止解析,但任何事物都有其相反的一面,对于SAX来说就是操作复杂。 JAXB(JavaArchitectureforXMLBinding)是一个业界的标准,是一项可以根据XMLSchema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便地结合XML数据和处理函数。 2、dom4j与sax之间的对比:【注:必须掌握!】 dom4j不适合大文件的解析,因为它是一下子将文件加载到内存中,所以有可能出现内存溢出, sax是基于事件来对xml进行解析的,所以他可以解析大文件的xml 也正是因为如此,所以dom4j可以对xml进行灵活的增删改查和导航,而sax没有这么强的灵活性 所以sax经常是用来解析大型xml文件,而要对xml文件进行一些灵活(crud)操作就用dom4j 1.需求分析 2.概要设计 3.详细设计(用例图,流程图,类图) 4.数据库设计(powerdesigner) 5.代码开发(编写) 6.单元测试(junit白盒测试)(开发人员) svn版本管理工具(提交,更新代码,文档) 7.集成测试(黑盒测试,loadrunner(编写测试脚本)(高级测试)) 8.上线试运行(用户自己体验) 9.压力测试(loadrunner) 10.正式上线 11.维护 Objectobj=CacheManager.getInstance().getObj("oaBrandList"); //从缓存中取数据 if(null==obj){ obj=brandDao.getBrandList(); //如果为空再从数据库获取数据 //获取之后放入缓存中 CacheManager.getInstance().putObj("oaBrandList",obj); return(List 1.csdn(详细步骤的描述) 2.iteye(详细步骤的描述) 3.oschina(开源中国获取java开源方面的信息技术) 4.java开源大全www.open-open.com(获取java开源方面的信息技术) 5.infoq(对java,php,.net等这些语言的一些最新消息的报道) 飞秋(局域网)qq(局域网,外网) 实战经验: ***inaction(实战) ***深入浅出 ***入门指南 思想基础: 大话设计模式重构 java异常是程序运行过程中出现的错误。Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。在JavaAPI中定义了许多异常类,分为两大类,错误Error和异常Exception。其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常(非runtimeException),也称之为不检查异常(UncheckedException)和检查异常(CheckedException)。 1、Error与Exception Error是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath等。 这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。 Exception是程序本身可以处理的异常,这种异常分两大类运行时异常和非运行时异常。程序中应当尽可能去处理这些异常。 2、运行时异常和非运行时异常 运行时异常:都是RuntimeException类及其子类异常:IndexOutOfBoundsException索引越界异常 ArithmeticException:数学计算异常 NullPointerException:空指针异常 ArrayOutOfBoundsException:数组索引越界异常 ClassNotFoundException:类文件未找到异常 ClassCastException:造型异常(类型转换异常) 这些异常是不检查异常(UncheckedException),程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的。 非运行时异常:是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如: IOException、文件读写异 FileNotFoundException:文件未找到异常 EOFException:读写文件尾异常 MalformedURLException:URL格式错误异常 SocketException:Socket异常 SQLException:SQL数据库异常 session是存储在服务器端,cookie是存储在客户端的,安全性session高 单个cookie在客户端的限制是3K 访问HTML页面是不会创建session,但是访问index.JSP时会创建session(JSP实际上是一个Servlet,Servlet中有getSession方法) stream结尾都是字节流,reader和writer结尾都是字符流 两者的区别就是读写的时候一个是按字节读写,一个是按字符。 实际使用通常差不多。 在读写文件需要对内容按行处理,比如比较特定字符,处理某一行数据的时候一般会选择字符流。 只是读写文件,和文件内容无关的,一般选择字节流。 三十五、static、final,finally,finalize三者区别 1、static修饰的变量和方法,在类加载时即被初始化,可直接通过类名.变量名和类型.方法名进行调用。 2、static修饰的变量,在类加载时会被分配到数据区的方法区。类的实例可共享方法区中的变量。如果static修饰的变量发生改变,那么所有类实例引用的变量都会一起发生改变。 3、static修饰的方法中不能使用this或super,static修饰的方法属于类的方法,而this或super只是对象的方法。 4、static修饰的方法不能引用非static修饰的变量,在类加载过程中,当static修饰的方法加载完成时,非static修饰的变量还未加载,所以无法引用非static修饰的变量。 5、非static修饰的方法可以引用static修饰的变量,在类加载过程中,static修饰的变量优先完成加载,所以当非static修饰的方法完成加载后可以引用static修饰的变量。 Final是一个修饰符: 当final修饰一个变量的时候,变量变成一个常量,它不能被二次赋值 当final修饰方法时,该方法不能被重写 当final修饰类时,该类不能被继承 Final不能修饰抽象类,因为抽象类中会有需要子类实现的抽象方法,(抽象类中可以有抽象方法,也可以有普通方法,当一个抽象类中没有抽象方法时,这个抽象类也就没有了它存在的必要) Final不能修饰接口,因为接口中有需要其实现类来实现的方法 Finally: Finally只能与try/catch语句结合使用,finally语句块中的语句一定会执行,并且会在return,continue,break关键字之前执行 finalize: Finalize是一个方法,属于java.lang.Object类,finalize()方法是GC(garbagecollector垃圾回收)运行机制的一部分,finalize()方法是在GC清理它所从属的对象时被调用的 三十六、Io流的层次结构 从流的方向 输入流输出流 从流的类型上 字符流字节流 inputstream和outputstream都是抽象类 它们下面的实现包括 FileInputStream,BufferedInputStream FileOutputStream,BufferedOutputStream reader和writer FileReader,BufferedReader,StringReader FileWriter,BufferedWriter,StringWriter,PrintWriter 三十七、JAVA: Java是面向对象的,跨平台的,它通过java虚拟机来进行跨平台操作,它可以进行自动垃圾回收的【c语言是通过人工进行垃圾回收】,java还会进行自动分配内存。【c语言是通过指定进行分配内存的】,只需要new一个对象,这个对象占用了多少空间,不需要我们来管,java虚拟机负责管这些,用完之后也不需要我们来释放,java虚拟机会自动释放 java是一种高级语言,简单,面向对象,多线程,高性能,安全。 java语言:数据结构+算法+内存管理 数据结构:数据在内存的分布方式 算法:解决问题的方式 内存的管理:内存的划分和释放 Java优点:简单、跨平台、多线程(线程、进程)、动态编译、类加载机制、垃圾回收机制 三十八、JavaSEJavaEEJavaME区别 是什么: JavaSE=JavaStandardEdition=j2se=java标准版 JavaEE=JavaEnterpriseEdition=j2ee=java企业版 JavaME=JavaMobileEdition=j2me=java移动版 特点: SE主要用于桌面程序(swing),控制台开发(main程序)。 EE企业级开发(JSP,EJB,SpringMVC,Struts,hibernate,ibatis等), 用于企业级软件开发,网络开发,web开发。 ME嵌入式开发(手机,小家电,PDA)。[苹果的ios,黑莓] 三者之间的关系: JavaSE(JavaPlatform,StandardEdition,Java标准版)就是基于JDK和JRE的。 JavaSE为JavaEE提供了基础。 JavaEE除了基于我们这个所谓的JavaSE外,还新加了企业应用所需的类库 三十九、JDKJREJVM的区别: Jdk【JavaDevelopmentToolKit】就是java开发工具箱,JDK是整个JAVA的核心里边包含了jre,它除了包含jre之外还包含了一些javac的工具类,把java源文件编译成class文件,java文件是用来运行这个程序的,除此之外,里边还包含了java源生的API,java.lang.integer在rt的jar包里边【可以在项目中看到】,通过rt这个jar包来调用我们的这些io流写入写出等 JDK有以下三种版本: J2SE,standardedition,标准版,是我们通常用的一个版本 J2EE,enterpsiseedtion,企业版,使用这种JDK开发J2EE应用程序 J2ME,microedtion,主要用于移动设备、嵌入式设备上的java应用程序 Jre【JavaRuntimeEnviromental】是java运行时环境,那么所谓的java运行时环境,就是为了保证java程序能够运行时,所必备的一基础环境,也就是它只是保证java程序运行的,不能用来开发,而jdk才是用来开发的,所有的Java程序都要在JRE下才能运行。 包括JVM和JAVA核心类库和支持文件。与JDK相比,它不包含开发工具——编译器、调试器和其它工具。 Jre里边包含jvm Jvm:【JavaVirtualMechinal】因为jre是java运行时环境,java运行靠什么运行,而底层就是依赖于jvm,即java虚拟机,java虚拟机用来加载类文件,java中之所以有跨平台的作用,就是因为我们的jvm 关系: J2se是基于jdk和jre, JDK是整个JAVA的核心里边包含了jre, 四十、报错的状态码: 301永久重定向 302临时重定向 304服务端未改变 403访问无权限 200正常 404路径 500内部错误 四十一、协议以及默认的端口号 ftp21文件传输协议 Smtp25简单邮件传输协议 oracle默认端口号1521 mysql默认端口号3306 四十二、抽象类与接口的区别 1.一个类只能进行单继承,但可以实现多个接口。 2.有抽象方法的类一定是抽象类,但是抽象类里面不一定有抽象方法; 接口里面所有的方法的默认修饰符为publicabstract,接口里的成员变量默认的修饰符为pulbicstaticfinal。 抽象类要被子类继承,接口要被类实现 接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量 关系 接口和接口继承 接口和抽象类抽象类实现接口 类和抽象类类继承抽象类 类和类继承 四十三、修饰符的作用 修饰符的作用范围: privatedefaultprotectedpublic 同一个类中可以可以可以可以 同一个包的类中可以可以可以 不同包的子类中可以可以 不同包的类中可以 四十四、onready和onload的区别 1.onready比onload先执行 2.onready是在页面解析完成之后执行,而onload是在页面所有元素加载后执行 3.onload只执行最后一个而onready可以执行多个。 Short,int,byte,char,String 四十六、request跟session的区别 1.他们的生命周期不同, request对应的是一次请求, session对应的是一次会话 2.request占用资源比较少,相对来说缺乏持续性, 而session资源消耗比较大,所以通常使用request来保存信息 四十七、找到解决svn冲突方法 对于svn冲突,可以采用手工处理将冲突的部分进行整合, 之后备份最新整合后的文件,采用覆盖更新的方式处理完 冲突之后,再把最新整合后的文件进行提交。 四十八、反射的描述 通过字符串可以动态创建java对象,并且可以动态访问方法, 属性等。 我们在项目中的时候封装过数据库jdbc的持久层, 其中就利用反射这项 技术来达到通用 和灵活的目的。 在启动时通过前端总控制器ActionServlet加载struts-config.xml并进行解析,当用户在jsp页面发送请求被struts1的核心控制器ActionServlet接收,ActionServlet在用户请求时将请求参数放到对应的ActionForm对象中的成员变量中,然后ActionServlet则会根据struts-config.xml中的映射关系找到相应的Action中的方法,将对应的ActionForm一并传给这个Action中的方法里,然后执行相应的业务逻辑操作,最后就根据ActionMapping的findforward方法返回一个ActionForward,之后在struts-config.xml中找到与之对应的forward标签,根据它的配置路径找到对应的jsp页面。 1、tomcat启动的时候会加载web.xml、核心控制器FilterDispatcher会加载并解析struts.xml 2、客户端会发送一个请求到action、FilterDispatcher会根据后缀名进行拦截 3、FilterDispatcher根据struts.xml的配置文件信息找到某个action对应的某个类里的指定方法 5、 1、客户端向Servlet容器(例如Tomcat)发送一个请求; 2、这个请求经过一系列的过滤器(Filter); 3、接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求是否需要调用某个Action; 4、如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy; 5、ActionProxy通过ConfigurationManager询问框架的配置文件,找到需要调用的Action类; 6、ActionProxy创建一个ActionInvocation的实例。 8、一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是jsp或者FreeMarker的模版。(体系结构图见下一页) 整个处理过程从一个HTTP请求开始: 2.DispatcherServlet接收到客户端请求,找到对应HandlerMapping,根据映射规则,找到对应的处理器(Handler)。 3.调用相应处理器中的处理方法,处理该请求后,会返回一个ModelAndView。 4.DispatcherServlet根据得到的ModelAndView中的视图对象,找到一个合适的ViewResolver(视图解析器),根据视图解析器的配置,DispatcherServlet将要显示的数据传给对应的视图,最后显示给用户。 Struts2以WebWork为核心, 采用拦截器的机制来处理用户的请求,struts1严重依赖于servletAPI, 属于侵入性框架,struts2不严重依赖于servletAPI,属于非侵入型框架。 线程模型方面: Struts1的Action是单实例的, 一个Action的实例处理所有的请求。 Struts2的Action是一个请求对应一个实例(每次请求时都新new出一个对象), 没有线程安全方面的问题 封装请求参数: Struts1中强制使用ActionForm对象封装请求的参数。 Struts2可以选择使用POJO类来封装请求的参数,或者直接使用Action的属性。 struts1的前端总控制器(核心总控制器)为ActionServlet, struts2的前端总控制器(核心总控制器)为FilterDispather 1.springmvc单例非线程安全 struts1单例非线程安全 struts2线程安全对每个请求都产生一个实例 2.springmvc的入口是servlet,而struts2是filter spring的前端总控制器为DispatcherServlet struts2的前端总控制器为FilterDispatcher struts1的前端总控制器为actionServlet 3.参数传递:struts是在接受参数的时候, 可以用属性来接受参数,这就说明参数是让多个方法共享的。 springmvc用方法来接受参数 4.springmvc是基于方法的设计,而sturts是基于类 1.dispatcher:它是默认的,用来转向页面,通常处理JSP 2.redirect:将用户重定向到一个已配置好的URL 3.redirectAction:将用户重定向到一个已定义好的action 4.chain:将action和另外一个action链接起来 5.freemarker:呈现Freemarker模板 7.stream:向浏览器发送InputSream对象对下载的内容和图片非常有用 8.velocity:呈现Velocity模板 9.xslt:该XML可以通过XSL模板进行转换 10.plaintext:显示原始文件内容,例如文件源代码 首先需要引用<%@taglibprefix="s"uri="/struts-tags"%> 1. 2. 3. 4. 5. 6. 7. 8. 最常用的是: 判断 循环 输出 1、Action继承于Actionsupport 2、引入struts-spring-plugin.jar包,从而完成struts和spring的整合 3、在struts2的action中注入service,保证service的名字和配置文件中的一致,并生成get,set方法 4、Dao层继承于SqlMapClientDaoSupport 5、在dao层的配置文件中注入sqlMapClient 1.首先在web.xml中通过ContextLoaderListener来融入spring, 请求并且加载struts.xml 3.action继承ActionSupport,然后通过引入struts-spring-plugin.jar 包并且根据配置文件中service的id生成get,set方法来注入service层。 4.dao层继承于HibernateDaoSupport,并且在dao的配置文件中注入sessionFactory. 5.通过spring中的配置文件加载hibernate.cfg.xml文件从而融入hibernate. 在ssh框架中是怎么整合spring 首先在web.xml中通过ContextLoaderListener来融入spring, 在ssh框架中是怎么整合hibernate 通过spring中的配置文件加载hibernate.cfg.xml文件从而融入hibernate dao层继承于HibernateDaoSupport,并且在dao的配置文件中注入sessionFactory 在ssh框架中是怎么整合struts2 1.首先,要在web.xml里面配置SpringMVC的核心控制器,DispatcherServlet,对指定的后缀请求进行拦截。 2.Controller层要加@Controller注解,表明该类是MVC的控制层。 3.创建Service接口,给接口加上注解@Component或者@Service表明这是Service业务处理层 5.在Controller层的方法上加上注解@RequestMapping("requestAddress")表明该方法的请求地址 6.Dao层要加上注解@Repository表明这是数据库持久层 7.同样将dao实例注入到service层中。 8.配置视图解析器"InternalResourceViewResolver",对处理后的跳转进行统一配置。 加载方式: load为延迟加载(返回的是一个只有id属性的代理,只有使用该对象属性时,才发出sql语句); get为立即加载(执行时,会立即向数据库发出sql语句) 返回结果: load检索不到记录时,会抛ObjectNotFoundException异常 get检索不到记录时,会返回null Hibernate属于全自动,Ibatis属于半自动,Jdbc属于手动,从开发效率上讲hibernate较高,ibatis居中,jdbc较低,从执行效率上讲hibernate较低,ibatis居中,jdbc较高,因为jdbc是手工写sql语句,程序员对sql的控制能力更大,可以根据业务需要进行优化,而ibatis虽然也可以对sql进行优化,但是他里面将resultset封装为实体的过程中采用了反射机制所以一定程度上影响了性能,而hibernate因为高度封装所以开发效率相对较高,但正因为这个原因,所以程序员在对sql语句的控制和优化方面相对比较弱,而且在将resultset封装成实体的过程中也采用了反射机制,所以在性能方面较低 首先通过configuration去加载hibernate.cfg.xml这个配置文件,根据 配置文件的信息去创建sessionFactory,sessionFactory是线程安全的, 是一个session工厂,用来创建session,session是线程不安全的,相当于 jdbc的connection,最后通过session去进行数据库的各种操作,在进行操作 的时候通过transaction进行事务的控制。 1.Configuration接口的作用是对Hibernate进行配置,以及对它进行启动。(加载hibernate.cfg.xml)并创建一个SessionFactory对象。 2.SessionFactory接口 SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。SessionFactory是线程安全的。 3.Session接口 Session(会话)接口是Hibernate应用使用的主要接口。Session接口负责执行被持久化对象的CRUD操作(增删改查)。Session对象是非线程安全的。Session相当于jdbc的connection 4.Query与Criteria接口 总之Query和Criteria接口负责执行各种数据库查询。 5.Transaction接口 1、hibernate和jdbc主要区别就是,hibernate先检索缓存中的映射对象(即hibernate操作的是对象),而jdbc则是直接操作数据库. 2、Hibernate是JDBC的轻量级的对象封装,它是一个独立的对象持久层框架。Hibernate可以用在任何JDBC可以使用的场合 3、Hibernate是一个和JDBC密切关联的框架,所以Hibernate的兼容性和JDBC驱动,和数据库都有一定的关系,但是和使用它的Java程序,和AppServer没有任何关系,也不存在兼容性问题。 4、如果正确的使用JDBC技术,它的执行效率一定比hibernate要好,因为hibernate是基于jdbc的技术. 5、JDBC使用的是SQL语句,Hibernate使用的是HQL语句,但是HQL语句最终还会隐式转换成SQL语句执行。 *.hbm.xml:主键生成策略,映射关系,一对多,一对一的关系。 Hibernate.cfg.xml:方言(用哪个数据库),数据库连接信息,包含*.hbm.xml内容,映射文件,也可以配事务。 开启事务session.beginTransaction(); 执行操作失败则session.getTransaction.rollback(); Transient(临时) new一个初始化对象后,并没有在数据库里保存数据,处于临时状态; Persistent(持久化) 当执行save()方法,调用session.close()方法之前,内存中的对象与数据库有对应关系处于持久化状态; Detached(托管/游离) 当执行session.close()之后,处于托管状态; 状态的转换 处于托管状态下,调用update()方法后,转换为持久化状态; 在持久化状态下,执行delete()方法后,转换为临时状态; 在未初始化对象之前,调用get(),load(),find(),iterate()之后,直接进入持久化状态。 ①前台封装一个显示分页的组件 ②查询总条数 ③后台封装分页工具类,计算开始位置、结束位置、总页数 ④后台写支持分页的sql语句 ⑤前台包含分页组件,实现分页效果 注意: 查询总条数的where和查询列表信息的where条件要保证一致。 hibernate分为一级缓存即session缓存也叫事务级别的缓存以及 二级缓存sessionFactory即应用级别的缓存,还有查询缓存即三级缓存. 一级缓存的生命周期和session的生命周期保持一致, hibernate默认就启用了一级缓存, 不能将其关闭,可以通过session.clear()和session.evict(object)来管理一级缓存。其中get,load,iterate都会使用一级缓存,一级缓存缓存的是对象。 二级缓存的生命周期和sessionFactory的生命周期保持一致,可以跨session,被多个session共享,hibernate3默认开启二级缓存,也可以手动开启并指定缓存插件如ehcache,oscache 等。二级缓存也只能缓存对象。 三级缓存也叫查询缓存,查询缓存是针对普通属性结果集的缓存, 对实体对象的结果集只缓存id。对query.list()起作用,query.iterate不起作用,也就是query.iterate不使用查询缓存 二十一、Ssh的概述: ssh是web开发中常见的一种框架 s-struts s-spring h-hibernate spring在ssh充当粘合剂,粘合struts-sping-hibernate,主要用来进行事物的控制, hibernate-充当数据库持久层,主要用它来与数据库交互,提高开发效率,减轻程序员sql控制要求,而且hibernate通过反射机制,有灵活的映射性,还支持各种关系,一对一,一对多,多对多。 在进行ssh整合的时候,我们应该注意: 1.Action继承于ActionSupport 引入struts-spring-plugin.jar包,从而完成struts和spring的整合 在struts2的action中注入service,保证service的名字和配置文件中的一致,并生成get,set方法 Dao层继承于hibernateDaoSupport 在dao层的配置文件中注入sessionFactory 二十二、防止表单重复提交 针对于重复提交的整体解决方案: 1.用redirect来解决重复提交的问题 2.点击一次之后,按钮失效 3.通过loading 4.自定义重复提交过滤器无奈 5.解决struts2重复提交 可以结合s:token标签来解决重复提交问题 利用token的原理: 1.在前端的jsp页面中加入s:token标签,在访问该页面时就会生成 隐藏域,该隐藏域中包含一个随机生成的字符串,并把该字符串 存入session中 2.在struts2的配置文件中加入token拦截器后,当正常访问action 的时候,会从session中取出该字符串,然后和页面隐藏域中提交 字符串做对比,如果一致则正常执行并删除session中存储的字符串。 二十三、JSP标签: JSP和servlet区别 jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类) jsp更擅长表现于页面显示,servlet更擅长于逻辑控制. Servlet中没有内置对象,Jsp中的内置对象都是必须通过HttpServletRequest对象,HttpServletResponse对象以及HttpServlet对象得到. Jsp是Servlet的一种简化,使用Jsp只需要完成程序员需要输出到客户端的内容,Jsp中的Java脚本如何镶嵌到一个类中,由Jsp容器完成。而Servlet则是个完整的Java类,这个类的Service方法用于生成对客户端的响应。 JSP是Servlet技术的扩展,本质上就是Servlet的简易方式。JSP编译后是“类servlet”。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。JSP侧重于视图,Servlet主要用于控制逻辑 1.JSPinclude动作 jsp:include动作 以“ 比如: 2.JSP指令:<%@include%><%@%> 以“<%@”开始,以“%>”结束。比如: <%@includefile="Filename"%> 3.JSP输出表达式:<%=%><%=Java表达式%> 输出变量的值,后边不能加<%=;%> 4.JSPScriptlet【脚本】:<%;%><%Java代码%> 例子: <%Calendarnow=Calendar.getInstance();%> <%! StringgetHello(Stringname){ return"Hi,"+name+"!"; %> 6.迭代标签: Jstl中的核心标签(core) 7.JSP注释: <%--这也是注释,但客户端不能查看到--%> 8.el表达式:${} 9.jsp:include动作是在运行时动态包含。 @include指令是在编译时包含。 如果要包含其他项目的文件可以使用c:import 二十四、过滤器 filter的概述: filter是一个过滤器,用来在请求前和响应后进行数据的处理。 filter的生命周期是: 实例化--->初始化(init)-->进行过滤(doFilter)--->销毁(destroy)-->释放资源 一个Filter必须实现javax.servlet.Filter接口 在项目中我们通常通过filter进行编码转换, 进行安全验证,进行重复提交的判断。 了解(不需要主动说) filter相当于拦截器相当于SpringAOP servlet+jsp+javabean+jdbc+filter 二十五、拦截器的理解 什么是拦截器: 拦截器是AOP中的概念,它本身是一段代码,可以通过定义“织入点”,来指定拦截器的代码在“织入点”的前后执行,从而起到拦截的作用 正如上面Struts2的Reference中讲述的,Struts2的Interceptor,其拦截的对象是Action代码,可以定义在Action代码之前或者之后执行拦截器的代码。 在项目中,我们经常用来拦截通过非正常程序而进行的访问 Struts2的拦截器和Servlet过滤器类似。在执行Action的execute方法之前,Struts2会首先执行在struts.xml中引用的拦截器,在执行完所有引用的拦截器的intercept方法后,会执行Action的execute方法。 其中intercept方法是拦截器的核心方法,所有安装的拦截器都会调用之个方法。在Struts2中已经在struts-default.xml中预定义了一些自带的拦截器,如timer、params等。如果在 拦截器是Struts2框架的核心,它主要完成解析请求参数、将请求参数赋值给Action属性、执行数据校验、文件上传等工作 在struts-default.xml中有一个默认的引用,在默认情况下(也就是 自定义拦截器需要特别注意的是不要忘记引入struts2默认的拦截器。为了实现某些操作,我们可以自定义拦截器, 自定义拦截器有三种方式定义。分别为实现Interceptor接口,继承抽象类AbstractInterceptor,继承MethodFilterInteceptor类。 拦截器在项目中的运用: 同时可以减轻代码冗余,提高重用率。 如果要求用户密码、权限等的验证,就可以用自定义的拦截器进行密码验证和权限限制。对符合的登入者才跳转到正确页面。 二十六、Spring融入框架 我们通过在web.xml中配置ContextLoaderListener这个监听器也加载 spring的配置文件,从而融入到项目框架中。 二十七、项目的部署方式 1、如果项目单独部署到tomcat中的时候,应该看tomcat中的server.xml; 2、如果和eclipse结合使用进行项目部署的时候,应该看eclipse里面的server.xml. 1、加载JDBC驱动程序: 通过Class类的forName方法实现,并将驱动地址放进去 成功加载后,会将Driver类的实例注册到DriverManager类中。 2、提供JDBC连接的URL、创建数据库的连接 要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象, 该对象就代表一个数据库的连接。 使用DriverManager的getConnectin()方法传入指定的欲连接的数据库的路径、数据库的用户名和密码。 Connectioncon=DriverManager.getConnection(url,username,password); &&&:"jdbc:mysql://localhost/testuser=root&password=123&useUnicode=true&characterEncoding=utf-8”; 3、创建一个Statement 要执行SQL语句,必须获得java.sql.Statement实例 执行静态SQL语句。通常通过Statement实例实现。 执行动态SQL语句。通常通过PreparedStatement实例实现。 Stringsql=“”; Statementst=con.createStatement(); PreparedStatementpst=con.prepareStatement(sql); 4、执行SQL语句 Statement接口提供了executeQuery、executeUpdate、execute三种方法 executeQuery:执行select语句,返回ResultSet结果集 ResultSetrst=pst.executeQuery(); executeUpdate:执行insert、update、delete语句 pst.executeUpdate(); 5、关闭JDBC对象 操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源。 数据库连接池的优点运行原理: 在我们不使用数据库连接池的时候,每次访问数据库都需要创建连接, 使用完成之后需要释放关闭连接,而这样是很耗费资源的。当我们使用 数据库连接池的时候,在tomcat启动的时候就创建了指定数量的连接, 之后当我们程序使用的时候就直接从连接池里面取,而不需要创建,同理, 当我们使用完的时候也不需要关闭连接,而是将连接返回到连接池中,供 其他请求继续使用。 DBCP:比较稳定。 C3P0:性能比较高。 配置: 首先找到mysql的安装目录,进入bin目录下复制路径 将mysql的bin目录粘贴在计算机环境变量的path中 将某张表的某个权限赋给某个用户 grant[select,insert,update,delete,create,drop]on[databaseName].[tableName]to[userName]@[userIP]identifiedby[‘连接口令’] grantselect,insert,update,delete,create,droponoa_ssh.usertoroot@[IP]identifiedby'root'; 将所有库的所有权限赋给某个用户 grantallprivilegeson*.*to[userName]@[userIp]identifiedby[‘连接口令’] grantallprivilegeson*.*toroot@[IP]identifiedby‘root'; 将所有库的所有权限赋给所有用户 grantallprivilegeson*.*toroot@'%'identifiedby‘root’; 导出本地数据库: mysqldump-u用户名-p数据库名>磁盘:导出的文件名(加后缀) 远程导出数据库: mysqldump-hIP-u用户名-p数据库名称>导出的文件名(加后缀) 远程导出数据表: mysqldump-uroot-p-d--add-drop-table数据库名称>导出文件 名(加后缀) 导入数据: 通过Map来解决性能问题。首先在分段批量提交的时候,我们不采用事务,这样就保证了合法的数据就自动提交,不合法的数据就自己自动进行回滚,为了避免不合法数据影响后续合法数据的提交,采用定义业务规则字典表,实现对数据的验证,将不合法的数据记录下来,供用户进行后续处理,而合法的数据就全部提交。 批量处理数据:(代码优化:提高程序执行性能) 降低了java程序代码(客户端)和数据库之间的网络通信的次数。 在jdbc中进行批量插入的核心API为addBatch,executeBatch 大数据量的插入问题:(jdbc,hibernate,ibatis) 2.批量插入和数据库只交互一次(内存溢出) 3.分段批量插入(推荐) jdbc批量处理数据是通过PreparedStatement对象的addbatch(),executebatch()clearbatch()进行和数据库的交互。通常我们使用分段批量处理的方式这样可以提高程序的性能,防止内存溢出。 1.每个sql语句都和数据库交互一次(非批量操作) 2.只和数据库交互一次(批量操作)(内存溢出) 当数据达到一定额度的时候就和数据库进行交互,分多次进行(分段批量操作) (500或者1000) pst.addBatch(); if(i>0&&i%1000==0){ pst.executeBatch(); pst.clearBatch(); select*from(select*from(selects.*,rownumrnfromstudents)wherern<=5)wherern>0 Oracle的基本数据类型(常用): 1、字符型 Char固定长度字符串占2000个字节 Varchar2可变长度字符串占4000个字节 Nvarchar2占2000个字符(最多能存2000个字母/中文) 2、大对象型(lob) Blob:二进制数据最大长度4G Blob用于存一些图片,视频,文件。 比如:当我们在进行文件上传时,我们一般把上传的文件存在硬盘上,可以不占用数据库,下载时,如果项目迁移时,文件也要跟着迁移。因此我们可以把用blob把它存在数据库中。但这样也增加了数据库的负担。 Clob:字符数据最大长度4G,可以存大字符串varchar2和nvarchar2都具有一定的局限性,它们长度有限,但数据库中无论用varchar2或nvarchar2类型,还是用clob,在java端都使用String接收。 3、数值型 Integer整数类型,小的整数。 Float浮点数类型。 Real实数类型。 Number(p,s)包含小数位的数值类型。P表示精度,s表示小数后的位数。 Eg:number(10,2)表示小数点之前可有8位数字,小数点后有2位。 4、日期类型 Date日期(日-月-年)DD-MM-YY(HH-MI-SS) Timestamp跟date比它可以精确到微秒。精确范围0~9默认为6. rowid物理位置的唯一标识。 而id是逻辑上的唯一标识,所以rowid查找速度要快于id,是目前最快的 定位一条记录的方式 rowid和rownum都是"伪数列" 所谓“伪数列”也就是默认隐藏的一个数列。 rownum用于标记结果集中结果顺序的一个字段, 它的特点是按顺序标记,而且是连续的, 换句话说就是只有有rownum=1的记录,才可能有rownum=2的记录。 rownum关键字只能和<或者<=直接关联 如果是>或者=则需要给他起个别名 在创建主键的同时会生成对应的唯一索引,主键在保证数据唯一性的同时不允许为空,而唯一可以有一个为空数据项,一个表中只能有一个主键,但是一个主键可以有多个字段,一个表中可以有多个唯一索引。 用Preparedstatement进行开发。Preparedstatement是预编译的,而statement不是,在每次执行sql语句的增删改时,如果是一条数据两者没差距,但如果数据量大于1,那么每次执行sql语句statement都要重新编译一次,而Preparedstatement不用,Preparedstatement的运行效率大于statement;从代码的可维护性和可读性来说,虽然用Preparedstatement来代替statement会使代码多出几行,但这样的代码无论从可读性还是可维护性来说,都比直接使用statement的代码高很多档次;最重要的一点,从安全角度来说,使用Preparedstatement可以大大提高程序的安全性,因为Preparedstatement是用‘?’传参,可以防止sql注入,具有安全性,而statement用的是‘+’字符串拼接,安全性较低。 第一范式:数据库表中的所有字段值都是不可分解的原子值。 视图可以视为“虚拟表”或“存储的查询” 创建视图所依据的表称为“基表” 视图的优点: 提供了另外一种级别的表安全性:隐藏了一些关键的字段 简化的用户的SQL命令 隔离基表结构的改变 存储过程(StoredProcedure) 可以包含逻辑判断的sql语句集合。 是经过预编译,存在于数据库中。 通过调用指定存储过程的名字(可有参,可无参)来执行。 优点: 简化了复杂的业务逻辑,根据需要可重复使用 屏蔽了底层细节,不暴露表信息即可完成操作 降低网络的通信量,多条语句可以封装成一个存储过程来执行 设置访问权限来提高安全性 提高执行效率,因为它是预编译以及存储在数据库中 缺点: 可移植性差,相同的存储过程并不能跨多个数据库进行操作 大量使用存储过程后,首先会使服务器压力增大,而且维护难度逐渐增加 存储过程的语法: --下面是在oracle数据库下最基本的语法 --仅创建一个名为testProcedure的无参的存储过程 --IS也可以是AS --如果已经存在名为testProcedure的存储过程,下面的语法会出现名称已被使用的错误 --解决办法: --第一句可以写成createorreplaceproceduretestProcedure --这样会替换原有的存储过程 --NULL表示任何可以正确执行的sql语句,但至少一句 createproceduretestProcedure IS BEGIN NULL END; 存储过程的参数的分类: IN OUT INOUT 注意: 存储过程之间可相互调用 存储过程一般修改后,立即生效。 1、索引的概念 索引就是为了提高数据的检索速度。 数据库的索引类似于书籍的索引。 在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息。 在数据库中,索引也允许数据库程序迅速地找到表中的数据, 而不必扫描整个数据库. 2、索引的优点 1.创建唯一性索引,保证数据库表中每一行数据的唯一性 2.大大加快数据的检索速度,这也是创建索引的最主要的原因 3.减少磁盘IO(向字典一样可以直接定位) 3、索引的缺点 2.索引需要占用额外的物理空间 3.当对表中的数据进行增加、删除和修改的时候, 索引也要动态的维护,降低了数据的维护速度 4、索引的分类 1.普通索引和唯一性索引 普通索引:CREATEINDEXmycolumn_indexONmytable(myclumn) 唯一性索引:保证在索引列中的全部数据是唯一的 CREATEuniqueINDEXmycolumn_indexONmytable(myclumn) 2.单个索引和复合索引 单个索引:对单个字段建立索引 复合索引:又叫组合索引,在索引建立语句中同时包含多个字段名, 最多16个字段 CREATEINDEXname_indexONuserInfo(firstname,lastname) 3.顺序索引,散列索引,位图索引 1:oracle分页 select*from(selectt.*,rownumrnfrom(select*frommenuorderbyiddesc)twhererownum<10)wherern>=5 2:mysql分页 select*frommusicwhereidlimit5,5 3:oracle中如何快速将一张表的数据复制到另外一张表中(另外一张表不存在,另外一张表存在,但数据为空) 1、.不存在另一张表时: createtable新表asselect*from将要复制的表 2、存在另一张表时: insertinto新表名select字段from将要复制的表名 4:音乐专辑 查询出special Selects.id,min(s.sname),count(m.mid)fromspecialsinner joinmsmons.id=m.idgroupbys.id 5:快速删除一张表(不可事物回滚,也就是没有日志记录) TRUNCATEfrom表名 6:innerjoin select查找信息from表名1innerjoin表名2on表名1.列名=表名2.列名 7:leftjoin 左外连接select查找信息from表名1leftjoin表名2on表名1.列名=表名2.列名 8:rightjoin 右外连接select查找信息from表名1rightjoin表名2on表名1.列名=表名2.列名 9:oracle中查询遍历树形结构(startwith) select*fromextmenu startwithpid=1 connectbypriorid=pid 快速删除父节点以及父节点下的所有节点: Deletefromextmenuwhereidin( elect*fromextmenu ) 10:查询出来60-70,80-90,95-100学生的信息 select*fromstuwherechengjibetween60and70orbetween80and90orbetween95and100 select*fromstuwherechengji>60andchengji<70orchengji>80andchengji<90orchengji>95andchengji<100 11:用exists替换in------进行联表查询 select*fromdeptwhereexists(select*fromempwhereemp.deptno=dept.deptno); 或 select*fromdeptdinnerjoinempeond.deptno=e.deptno(只查询出两表共同拥有的字段数据) 12:删除表中的重复数据: deletefromxinawherea.rowid!=( selectmax(b.rowid)fromxinb wherea.name=b.name ); 13:row_number(),rank()over,dense_rank()over按工资排序 selectsal, row_number()over(orderbysaldesc)rank1, rank()over(orderbysaldesc)rank, dense_rank()over(orderbysaldesc)drank fromemp 14:select*from(selectemp.*from( dense_rank()over(partitionbydepartNoorderbysaldesc) rkfromemp) Whererk=4 十六、ibatis批量 this.getSqlMapClientTemplate().execute( newSqlMapClientCallback(){ publicObjectdoInSqlMapClient( SqlMapExecutorexecutor) throwsSQLException{ executor.startBatch(); for(inti=0,n=list.size();i executor.insert( "productAttach.insertProductAttach", list.get(i)); executor.executeBatch(); returnnull; }); ibatis,jdbc,hibernate的分段的实现: 都应该在组装list的时候进行拆分(如:action层加入) if(list.size()%1000==0) { productAttachService.addBatch(list); list.clear(); if(list.size()>0) Spring是完全面向接口的设计,降低程序耦合性,主要是事务控制并创建bean实例对象。在ssh整合时,充当黏合剂的作用。IOC(InversionofControl)控制反转/依赖注入,又称DI(DependencyInjection)(依赖注入) IOC的作用:产生对象实例,所以它是基于工厂设计模式的 SpringIOC的注入 通过属性进行注入,通过构造函数进行注入, 注入对象数组注入List集合 注入Map集合注入Properties类型 SpringIOC自动绑定模式: 可以设置autowire按以下方式进行绑定 按byType只要类型一致会自动寻找, 按byName自动按属性名称进行自动查找匹配. AOP面向方面(切面)编程 AOP是OOP的延续,是AspectOrientedProgramming的缩写, 意思是面向方面(切面)编程。 注:OOP(Object-OrientedProgramming)面向对象编程 AOP主要应用于日志记录,性能统计,安全控制,事务处理(项目中使用的)等方面。 Spring中实现AOP技术: 在Spring中可以通过代理模式来实现AOP 代理模式分为 静态代理:一个接口,分别有一个真实实现和一个代理实现。 动态代理:通过代理类的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联。 动态代理有两种实现方式,可以通过jdk的动态代理实现也可以通过cglib 来实现而AOP默认是通过jdk的动态代理来实现的。jdk的动态代理必须要有 接口的支持,而cglib不需要,它是基于类的。 SpringAOP事务的描述: 在spring-common.xml里通过 Spring实现ioc控制反转描述: 原来需要我们自己进行bean的创建以及注入,而现在交给 spring容器去完成bean的创建以及注入。 所谓的“控制反转”就是对象控制权的转移, 从程序代码本身转移到了外部容器。 官方解释: 控制反转即IoC(InversionofControl), 它把传统上由程序代码直接操控的对象的调用权交给容器, 通过容器来实现对象组件的装配和管理。 所谓的“控制反转”概念就是对组件对象控制权的转移, 在数据库中,所谓事务是指一组逻辑操作单元即一组sql语句。当这个单元中的一部分操作失败,整个事务回滚,只有全部正确才完成提交。 判断事务是否配置成功的关键点在于出现异常时事务是否会回滚 事务的ACID属性 1.原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生, 要么都不发生。 2.一致性(Consistency) 事务必须使数据库从一个一致性状态变换到另外一个一致性状态。(数据不被破坏) 3.隔离性(Isolation) 事务的隔离性是指一个事务的执行不能被其他事务干扰. 4.持久性(Durability) 持久性是指一个事务一旦被提交, 它对数据库中数据的改变就是永久性的.即使系统重启也不会丢失. 在JDBC中, 事务默认是自动提交的, 每次执行一个SQL语句时,如果执行成功, 就会向数据库自动提交,而不能回滚 为了让多个SQL语句作为一个事务执行: (1)执行语句前调用Connection对象的setAutoCommit(false); 以取消自动提交事务 (2)在所有的SQL语句都成功执行后,调用commit();方法提交事务 (3)在出现异常时,调用rollback();方法回滚事务。 权限涉及到5张表: 用户表,角色表,权限表(菜单表),用户角色关联表,角色权限关联表 id集合,之后根据角色id再到角色权限关联表中获取该角色所拥有的权限id集合, 然后再根据权限id集合到权限表(菜单表)中获取具体的菜单,展现给当前 我们通过ZTree来给角色赋权并且通过ZTree来展示菜单,以及通过ZTree来管理菜单即增加和编辑菜单。 在我以前的项目中,我们考虑了系统性能问题,这个时候我们采用了Oscache缓存,刚开始把这个功能交给了项目组中的另外一个同事来做的,但是他做完的时候他发现缓存中明明已经缓存了数据,但是在取得时候发现没有数据,我们项目经理让我去帮忙看看这个问题,我阅读完他的代码之后,我发现了他每次缓存的时候都是调用一个新的缓存对象的方法,结果出现了明明已经走了缓存的方法而取不到数据的问题,通过我多年的工作经验,我就想到了应该用单例模式去封装一个单例工具类来调用oscache。但是,在后来的测试过程中,发现当并发访问的时候也会出现上述的问题,这个时候我直接采取的DCL(双重判定锁)单例模式封装了工具类,既解决了线程安全问题,相对的性能问题也考虑到了,这个问题才得到了完善的解决。 线程的状态以及状态之间的相互转换: 1、新建状态(New):新创建了一个线程对象。 2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。 3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。 4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种: (一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。 (二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。 (三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。 5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。 实现线程的两种方式: 是继承Thread类或实现Runnable接口,但不管怎样,当new了这个对象后,线程就已经进入了初始状态 wait和sleep的区别: 线程访问: 锁池状态,之后等待锁释放,然后访问代码 wait 等待队列(释放资源)--->调用notify或者notifyall之后锁池状态--->(等待锁释放)--->可运行状态--->运行状态---->访问代码 sleep,join 不释放资源-->结束后直接进入可运行状态--->运行状态---->访问代码 一个java控制台程序,默认运行两个线程,一个主线程,一个垃圾回收线程。 线程与进程的区别: 1.线程(Thread)与进程(Process) 我在做项目时有时会遇到session超时问题,如果session超时,平常请求没有什么问题,通过拦截器可以正确跳到登陆页面,可是你如果用ajax请求的话这就出现问题了,因为ajax是异步的,局部刷新,所以登陆界面不会再全页面中显示,他只会显示到页面的一部分当中。所以根据我这几年的经验找到了我认为比较好的一种方法。因为那我用的框架是和struts2集成的,所以就在拦截器中进行设置: 首先判断session是否为空就是判断session是否超时,如果超时就取出请求的head头信息request.getHeader("x-requested-with"),如果不为空就和XMLHttpRequest(Ajax标识)进行比较(request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")))如果相等说明此请求是ajax请求。 如果是ajax请求就可以用response.setHeader("键","值")来设置一个标识来告诉用户这是ajax请求并且session超时时发出的,这样我就可以在回调函数中取出自己设置的那个唯一标识:XMLHttpRequest.getResponseHeader("");如果取出的值是和自己在后台中设置的值一样的话,就证明session已经超时,这样就可以设置window.location.replace("登陆界面"),来跳转到登陆界面了。 这样做虽然解决了问题,但是,会在每个回调函数中写入那些代码,这样的话代码就会显得特别零散,所以就想能不能定义一个全局的设置所以就找到了jqery的ajaxSetUp方法,通过ajaxSetUp对jqery的ajax进行全局的判断(ajaxSetUp就相当于ajax的拦截器),通过设置ajaxSetUp里的complete,它就相当于回调函数,这样那就弥补了上一方法的不足。 我做项目时还用到$(document).ajaxStart(),这是ajax请求时的事件;$(document).ajaxSuccess(),这是AJAX请求成功后的事件。我一般用他们来显示遮罩层和隐藏遮罩层用的加遮罩层是为了不让用户重复提交,更提高了用户体验度,让用户知道已经提交了。 java线程池的工作原理和数据库连接池的差不多,因为每次重新创建线程 都是很耗资源的操作,所以我们可以建立一个线程池,这样当需要用到线程 进行某些操作时,就可以直接去线程池里面找到空闲的线程,这样就可以直接 使用,而不用等到用到的时候再去创建,用完之后可以把该线程重新放入线程池 供其他请求使用从而提高应用程序的性能。 线程池的核心流程: 1.构建一个ThreadPoolExecutor并指定默认要创建的线程的数量 2.通过threadPool.execute() 去添加一个个要执行的线程即实现了Runable接口的java类 3.在实现了Runable接口的java类的run方法中写入具体的业务代码 线程池的业务场景: 我在工作的时候,当时一个同事给我提了一个需求,目前有大量的图片 需要处理生产缩略图并进行加水印,因为按照普通的处理方法一个个的 进行处理太慢了,问我有没有好的解决方案,这个时候我就想到了java中 的线程池,我构建了一个线程数为5个线程池,然后采用分段批量提取的 方式每500条为一组数据进行图片信息的提取,然后再把这些通过Threadpool的 execute方法交给线程池中的线程进行处理,即充分使用了CPU硬件资源又加快 了大数据情况下程序的处理效率。 我当时在工作的过程中,认识一个做电商的朋友,他们当时公司才起步,很多 技术都不成熟,所以就常常和我探讨一些技术问题,有次他向我请教一个问题, 问我如何才能提高网站的性能,我根据自己在项目中的经验以及自己以前阅读的 关于优化方面的资料给他提出了很多建议,如用lucene进行全文检索,用memcached 进行分布式缓存,以及通过spring定时器结合freeMarker模板引擎来生成静态 页面,由于要生成的页面的数量比较多,考虑到程序的性能,我建议他结合 java的线程池进行工作,这样就可以充分使用了CPU硬件资源又加快 oscache是一个高性能的j2ee框架,可以和任何java代码进行集成,并且还可以通过标签对页面内容进行缓存,还以缓存请求。 我们通常将那些频繁访问但是又不是经常改变的数据进行缓存。为了保证缓存数据的有效性,在数据发生改变的时候,我们要刷新缓存,避免脏数据的出现。刷新缓存的策略有两种,一种是定时刷新,一种手动刷新。 缓存数据的时机通常也分为两种,即在tomcat(web容器)启动时候加载数据进行缓存,另外也可以在用户第一次访问数据的时候进行缓存,这个相当于缓存的立即加载和按需加载。 缓存的层次如下:jsp-->action-->service-->dao,缓存越靠前对性能的提升越大 一个action里面可以有多个service,一个service中可以有多个dao或者多个service 应用程序为了提高性能,可以通过使用缓存来达到目的,缓存的存储介质可以 内存或者硬盘,通常将数据存储在内存里,确切的说是jvm的内存中,缓存是 基于Map这种思想构建的,以键值对的方式进行存取,之所以还可以将 缓存的数据存储在硬盘中,是因为内存资源相当有限和宝贵,所以当内存资源 不足的时候,就可以将其存储到硬盘中,虽然硬盘的存取速度比内存要慢,但是 因为减少了网络通信量,所以还是提高程序的性能。缓存可以分为客户端缓存和 服务器端缓存,所谓的客户端缓存通常指的是IE浏览器的缓存,服务器端缓存指 的web服务器的缓存,通常可以通过第三方组件实现,如oscache,memcache 我们通常将那些频繁访问但是又不是经常改变的数据进行缓存。为了保证缓存数据的 有效性,在数据发生改变的时候,我们要刷新缓存,避免脏数据的出现。刷新缓存的 策略有两种,一种是定时刷新,一种手动刷新。 缓存的层次如下:jsp-->action-->service(通常放置在service)-->dao, 缓存越靠前对性能的提升越大 缓存的策略:(缓存空间不足需要进行清理的时候使用) LRU:最近最少使用原则.(理解:存储书) FIFO:先进先出的缓存策略.(理解:排队) 你来说说缓存?说说你对缓存的理解(如果遇到重复的,就可以省略) 我们在项目中使用缓存的目的是为了提高应用程序的性能,减少访问数据库 的次数,从而提高应用程序的吞吐量。我们通常将权限,菜单,组织机构 这些频繁访问但是不经常改变的基础数据进行缓存,其中我在做()某某项目的时候 就通过oscache对ZTree的树形菜单进行了缓存,并且在做的时候和单列设计 模式进行结合,考虑到多线程下的安全问题,还对单例模式加入了双重判定锁 的检查方式。 servlet是单列的,对于所有请求都使用一个实例,所以如果有全局变量被多 线程使用的时候,就会出现线程安全问题。 解决这个问题有三种方案: 1.实现singleThreadModel接口,这样对于每次请求都会创建一个新的servlet实例,这样就会消耗服务端内存,降低性能,但是这个接口已经过时,不推荐使用。 2.可以通过加锁(synchroniezd关键字)来避免线程安全问题。这个时候虽然还是单列,但是对于多线程的访问,每次只能有一个请求进行方法体内执行,只有执行完毕后,其他线程才允许访问,降低吞吐量。 3.避免使用全局变量,使用局部变量可以避免线程安全问题,强烈推荐使用此方法来解决servlet线程安全的问题。 JPBM是JBOSS旗下的一个开源的基于hibernate的工作流引擎。工作流就是在日常生活中,我们一些常见的如请假流程、采购流程、入职流程,通俗的来讲就是一些在现实生活中的流程以信息化以程序的方式实现。 一个工作流首先需要进行流程定义,流程定义是由节点和跳转组成的,节点又可以称为环节、活动节点、活动环节,并且节点也可以分为两大类型:人工节点和自动节点,人工节点有start开始节点、end结束节点、task任务节点,自动节点有decision判断节点、fork分支节点、join聚合节点和state状态节点,并且一个流程有且只有一个开始节点,但可以有多个结束节点。 流程定义是静止的,它在运行状态时会转换成流程实例,一个流程定义可以对应多个流程实例。流程运行后,会产生两个文件,*.jdpl.xml文件和*.png图片文件,也会生成18张数据库表,常用且核心的表有JBPM4_LOB存储表,主要存储xml文件和png图片、JBPM4_TASK任务表、JBPM4_EXECUTION流程实例表、JBPM4_VARIABLE变量表。 图形化的灵活定制(主动说) 可以根据需求进行流程图的改变的,即定义的流程图是可以根据需要改变的,而不是死的。 可以进行图形化的监控(主动说) 输出图片 获取活动节点的坐标 进行叠加 判断节点:(主动说,也可以了解) 实现implementsDecisionHandler接口并重写decide方法, 返回的字符串要和xml中配置的transition的name保持一致。 分支判定节点 JBPM有五大核心类: ProcessEngine:主要获取各种的Service RepositoryService:主要发布流程定义 ExecutionService:主要操作流程实例 TaskService:主要操作人工服务 HistoryService:主要操作历史服务。 核心方法: 读取jbpm定义的文件生成zip包存到lob表中:createDeployment() 获取流程定义列表:createProcessDefinitionQuery 根据定义的key或id来启动流程实例:startProcessInstanceByKey(id) 获取待办任务列表:findPersonalTasks(userName) 完成指定任务列表:completeTask(*.getActivityId()) 获取历史任务列表:createHistoryTaskQuery() 获取流程实例的ID:task.getExecutionId() (了解的表) JBPM4_HIST_ACTINST流程活动(节点)实例表 JBPM4_HIST_DETAIL流程历史详细表 JBPM4_HIST_PROCINST流程实例历史表 JBPM4_HIST_TASK流程任务实例历史表 JBPM4_HIST_VAR流程变量(上下文)历史表 首先进行请假的流程定义,我们流程的定义是(员工提交请假单---》经理审批---》总监审批---》总经理审批---》结束),通过repositoryService将其发布部署到jbpm4_lob表中, Ant是apache旗下的对项目进行自动打包、编译、部署的构建工具,他主要具有轻量级并且跨平台的特性,而且基于jvm,默认文件名为build.xml Ant主要的标签: Project根标签, target任务标签, property属性标签,自定义键/值供多次使用, java执行编译后的java文件 javac编译java文件 war打成war包 其它标签:copy,delete,mkdir,move,echo等。 FreeMarker是一个用Java语言编写的模板引擎,它是基于模板来生成文本输出的通用工具。Freemarker可以生成HTML,XML,JSP或Java等多种文本输出。 工作原理:定义模板文件,嵌入数据源,通过模板显示准备的数据 (数据+模板=输出) 我们在使用模板中发现freemarker具有许多优点,它彻底的分离表现层和业务逻辑,模板只负责数据在页面中的表现,不涉及任何的逻辑代码,所以使得开发过程中的人员分工更加明确,作为界面开发人员,只需专心创建HTML文件、图像以及Web页面的其他可视化方面,不用理会数据;而程序开发人员则专注于系统实现,负责为页面准备要显示的数据。 (主动说) webservice是SOA(面向服务编程)的一种实现, 主要是用来实现异构平台通信也就 是不同平台不同项目之间的数据传输,从而避免了信息孤岛的问题, 它之所以能够 进行异构平台通信是因为它是完全基于xml的, 所以说,webService是跨平台, 跨语言,跨框架的,在java中通常有三种技术框架分别是xfire,cxf,axis2。 我们为了保证 webservice的安全性,采用了基于 WS-Security标准的安全验证(使用回调函数)。 (没必要主动说) webservice的三要素分别是: wsdl(webservicedescriptionlanguage) 用来描述发布的接口(服务) soap(simpleobjectaccessprotocol) uddi用来管理,查询webService的服务 webservice的具体三种实现方式(框架)或者三种实现框架的区别 1.Axis2:可以用多种语言开发, 是一个重量级框架,功能非常强大, 但是它的性能比较低。 2.Xfire:它相比Axis2来说是一个轻量级框架, 它的性能要比Axis2高。 3.cxf:是Xfire的升级版,就好比是, struts2是webwork的升级, 然后cxf和spring集成起来非常方便,简易, 性能方面也要比Xfire高。 【注】jdk6自带的webservicejws 业务场景 我在以前做项目的时候,其中遇到一个功能, 需要进行两个项目之间的数据的传输, 项目经理让我去完成这个任务,我根据以往的项目经验, 想到两种解决方案,第一种 就是开放另外一个项目的数据库的权限给我, 然后我直接通过访问另外一个项目的数据 库,来得到需要的信息,但后来我分析了下,觉的这种方式不安全, 而且因为当时 这个项目是另外一家公司负责在做,所以数据库里面的表结构, 以及以后牵涉 到的责任问题都很多,所以我就采用了第二种方案, 即通过webservices的方式,进行 异构系统之间数据信息的传递,webservices的具体实现, 有xfire,cxf,axis2, 我根据以往的项目经验,了解到cxf是xfire的升级版本,适用于java语言, xfire/cxf性能比axis2要高,并且和spring整合起来也比较方便, 而axis2支持更多的语言, 性能相对于cxf要低,通过上面分析, 结合我们目前的两个项目都是基于java 语言的,所以我采用cxf这种方式实现了两个项目之间数据的传递, webservice的安全性我们采用了基于 WS-Security标准的安全验证(使用CXF回调函数)。 webservice服务端配置流程 首先在web.xml中引入cxfServlet核心类, 指定对以/cxf开头的url路径提供webservice服务, 之后我们在要发布成webservice接口上添加@Webservice注解, 而且还要在实现类上添加同样的webservice注解并且要说明实现了哪个接口, 之后在spring-webservice.xml中发布webservice服务, 通过jaxws:endpoint这个标签, 并且在标签配置implementor和address来表明实现服务的类, 以及发布的地址, webservice客户端的配置 首先通过wsdl2java根据发布的webservice服务端地址的wsdl 生成客户端调用的中间桥梁java类, 将生成的java类拷贝到客户端项目中, 配置spring-client.xml文件, 通过jaxws:client定义一个bean, 并通过address属性指明要访问的webservice的服务地址, 通过serviceClass指明充当中间桥梁的服务类,之后获取该bean, 就可以通过它来访问发布的webservice接口中的方法。 存储过程就是封装一些sql的集合,也就是一条条的sql语句,过程的优点就是简化了sql命令加上它是预编译的,所以它的执行效率和性能较高,再者,如果不调用过程的话就要和数据库发生多次交互,调用过程只需传一个命令所有的那些执行逻辑都在数据库端执行,所以说它降低了网络的通信量,其次,存储过程大大提高了安全性,这就是优点 缺点呢,就是不同的数据库对过程支持的关键字支持的关键字都是不一样的,所以它的移植性是非常差的,再者,它的维护性难度也比较大,因为它没有专业的调试和维护工具,所以说它维护起来比较麻烦,这就是存储过程的基本概述. 当我们tomcat访问量大,线程连接数不够时,我们考虑到了tomcat的负载均衡来分担过多的访问.性能方面负载均衡也能利用多台tomcat来增大内存量, 我们在做这个项目时,我们考虑到服务器性能的问题,我们最开始想到使用纵向扩展,来增加硬件的配置提高其性能,但这样做比较耗费资金,而且服务器内存空间也是有限的;所以后来就想到使用横向扩展来达到这一目的 当时我们的apache是通过jk借助于ajp协议与tomcat进行通信的,在我们不进行负载均衡之前,那所有的请求都由一台tomcat进行处理,这样会使我们的tomcat所承受的压力增大,而我们进行负载均衡之后,同样数量的请求经过apache和jk将其分发到多台tomcat进行处理,从而降低每台tomcat所承受的压力,而且当其中一台机器宕机时,其他机器还可以继续提供服务,保证服务不间断。 在这个过程中,我们遇到了session问题,然后我此昂到用session复制来解决这个问题; 在apache的配置文件中增加session粘带特性: worker.lb.sticky_session=1 worker.lb.sticky_session_force=0 Tomcat的配置 修改server.xml文件: 增加jvmRoute=”tomcat2”*.jvmRoute赋的值为worker.properties中配置的相应的server名一致 修改应用的web.xml文件 在应用中的web.xml文件中增加 如果这样做,当第一次访问的时候,会把所以数据全部缓存到第一台服务器上,通过web配置文件,会把第一台缓存的数据全部复制到第二胎服务器上,这样做就加大网路通信量,导致阻塞,所以我们就想到了可以通过memcached分布式缓存来存取session从而解决上述问题。 Ant是基于java语言编写的,因此具有跨平台的特性,此外还具有简洁方便,灵活 配置的特性,因此我就在XX项目中使用ant进行项目的编译,打包,部署操作。使用ant 之后,如果我们在客户那里修改代码后,就可以直接使用ant进行编译,打包,部署,而不需要为了编译,打包,部署专门在客户那里安装eclipse.此外使用ant也可以直接和svn进行交互,下载源码的同时进行编译,打包,部署。 maven业务场景 maven可以进行包的依赖管理,保证jar包版本的一致性,以及可以使多个项目共享 jar包,从而能够在开发大型j2ee应用的时候,减小项目的大小,并且和ant 比起来,maven根据“约定优于配置”的特性,可以对其项目的编译打包部署进行了 更为抽象的封装,使得自己不需要像ant那样进行详细配置文件的编写,直接使用 系统预定好的mvnclean,compile,test,package等命令进行项目的操作。于是我就 于是我就采用nexus搭建了在局域网内的maven私服,然后通过配置settings.xml中 建立mirror镜像,将所有下载jar包的请求都转发到maven私服上,之后通过在pom.xml 即(projectobjectmodel)中配置项目所依赖的jar包,从而达到在构建项目的时候, 先从本地仓库中查找,如果不存在从内部私服查找,如果不存在最后再从外网central 服务器查找的机制,达到了节省下载带宽,提高开发效率,以及jar包重用的目的。 ant业务场景 ant是基于java语言编写的,因此具有跨平台的特性,此外还具有简洁方便,灵活 之后,如果我们在客户那里修改代码后,就可以直接使用ant进行编译,打包,部署, 而不需要为了编译,打包,部署专门在客户那里安装eclipse.此外使用ant也可以 直接和svn进行交互,下载源码的同时进行编译,打包,部署。 maven的常用命令 mvneclipse:cleaneclipse:eclipse-Dwtpversion=2.0 mvncleanpackage maven的生命周期是独立的,但是生命周期下的阶段是相互关联并且延续的。 maven的生命周期 clean(清理):clean;default(默认):compile,test,packageinstall;site(站点) 第一种,继承SingleThreadModel但是这样每次都会创建一个新的servlet实例,但这样消耗服务器的内存,降低了性能,并且这个接口现在已经过时了,不推荐使用。 第二种:我们尽量避免使用全局变量,就我个人而言,我比较喜欢使用这种方法。 第三种,我们可以通过使用ThreadLocal,内部结构是一个Map结构,用当前线程作为key,他会创建多个副本。get,set方法 第四种,我们当然还可以来加锁,进行解决线程问题。 而且我还知道,向我们这种常用的MVC框架,struts1,spring这些MVC框架,都是基于servlet发展而来的,就比如struts1的核心总控制器是ActionServlet,而springMVC的前端总控制器是dispatchServlet,在项目我们曾经用serlet来生成图片验证码的,防止用户进行暴力破解 (别人问了,再回答) servlet的配置文件web.xml 描述: 我在web.xml中,我首先需要写一个servlet标签,servlet标签中有两个子标签,一个叫servlet-name,这个name可以随便起,但是要保证唯一性,除此之外,在这个servlet-name下有一个servlet-class,这个servlet-class对应的就是我后台提高服务的servlet,除此之外还有一个servlet-mapping,这个里边首先有一个servl-name。,这个servl-name首先要保证和上边的servlet-name保持一致,除此之外还有一个url-pattern,这是一个虚拟路径,是用来发送请求的url地址 二十五、bugfree的操作步骤 Bug的三种状态:未解决(Active)(测试人员)、已解决(Resolved)(开发人员)、关闭(Closed)(测试人员) 二十六、Axis2的配置 axis2服务端配置流程 services-->自定义文件夹名-->META-INF-->servies.xml 3.在servies.xml中配置service的name以及对应的springBeanName 4.在浏览器中输入webservice的服务端地址并加上wsdl来进行测试,看 是否发布成功 axis2客户端配置流程 1.通过wsdl2java根据webservice服务端的url生成客户端代码 2.将代码引入项目的文件夹中进行正常访问 二十六、spring定时器 1.建立一个triggers触发器集合 3.通过targetObject以及targetMethod找到要执行的具体类的具体方法 目标对象是一个普通的java类 1.建立一个triggers触发器集合. 2.建立CronTriggerBean指定cron表达式以及要执行的目标 二十七、Ext概述 据我了解Ext是一个用js编写RIA框架,它可以和各种后台语言结合使用。 我在项目中用Ext来完成的模块大概情况是这个样子,首先我通过layout 等于border的这种方式来进行布局,分为上下左右中,然后在左边用ext tree来进行菜单的展示,之后在中间区域通过tabs来加入选项卡,而在 选项卡中就是一个个的grid以及form,其中我在做grid的时候,首先通过 store来存取后台返回的符合model格式数据集,store是通过proxy和后台的 contoller进行交互,之后把store赋值给grid的store属性并且通过renderTO 在指定的位置进行渲染展示。 Grid问题: 当时我在做grid的时候,发现数据没有展示出来, 我通过f12进行跟踪,发现压根就没有发送请求,后来我分析了下,发现因为 没有调用store的loadPage方法,所以导致了这个问题。除此之外在我们做 项目的过程中,我手底下带的一个人同样在负责grid的时候,数据可以正常展示,但 分页信息没有展示,通过跟踪他的代码发现是因为他没有把store属性赋值给 分页工具条,所以才导致了这个问题。 tabs选项卡: 当我在做tab选项卡这一模块的时候, 我首先在加载页面的时候用TabPanel创建了一个 tab页面,让它展示在中间位置, 然后点击左边Tree菜单调用add方法动态添加一个个 的tab选项卡,但是做的过程中出现了相同的选项卡会重复添加的问题, 如果选中则调用setActiveTab来激活该选项卡,让它选中, 否则就添加一个tab。 最后达到了tab不存在就添加,存在就选中的效果。 了解: Ext4.0也支持前端的MVC开发模式. 为啥没采用mvc的开发模式? 开发模式进行开发,并没有采用Ext4.0这种mvc模式的特性。但 我认为他们的核心操作流程是一致的所以对我来说去学习和使用 这种方式并没有什么难度。 二十八、lucene的概述 lucene是一个全文检索引擎,在进行模糊匹配的时候,他可以 用来替代数据库中的like,从而在匹配准确性以及性能进行大幅度 的提高。我在做XX项目的XX模块的时候,就是用lucene来进行全文检索 用IK分词器来进行分词。从而实现了高亮显示关键词,分页,排序, 多字段,多条件的高性能搜索。在从数据中取数据生成索引的时候, 因为表中的数据量比较大,防止一次取出所导致内存溢出问题,我采用了 分段批量提取的方式进行,除此之外我们对后续增加的数据根据优先级的 不同采取不同的策略,对于那些需要及时显示的数据我们通过spring 及时展示的数据,我们通过spring定时器在每天晚上凌晨的时候进行索 引的重新生成。 二十九、线程池作用 1.减少了创建和销毁线程的次数, 每个线程都可以被重复利用, 可执行多个任务。 2.可以根据系统的承受能力, 调整线程池中线程的数目, 防止因为消耗过多的内存, 而导致服务器宕机 (每个线程需要大约1MB内存,线程开的越多, 消耗的内存也就越大,最后宕机)。 通常我们使用的线程池是实现了ExecutorService的 ThreadPoolExecutor。 三十、jbpm是如何和spring进行整合 1.通过在spring-common.xml配置文件中配置springHelper,通过springHelper创建 processEngine,再通过processEngine获取各种工作流的Service, 如repositoryService,executionService,historyService,taskService 2.在src根目录下新建jbpm.cfg.xml文件 三十一、Tomcat优化 增大内存(堆,持久代)并开启server模式 我在做XXX项目时,用到了poi导入和导出数据,由于公司的业务比较繁多,数据量很大,测试时报内存溢出,经过我的分析再结合上网查阅资料,发现可能是tomcat内存不足,需要增大,修改配置文件后测试不再报错. tomcat增大内存的方式通过修改tomcat配置文件 window下,在bin/catalina.bat文件中最前面添加: setJAVA_OPTS=-XX:PermSize=64M-XX:MaxPermSize=128m–Xms1024m-Xmx1024m linux下,在catalina.sh最前面增加: JAVA_OPTS="-XX:PermSize=64M-XX:MaxPermSize=128m–Xms1024m-Xmx1024m" -client–service 当我们在cmd中运行-java时,黑窗口会出现-client-service这两参数.其作用是设置虚拟机运行模式;client模式启动比较快,但运行时性能和内存管理效率不如server模式,通常用于客户端应用程序。server模式启动比client慢,但可获得更高的运行性能。Windows默认为client,如果要使用server模式,就需要在启动虚拟机时加-server参数,以获得更高性能,对服务器端应用,推荐采用server模式,尤其是多个CPU的系统。在Linux,Solaris上,默认值为server模式. JDK版本 影响虚拟机还有JDK的版本,JDK分为32位,64位两种版本,32位装在32位系统,64位系统可以装32位和64位JDK.64位JDK性能优于32位JDK. 测试的命令java-xmx数值m–version报错配置大小失败,反之成功 增加Tomcat最大连接数 使用场景 我在做完一个XXX项目后,测试时发现并发数量增加到一定程度就会很卡,于是我想到了是不是tomcat最大连接数设置有限制.果不其然,配置文件中最大值才500,于是我更改了最大连接数,根据业务我修改了连接数为2000,完美的解决了这个问题; 修改方法在conf/service.xml中默认值 minSpareThreads="30"maxSpareThreads="75"enableLookups="false" redirectPort="8443"acceptCount="100"connectionTimeout="20000" disableUploadTimeout="true"/>,修改maxthreads的值即可 tomcat进行gzip压缩从而降低网络传输量 tomcat压缩设置tomcat压缩gzip启用 HTTP压缩可以大大提高浏览网站的速度,它的原理是, 在客户端请求服务器对应资源后,从服务器端将资源文件压缩, 再输出到客户端,由客户端的浏览器负责解压缩并浏览。 相对于普通的浏览过程HTML,CSS,Javascript,Text, 它可以节省60%左右的流量。更为重要的是,它可以对动态生成的, 包括CGI、PHP,JSP,ASP,Servlet,SHTML等输出的网页也能进行压缩, 压缩效率也很高。 启用tomcat的gzip压缩 要使用gzip压缩功能,你需要在Connector节点中加上如下属性 compression="on"打开压缩功能 compressionMinSize="50"启用压缩的输出内容大小,默认为2KB noCompressionUserAgents="gozilla,traviata"对于以下的浏览器,不启用压缩 compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"哪些资源类型需要压缩 connectionTimeout="20000" redirectPort="8443"executor="tomcatThreadPool"URIEncoding="utf-8" compression="on" compressionMinSize="50"noCompressionUserAgents="gozilla,traviata" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"/> 三十二、memcached的介绍 memcached是一个用C语言开发的分布式的缓存,内部基于类似hashMap的结构。 它的优点是协议简单,内置内存存储,并且他的 分布式算法是在客户端完成的,不需要服务器端进行 通信,我们当时在做项目的时候因为考虑到项目 的高可用性高扩展性,因此在服务器部署方面采用 了apache+jk+tomcat这种负载均衡的方式,但是也带来了一个问题 就是session共享的问题,虽然可以通过session复制来解决这个 问题,但是在性能方面存在缺陷,所以最后我们采用了 用memcached来存储session,这样既解决了session共享 问题,也解决了session复制那种方式所产生的性能问题。 了解(不必主动说,但别人问的话一定要知道) memcached是以KEY-VALUE的方式进行数据存储的, KEY的大小限制:Key(max)<=250个字符; VALUE在存储时有限制:Value(max)<=1M; 根据最近最少使用原则删除对象即LRU. 代码结构层次的优化(目的:更加方便代码的维护--可维护性,可读性) 1.代码注释(代码规范) 2.工具类的封装(方便代码的维护,使代码结构更加清晰不臃肿,保证团队里代码质量一致性) 3.公共部分的提取 代码性能的优化(目的:使程序的性能最优化) 1.使用一些性能比较高的类(bufferInputStream) 2.缓冲区块的大小(4k或者8k) 4.通常要用stringbuffer替代string加号拼接 我们做项目的时候业务优化这方面最主要是从用户体验度角度进行考虑,减少用户操作的步骤提高工作效率,通常有以下几种: 1.可以通过tabindex属性来改变tab键盘的操作顺序 2.可以通过回车键来进行搜索或者提交操作 3.对于单选按钮和复选按钮可以通过操作后面的文本来选择前面的单选按钮以及复选按钮 4.添加的信息要按照id倒序进行排列 5.进行搜索操作时加入jsloading操作(不仅告诉用户所进行的请求正在被处理,而且防止用户多次点击提交操作) 6.当进行删除操作的时候要弹出提示框,警告用户要进行删除操作,是否确认。 8.进行删除操作时通过confirm提示用户是否确认删除操作,操作完后提示操作是否成功。 9.减少用户操作的步骤 10.使用autocomplete插件快速进行搜索 必背,必做: 1.可以通过回车键来进行搜索或者提交操作 2.添加的信息要按照id倒序进行排列 3.进行搜索操作时加入jsloading操作(不仅告诉用户所进行的请求正在被处理,而且防止用户多次点击提交操作) 4.当进行删除操作的时候要弹出提示框,警告用户要进行删除操作,是否确认,如果删除成功则弹出提示框告诉用户。 5.减少用户操作的步骤 6.通过ztree,以及kindeiditor来提高用户的体验度 1、SELECT子句中避免使用*,尽量应该根据业务需求按字段进行查询 2、尽量多使用COMMIT如对大数据量的分段批量提交释放了资源,减轻了服务器压力 3、在写sql语句的话,尽量保持每次查询的sql语句字段用大写,因为oracle总是先解析sql语句,把小写的字母转换成大写的再执行 4、用UNION-ALL替换UNION,因为UNION-ALL不会过滤重复数据,所执行效率要快于UNION,并且UNION可以自动排序,而UNION-ALL不会 5、避免在索引列上使用计算和函数,这样索引就不能使用 Sql优化精简版: 1.(重点)(必须说)SELECT语句中避免使用*, 尽量应该根据业务需求按字段进行查询 举例:如果表中有个字段用的是clob或者是blob这种大数据字段的话, 他们的查询应该根据业务需要来进行指定字段的查询,切记勿直接用* 2.(重点)删除重复记录(oracle): 最高效的删除重复记录方法(因为使用了ROWID)例子: DELETEFROMEMPEWHEREE.ROWID>(SELECTMIN(X.ROWID) FROMEMPXWHEREX.EMP_NO=E.EMP_NO); 3.用>=替换> 如一个表有100万记录,一个数值型字段A, A=0时,有30万条; A=1时,有30万条; A=2时,有39万条; A=3时,有1万记录。 那么执行A>2与A>=3的效果就有很大的区别了,因为A>2时, ORACLE会先找出为2的记录索引再进行比较, 而A>=3时ORACLE则直接找到=3的记录索引。 4.(重点)尽量多使用COMMIT 如对大数据量的分段批量提交 5.(重点)用NOTEXISTS或(外连接+判断为空)方案替换NOTIN操作符 此操作是强列推荐不使用的,因为它不能应用表的索引。 推荐方案:用NOTEXISTS或(外连接+判断为空)方案代替 6.(重点必须说)LIKE操作符(大数据的全文检索使用luncene)(solr) 因为使用like不当,会导致性能问题,原因是like在左右两边都有 %的时候,不会使用索引。 如LIKE'%5400%'这种查询不会引用索引, 而LIKE'X5400%'则会引用范围索引。 一个实际例子: 查询营业编号YY_BHLIKE'%5400%'这个条件会产生全表扫描, 如果改成YY_BHLIKE'X5400%'ORYY_BHLIKE'B5400%' 则会利用YY_BH的索引进行两个范围的查询,性能肯定大大提高。 7.(重点,必须说)避免在索引列上使用计算和函数,这样索引就不能使用 举例: 低效: SELECT…FROMDEPTWHERESAL*12>25000; 高效: SELECT…FROMDEPTWHERESAL>25000/12; 8.(重点必须说)用UNION-ALL替换UNION, 因为UNION-ALL不会过滤重复数据而且不会自动排序, 所执行效率要快于UNION。 9.(优化,重点,3个方面a.缓存b.分段批量c.存储过程)减少访问数据库的次数 举例:如果批量删除多条数据,可以用deletefromtableNamewhereid in(1,2,3) 而不要用多条delete语句进行删除 10.(重点必须说)用TRUNCATE替代DELETE TRUNCATE不记录日志,DELETE记录日志,所以TRUNCATE要快于DELETE 但是一旦用TRUNCATE进行删除就不能进行恢复,TRUNCATE是删除整张表的数据 不能加where条件。 ================================================================== mysql,sqlserver中如果 id为自增类型,那么如果用TRUNCATE删除,则id字段再插入数据时从1开始, 如果delete删除的话,则从删除之前的id的值继续增长。 针对防sql注入,我们通常是这样做的: 首先在前台页面对用户输入信息进行js验证,对一些特殊字符进行屏蔽, 比如:or,单引号,--,=,还有就是限制用户名输入的长度,我们一般 将其限制在6---13位。另外,对于用户的敏感信息我们进行Md5加密,还有 ,为了增加用户体验度和用户友好度,为了不使用户看到一些详细的异常信息 我们会进行错误信息页面的定制,像404,500错误。另一个我层面讲,这样做 也是为了保护我们的一些重要信息。此外,我们会给特定的人分配定定的权限 ,而不是给其分配管理员权限! sql注入 所谓SQL注入,就是通过一些含有特殊字符的sql语句发送到服务器欺骗服务器并进行攻击。(特殊字符:or,单引号,--,空格) Sql注入的防护 2.永远不要使用动态拼装sql,使用参数化的sql。(永远不要使用+号拼接sql字符串,而是使用?传参的方式进行) 3.不要给用户太高的权限而根据需求进行赋权 4.对敏感信息进行加密如md5(单向加密不可逆转)。 5.自定义错误页面。目的是为了不把我们的程序的bug暴露在别有用心的人的面前。而去不会让用户看到报错的页面,也提高了用户的体验度。 SQL注入防范 使用参数化的过滤性语句要防御SQL注入,用户的输入就绝对不能直接被嵌入到SQL语句中。恰恰相反,用户的输入必须进行过滤,或者使用参数化的语句。参数化的语句使用参数而不是将用户输入嵌入到语句中。在多数情况中,SQL语句就得以修正。然后,用户输入就被限于一个参数。 输入验证 检查用户输入的合法性,确信输入的内容只包含合法的数据。数据检查应当在客户端和服务器端(java代码)都执行之所以要执行服务器端验证,是为了弥补客户端验证机制脆弱的安全性。在客户端,攻击者完全有可能获得网页的源代码,修改验证合法性的脚本(或者直接删除脚本),然后将非法内容通过修改后的表单提交给服务器。因此,要保证验证操作确实已经执行,唯一的办法就是在服务器端也执行验证。你可以使用许多内建的验证对象,例如RegularExpressionValidator,它们能够自动生成验证用的客户端脚本,当然你也可以插入服务器端的方法调用。如果找不到现成的验证对象,你可以通过CustomValidator自己创建一个。 错误消息处理 防范SQL注入,还要避免出现一些详细的错误消息,因为黑客们可以利用这些消息。要使用一种标准的输入确认机制来验证所有的输入数据的长度、类型、语句、企业规则等。 加密处理 存储过程来执行所有的查询 SQL参数的传递方式将防止攻击者利用单引号和连字符实施攻击。此外,它还使得数据库权限可以限制到只允许特定的存储过程执行,所有的用户输入必须遵从被调用的存储过程的安全上下文,这样就很难再发生注入式攻击了。 使用专业的漏洞扫描工具 攻击者们目前正在自动搜索攻击目标并实施攻击,其技术甚至可以轻易地被应用于其它的Web架构中的漏洞。企业应当投资于一些专业的漏洞扫描工具,如大名鼎鼎的Acunetix的Web漏洞扫描程序等。一个完善的漏洞扫描程序不同于网络扫描程序,它专门查找网站上的SQL注入式漏洞。最新的漏洞扫描程序可以查找最新发现的漏洞。 确保数据库安全 锁定你的数据库的安全,只给访问数据库的web应用功能所需的最低的权限,撤销不必要的公共许可,使用强大的加密技术来保护敏感数据并维护审查跟踪。如果web应用不需要访问某些表,那么确认它没有访问这些表的权限。如果web应用只需要只读的权限,那么就禁止它对此表的drop、insert、update、delete的权限,并确保数据库打了最新补丁。 安全审评 在部署应用系统前,始终要做安全审评。建立一个正式的安全过程,并且每次做更新时,要对所有的编码做审评。开发队伍在正式上线前会做很详细的安全审评,然后在几周或几个月之后他们做一些很小的更新时,他们会跳过安全审评这关,“就是一个小小的更新,我们以后再做编码审评好了”。请始终坚持做安全审评。 五、数据库中常用术语: ddl:数据定义语言CreateDropAlter dml:数据操纵语言insertupdatedeleteselect dcl:数据控制语言grantrevoke tcl:事务控制语言commitrollback 深入java虚拟机以及大数据 当List放了大量的数据超过jvm中所能容纳的内存后,就会发生堆溢出。 当递归调用没有临界退出条件就会出现栈溢出。 当批量导入大量数据或者用dom4j解析大的xml文件的时候, 会出现堆溢出,这个时候可以通过分段批量提交以及用 sax代替dom4j来解决问题。 heap(堆),stack(栈) jvm的结构细分及其概述 Java虚拟机有一个堆,堆是运行时数据区域, 所有类实例和数组的内存均从此处分配。 堆是在Java虚拟机启动时创建的。” “在JVM中堆之外的内存称为非堆内存(Non-heapmemory)”。 可以看出JVM主要管理两种类型的内存:堆和非堆。 简单来说堆就是Java代码可及的内存,是留给开发人员使用的; 非堆就是JVM留给自己用的。 jvm内存结构? 堆:逻辑上是连续,物理上可以处于不连续的内存空间中, 里面存储的是对象实例以及数组。可以细分为新生代,老生代。 通过-Xmx和-Xms控制大小。 虚拟机栈:基本数据类型,对象引用(地址,指针)。 本地方法栈(了解):它与虚拟机栈发挥的作用差不多,区别在于虚拟机栈为java方法 的执行提供服务,而本地方法栈为虚拟机使用到的Native(本地)方法服务。 方法区:放了所加载的类的信息(名称、修饰符等)、类中的静态变量、 类中定义为final类型的常量、类中的Field信息、类中的方法信息 在SunJDK中这块区域对应的为PermanetGeneration,又称为持久代, 默认为64M,可通过-XX:PermSize以及-XX:MaxPermSize来指定其大小 在服务器启动的时候报内存溢出是因为方法区太小,也就相当于持久代的内存太小。 通过-XX:PermSize以及-XX:MaxPermSize来指定其大小,可以解决这个问题。 常量池是方法区的一部分,用来存储常量信息。如String就存储在 常量池中。 计数器(了解):通过该计数器的值来选取下一条要执行的字节码指令。 GC是什么,为什么要有GC? GC就是垃圾回收,java这种语言是动态分配内存大小的,并且依靠 垃圾回收机制来完成对分配内存空间的回收,从而来避免内存溢出的问题, 也在一定程度上降低了程序员工作的复杂度。 jvm中的GC采用了generation(分代回收)算法, 因此,jvm将堆内存划分为年轻代(younggeneration)和 年老代(oldgeneration)。 年老代中的对象则已经创建比较久了, 按照上面的划分,jvm在做GC时也进行了区别对待, 对年轻代GC会相对比较频繁,且采用了copying(复制)算法; 年老代的GC相对比较少,且采用的是tracing算法的一种, 是标记-清除-压缩。 JVM内存限制(最大值) JVM内存的最大值跟操作系统有很大的关系。 简单的说就32位处理器虽然可控内存空间有4GB, 但是具体的操作系统会给一个限制, 这个限制一般是2GB-3GB (一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G), 而64bit以上的处理器就不会有限制了。 Java监视和管理控制台: JConsole使您能够在运行时监视各种JVM资源统计信息。 这种特性特别适用于检测死锁、内存泄漏。 它可以连接到一个本地或远程JVM并可用来进行监视: 内存使用情况 垃圾收集 运行时信息 JVM信息 jvm的调优 开启-Server模式,增大堆的大小,以及持久代的大小,从而 提高程序的运行效率,并且将初始堆大小和最大堆大小设置为 一样的值从而避免了堆增长会带来额外压力。持久代大小的设置 同理,也设置为初始大小和最大大小一样大。 jvm的类加载机制jvm中类的生命周期? 生命周期:加载、连接、初始化,使用,卸载 对象基本上都是在jvm的堆区中创建,在创建对象之前, 会触发类加载(加载、连接、初始化), 当类初始化完成后, 根据类信息在堆中实例化类对象, 初始化非静态变量、非静态代码以及默认构造方法, 当对象使用完之后会在合适的时候被jvm垃圾收集器回收。 要经过三步:加载(Load),链接(Link),初始化(Initializ)。 其中链接又可分为校验(Verify),准备(Prepare),解析(Resolve)三步。 ClassLoader就是用来装载的。通过指定的className,找到二进制码, 生成Class实例,放到JVM中。 ClassLoader从顶向下分为: BootstrapClassLoader:引导类加载器, 它负责加载Java的核心类(如rt.jar) ExtensionClassLoader:扩展类加载器, 它负责加载JRE的扩展目录 (JAVA_HOME/jre/lib/ext)中的JAR包 SystemClassLoader:系统(也称为应用)类加载器, 它负责在JVM被启动时加载来自在命令java中的-classpath 中的JAR包 User-DefinedClassLoader:用户自定义的类加载器 linux中的命令: ps-ef|grep:查看进程信息 vi:文件编辑命令 more:分页查看命令 top:常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况 ifconfig:显示或配置网络设备的命令 ping:它通常用来测试与目标主机的连通性 rsync、scp:文件同步命令 2.云计算+大数据的具体技术实现方案: Hadoop是一个能够对大量数据进行分布式处理的软件框架。 它以并行的方式工作,通过并行处理加快处理速度, 维护多个工作数据副本, 具有可伸缩性,能够处理PB级数据. hadoop由许多元素构成。其最底部是HDFS, 它存储Hadoop集群中所有存储节点上的文件。 HDFS的上一层是MapReduce引擎. hadoop下的子项目: HDFS:Hadoop分布式文件系统 MapReduce:并行计算框架(建立在HDFS上的) HBase:类似GoogleBigTable的分布式NoSQL列数据库 Hive:数据仓库工具 Zookeeper:分布式锁设施 Pig:大数据分析平台,为用户提供多种接口 行业知识(了解): 存储容量:是该存储设备上可以存储数据的最大数量,通常使用千字节(kbkilobyte)、兆字节(MBmegabyte)、吉字节(GB,gigabyte)、太字节(TB,terabyte)和PB(Petabyte)、EB(Exabyte)等来衡量。 1KB=2(10)B=1024B;括号中的数字为2的指数(即多少次方) 1MB=2(10)KB=1024KB=2(20)B; 1GB=2(10)MB=1024MB=2(30)B。 1TB=2(10)GB=1024GB=2(40)B 1PB=2(10)TB=1024TB=2(50)B 1EB=2(10)PB=1024PB=2(60)B 1Byte(相當於一個英文字母,您的名字相當6Bytes(6B)。 Kilobyte(KB)=1024B相當於一則短篇故事的內容。 Megabyte(MB)=l024KB相當於一則短篇小說的文字內容。 Gigabyte(GB)=1024MB相當於貝多芬第五樂章交響曲的樂譜內容。 Terabyte(TB)=1024GB相當於一家大型醫院中所有的X光圖片資訊量。 Petabyte(PB)=l024TB相當於50%的全美學術研究圖書館藏書資訊內容。 Exabyte(EB)=1024PB;5EB相當於至今全世界人類所講過的話語。 Zettabyte(ZB)=1024EB如同全世界海灘上的沙子數量總和。 Yottabyte(YB)=1024ZB相當於7000位人類體內的微細胞總和。