java面试题(十一)

 


1.JAVA中 jdk与jre的关系,以及编译的过程,加载的过程

JDK(Java Development Kit)

  JDK是Java开发工具包,是Sun Microsystems针对Java开发员的产品。

  JDK中包含JRE,在JDK的安装目录下有一个名为jre的目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而bin和 lib和起来就称为jre。

  JDK是整个JAVA的核心,包括了Java运行环境JRE(Java Runtime Envirnment)、一堆Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)。

Java Runtime Environment(JRE)

  是运行基于Java语言编写的程序所不可缺少的运行环境。也是通过它,Java的开发者才得以将自己开发的程序发布到用户手中,让用户使用。

  RE中包含了Java virtual machine(JVM),runtime class libraries和Java application launcher,这些是运行Java程序的必要组件。

  与大家熟知的JDK不同,JRE是Java运行环境,并不是一个开发环境,所以没有包含任何开发工具(如编译器和调试器),只是针对于使用Java程序的用户。

所以JDK包含JRE,JDK是开发环境而jre则是java运行环境。

2)

一.java的编译阶段大致分为两个阶段: 


早期: 将java程序源码编译成字节码 ,“前端编译器”javac 
晚期: 从字节码生成本地机器码的过程, “后端编译器”JIT编译器 
1.早期大致分为三个过程 
<1>解析和与填充符号表的过程 
a. 词法,语法分析 
词法分析:将源代码的字符流转变为标记(Token)集合,单个字符是编写过程的最小元素,而标记是编译过程的最小元素。 
语法分析:根据Token序列构造抽象语法树(AST)过程。AST的每个节点都代表着程序代码中的一个语法结构(包,类型,修饰符,运算符,接口,返回值类型,代码注释etc)。 
b.符号表 
是由一组符号地址和符号信息构成的表格(类似于哈希表中K-V值对的形式)。 
<2>插入式注解处理器的注解处理过程 
a.注解处理器 
相当于一组编译器的插件,在插件里面可以对AST进行读取,修改,添加任意元素,如果插件对处理注解期间对AST进行了修改,编译器将回到解析以及填充符号表的过程重新处理。直到处理器没有在对AST进行修改为止。每次循环称为一个回环过程如下图所示: 
这里写图片描述
<3>语义分析以及字节码的生成 
1.标注检查 
2.数据及控制流分析 
3.解语法糖 
在计算机语言中添加某种语法,使用语法糖能够增加程序的可读性,从而减少代码出错的机会

2)

2.什么是内存泄漏。溢出

   

一、为什么要了解内存泄露和内存溢出?

 

1、内存泄露一般是代码设计存在缺陷导致的,通过了解内存泄露的场景,可以避免不必要的内存溢出和提高自己的代码编写水平;

 

2、通过了解内存溢出的几种常见情况,可以在出现内存溢出的时候快速的定位问题的位置,缩短解决故障的时间。

 

 

 二、基本概念

 

理解这两个概念非常重要。

 

内存泄露:指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存。即被分配的对象可达但已无用

 

内存溢出:指程序运行过程中无法申请到足够的内存而导致的一种错误。内存溢出通常发生于OLD段或Perm段垃圾回收后,仍然无内存空间容纳新的Java对象的情况。

 

从定义上可以看出内存泄露是内存溢出的一种诱因,不是唯一因素。

 

 

三、内存泄露的几种场景:

 

1、长生命周期的对象持有短生命周期对象的引用

 

            这是内存泄露最常见的场景,也是代码设计中经常出现的问题。

            例如:在全局静态map中缓存局部变量,且没有清空操作,随着时间的推移,这个map会越来越大,造成内存泄露。

 

2、修改hashset中对象的参数值,且参数是计算哈希值的字段

 

             当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段,否则对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中删除当前对象,造成内存泄露。

 

3、机器的连接数和关闭时间设置

 

            长时间开启非常耗费资源的连接,也会造成内存泄露。

 

 

 

 四、内存溢出的几种情况:

 

1、堆内存溢出outOfMemoryError:java heap space

       在jvm规范中,堆中的内存是用来生成对象实例和数组的。

       如果细分,堆内存还可以分为年轻代和年老代,年轻代包括一个eden区和两个survivor区。

       当生成新对象时,内存的申请过程如下:

          a、jvm先尝试在eden区分配新建对象所需的内存;

          b、如果内存大小足够,申请结束,否则下一步;

          c、jvm启动youngGC,试图将eden区中不活跃的对象释放掉,释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区;

          d、Survivor区被用来作为Eden及old的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区;

          e、 当OLD区空间不够时,JVM会在OLD区进行full GC;

          f、full GC后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”:

                                   outOfMemoryError:java heap space

 

/**
 * 堆内存溢出
 *
 * jvm参数:-Xms5m -Xmx5m -Xmn2m -XX:NewSize=1m
 *
 */
public class MemoryLeak {
   
    private String[] s = new String[1000];
 
    public static void main(String[] args) throws InterruptedException {
        Map<String,Object> m =new HashMap<String,Object>();
        int i =0;
        int j=10000;
        while(true){
            for(;i<j;i++){
                MemoryLeak memoryLeak = new MemoryLeak();
                m.put(String.valueOf(i), memoryLeak);
            }
        }
    }
}

 

2、方法区内存溢出(outOfMemoryError:permgem space)

       在jvm规范中,方法区主要存放的是类信息、常量、静态变量等。

       所以如果程序加载的类过多,或者使用反射、gclib等这种动态代理生成类的技术,就可能导致该区发生内存溢出,一般该区发生内存溢出时的错误信息为:

             outOfMemoryError:permgem space

3、线程栈溢出java.lang.StackOverflowError

       线程栈时线程独有的一块内存结构,所以线程栈发生问题必定是某个线程运行时产生的错误。

       一般线程栈溢出是由于递归太深或方法调用层级过多导致的。

       发生栈溢出的错误信息为:

              java.lang.StackOverflowError

/**
 * 线程操作栈溢出
 *
 * 参数:-Xms5m -Xmx5m -Xmn2m -XX:NewSize=1m -Xss64k
 *
 */
public class StackOverflowTest {
   
    public static void main(String[] args) {
        int i =0;
        digui(i);
    }
   
    private static void digui(int i){
        System.out.println(i++);
        String[] s = new String[50];
        digui(i);
    }
 
}

五、为了避免内存泄露,在编写代码的过程中可以参考下面的建议:

 

1、尽早释放无用对象的引用

 

2、使用字符串处理,避免使用String,应大量使用StringBuffer,每一个String对象都得独立占用内存一块区域

 

3、尽量少用静态变量,因为静态变量存放在永久代(方法区),永久代基本不参与垃圾回收

 

4、避免在循环中创建对象

 

5、开启大型文件或从数据库一次拿了太多的数据很容易造成内存溢出,所以在这些地方要大概计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值。 

 

 

3.简答jsp和servlet的联系和区别。

1.jsp经编译后就变成了Servlet.
(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类)
2.jsp更擅长表现于页面显示,servlet更擅长于逻辑控制.
3.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主要用于控制逻辑
Servlet更多的是类似于一个Controller,用来做控制。


 

理解以下三点即可:

 

1、不同之处在哪?

  • Servlet在Java代码中通过HttpServletResponse对象动态输出HTML内容
  • JSP在静态HTML内容中嵌入Java代码,Java代码被动态执行后生成HTML内容

2、各自的特点

  • Servlet能够很好地组织业务逻辑代码,但是在Java源文件中通过字符串拼接的方式生成动态HTML内容会导致代码维护困难、可读性差
  • JSP虽然规避了Servlet在生成HTML内容方面的劣势,但是在HTML中混入大量、复杂的业务逻辑同样也是不可取的

3、通过MVC双剑合璧

既然JSP和Servlet都有自身的适用环境,那么能否扬长避短,让它们发挥各自的优势呢?答案是肯定的——MVC(Model-View-Controller)模式非常适合解决这一问题。

MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller):

  • Controller——负责转发请求,对请求进行处理
  • View——负责界面显示
  • Model——业务功能编写(例如算法实现)、数据库设计以及数据存取操作实现

在JSP/Servlet开发的软件系统中,这三个部分的描述如下所示:

  1. Web浏览器发送HTTP请求到服务端,被Controller(Servlet)获取并进行处理(例如参数解析、请求转发)
  2. Controller(Servlet)调用核心业务逻辑——Model部分,获得结果
  3. Controller(Servlet)将逻辑处理结果交给View(JSP),动态输出HTML内容
  4. 动态生成的HTML内容返回到浏览器显示

MVC模式在Web开发中的好处是非常明显,它规避了JSP与Servlet各自的短板,Servlet只负责业务逻辑而不会通过out.append()动态生成HTML代码;JSP中也不会充斥着大量的业务代码。这大大提高了代码的可读性和可维护性。


4.webService 名词解释。

WebService简介

WebService技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据WebService规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。

简单的说,WebService就是一种跨编程语言和跨操作系统平台的远程调用技术。所谓跨编程语言和跨操作平台,就是说服务端程序采用java编写,客户端程序则可以采用其他编程语言编写,反之亦然。跨操作系统平台则是指服务端程序和客户端程序可以在不同的操作系统上运行。 远程调用,就是一台计算机的应用可以调用其他计算机上的应用。例如:支付宝,支付宝并没有银行卡等数据,它只是去调用银行提供的接口来获得数据。还有天气预报等,也是气象局把自己的系统服务以webservice服务的形式暴露出来,让第三方网站和程序可以调用这些服务功能。

 

XML,SOAP和WSDL就是构成WebService平台的三大技术 。

  • WebService采用Http协议来在客户端和服务端之间传输数据。WebService使用XML来封装数据,XML主要的优点在于它是跨平台的。

  • WebService通过HTTP协议发送请求和接收结果时,发送的请求内容和结果内容都采用XML格式封装,并增加了一些特定的HTTP消息头,以说明HTTP消息的内容格式,这些特定的HTTP消息头和XML内容格式就是SOAP协议规定的。

  • WebService服务器端首先要通过一个WSDL文件来说明自己有什么服务可以对外调用。简单的说,WSDL就像是一个说明书,用于描述WebService及其方法、参数和返回值。 WSDL文件保存在Web服务器上,通过一个url地址就可以访问到它。客户端要调用一个WebService服务之前,要知道该服务的WSDL文件的地址。WebService服务提供商可以通过两种方式来暴露它的WSDL文件地址:1.注册到UDDI服务器,以便被人查找;2.直接告诉给客户端调用者。

SOAP

SOAP即简单对象访问协议,他是使用http发送的XML格式的数据,它可以跨平台,跨防火墙,SOAP不是webservice的专有协议。

SOAP=http+xml

SOAP结构

<span style="color:#000000"><code>必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息
可选的 Header 元素,包含头部信息
必需的 Body 元素,包含所有的调用和响应信息
可选的 Fault 元素,提供有关在处理此消息所发生错误的信息</code></span>

5.索引的作用?和它的优点缺点是什么?

一、作用和优点:
第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 
第二,可以大大加快 数据的检索速度,这也是创建索引的最主要的原因。 
第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 
第四,在使用分组和排序 子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 
第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 


也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?这种想法固然有其合理性,然而也有其片面性。虽然,索引有许多优点,但是,为表中的每一个列都增加索引,是非常不明智的。这是因为,增加索引也有许多不利的一个方面。 

二、缺点:


第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 
第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。 
第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 

 

6.请描述一下CSS的用法。

css的四种引入方式:

1.行内式

行内式是在标记的style属性中设定CSS样式。这种方式没有体现出CSS的优势,不推荐使用。

2.内嵌式

嵌入式是将CSS样式集中写在网页的<head></head>标签对的<style></style>标签对中。格式如下: <head> <style type="text/css"> ...此处写CSS样式 </style> </head> 缺点是对于一个包含很多网页的网站,在每个网页中使用嵌入式,进行修改样式时非常麻烦。单一网页可以考虑使用嵌入式。

3.导入式

将一个独立的.css文件引入HTML文件中,导入式使用CSS规则引入外部CSS文件,<style>标记也是写在<head>标记中,使用的语法如下: <style type="text/css"> @import"mystyle.css"; 此处要注意.css文件的路径 </style> 导入式会在整个网页装载完后再装载CSS文件,因此这就导致了一个问题,如果网页比较大则会儿出现先显示无样式的页面,闪烁一下之后,再出现网页的样式。这是导入式固有的一个缺陷。

4.链接式

也是将一个.css文件引入到HTML文件中,但它与导入式不同的是链接式使用HTML规则引入外部CSS文件,它在网页的<head></head>标签对中使用<link>标记来引入外部样式表文件,使用语法如下: <link href="mystyle.css" rel="stylesheet" type="text/css"/> 使用链接式时与导入式不同的是它会以网页文件主体装载前装载CSS文件,因此显示出来的网页从一开始就是带样式的效果的,它不会象导入式那样先显示无样式的网页,然后再显示有样式的网页,这是链接式的优点。 总结:一般来说,做网站时把样式多写在多个样式表文件中,因此我们先用链接式引入一个总的CSS文件,然后在这个CSS文件中在使用导入式来引入其他的CSS文件。但如果通过JavaScrip来动态引入CSS文件则只能使用链接式


7.什么是存储过程?用什么来调用?

:存储过程是一个预编译的SQL语句,比如一些场景的sql比较复杂,并且需要经常使用或者多次使用的。存储过程的优点是说只需创建一次编译一次,以后在该程序中就可以多次直接调用。如果一个sql是经常需要操作的,并且逻辑不容易改变,使用存储过程比单纯SQL语句执行要快,因为sql每次查询而且都需要编译。而且网络开销也大,存储过程只需要传一个名字,在数据库调用就行了,而且这样程序可移植高。


8.静态include和动态include的区别?

jsp中有两种include,一种是<%@include file="xxx.jsp"%>,另一种是<jsp:include page="xxx.jsp"/>。

<%@include file="xxx.jsp"%>

1.这是一种Driective指令,是一种编译指令,是在编译期间的指令,是静态包含,即将指定的JSP页面或HTML页面包含进来,整个页面一起编译。

2.不能在include指令里面传递参数,如<%@include file="xxx.jsp?aa=1"%>是不合法的,只能在运行JSP页面后,在URL地址栏上传递参数。

3.若当前页面中有<%@page%>指令,则xxx.jsp这个被包含的页面中的<%@page%>指令中 不能存在与当前页面<%@page%>指令中相同的元素,不然会报错。

<jsp:include page="xxx.jsp"/>

1.这是一种Action指令,用于动态包含JSP程序或HTML页面。

2.除非该指令被运行到,否则不会被Tomcat等JSP Engine编译

3、生成的servlet的个数不同:

静态包含和原文件一起共同生成一个servlet(不能有相同的元素),而动态包含是有几处包含就生成几个不同的servlet

4、运行机制不同:

静态包含是先包含再转换成servlet,而动态包含是jsp先转换成servlet再包含在一起、

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值