聊聊java

家电修理 2023-07-16 19:16www.caominkang.com电器维修

1.java的发展历史现状

一、java的前身
1990年,由于单片式计算机系统的火爆,sun公司为了抢占市场,成立了包括詹姆斯·高斯林在内的green小组,主要攻克家电的嵌入式应用,这些家电由于当时硬件的限制,计算处理能力和内存都非常有限,这就要求在极为紧凑的硬件中必须写入大量代码,且当时的嵌入式处理器芯片的种类繁杂,这对跨平台性要求极高,所以采用的语言必须具备简单、可移植、高性能等特点。当时最流行的语言是C++,所以green小组优先考虑使用C++编写程序,在实践过程中却发现单片机的硬件资源极其匮乏,而C++有过于庞大复杂。于是green小组萌生了开发一门实用性更强的语言的想法。green小组在C++的基础上进行了改良,去除了不太实用及影响安全的成分,并结合嵌入式系统的实时性要求,开发了一种称为Oak的面向对象语言,这就是java的前身。

二、java诞生
1992年,green小组向硬件生产商展示采用Oak语言开发的Green操作系统,可是硬件生产商觉得对Oak语言一无所知,贸然生产风险太大,所以Oak语言坐上了冷板凳。
1993年,美国伊利诺州的伊利诺大学的NCSA组织,发表了第一个可以显示图片的浏览器,命名为MOSAIC浏览器,这是第一个万维网浏览器。
1994年,green小组受到Mosaic浏览器的启发,认为互联网应用前景巨大,改变了面向硬件编程的目标,转而研究怎么将技术运用于互联网,并开发了一个小型万维网浏览器WebRunner。
1995年,互联网蓬勃发展,许多公司看到了互联网的前景,纷纷投入大量人力、物力研究。这时Sun公司想到了冷板凳上的Oak,重新审视了一番Oak,发现其开发的应用特性刚好满足互联网的需求,所以加大力度开发了可以嵌入网页并且可以随同网页在网络上传输的Applet程序,并准备为Oak申请注册商标,发现该商标已被注册。一群程序员在那里左思右想,不知道该起什么名字,一人在看到咖啡的时候灵机一动,提议道“要不就叫java吧”,其他人都表示赞同,于是Oak改名为JAVA,并与同年5月23日Sun orld会议上正式发布Java和和HotJava浏览器。JAVA就此诞生!

 

三、java的发展历程

1995年5月23日,Sun公司在Sun orld会议上正式发布Java和HotJava浏览器,宣告着JAVA的诞生,创始人为詹姆斯·高斯林

1996年,Sun公司正式发布独立的、可供下载的java开发工具JDK1.0版本,这是Java发展历程中的重要里程碑

1997年,JDK1.1发布,3周内下载量达22万次

1998年,第二代java平台发布,并发布了企业版java EE

1999年,Sun公司发布Java第二代平台的三大版本

标准版(J2SE)桌面级 C/S

企业版(J2EE)企业级 B/S

微型版(J2ME)移动端

2000年,JDK1.3、JDK1.4和J2SE1.3相继发布,几周后其获得了Apple公司Mac OS X的工业标准的支持

2001年,J2EE1.3发布

2002年,J2SE1.4发布,自此Java的计算能力有了大幅提升

2004年,J2SE1.5发布,J2SE 1.5更名为Java SE 5.0(内部版本号1.5.0),成为Java语言发展史上的又一里程碑

2005年,在Java One大会上,Sun公司发布了Java SE 6。至此,Java的各种版本已经更名,已取消其中的数字2,如J2EE更名为JavaEE,J2SE更名为JavaSE,J2ME更名为JavaME

2009年,oracle公司收购了sun公司
2010年,Java编程语言的共同创始人之一詹姆斯·高斯林从Oracle公司辞职
2011年,oracle公司举行了全球性的活动,以庆祝Java7的推出,随后Java7正式发布
2014年,oracle公司发布了Java8正式版
2017年,oracle公司发布Java SE 9
2018年3月,oracle公司发布Java SE 10
2018年9月,oracle公司发布Java SE 11
2019年2月,oracle公司发布Java SE 12
2019年9月,oracle公司发布Java SE 13
2020年3月,oracle公司发布Java SE 14
2020年9月,oracle公司发布Java SE 15
2021年4月,oracle公司发布Java SE 16

1. 美国Segue公司的Silk系列产品
   Segue公司一直专注于软件质量优化领域。在Segue的产品套件中,拥有业内最强劲且最容易使用的、用于企业应用测试、调优和监测的自动化工具,能够帮助用户保障应用在其生命周期内的可靠性和性能。
  (1) SilkPerformer——企业级性能测试工具
  企业级自动化测试工具能够支持多种系统,如Java、.Net、Wireless、COM、CORBA、Oracle、Citrix、MetaFrame、客户机/服务器、以及各种ERP/CRM应用 
  多项专利技术精确模拟各种复杂的企业环境 
  可视化脚本记录功能及自定义工具简化了测试创建工作 
  SilkPerformer的Java/.NET浏览器以及JUnit/NUnit测试输入功能简化了对并发访问情况下远程应用组件的早期负载测试工作 
  方便易用,工作流向导会逐步引导用户完成整个测试流程 
  (2) SilkTest International——业内唯一的Unicode功能测试工具
  SilkBean 充分利用 Java 语言的“编写一次,随处使用”的优点,让用户不必修改现有的脚本而能够在多种基于 Unix 的系统上运行
  能够识别多种开发平台,如Java、JavaScript、HTML、ActiveX、Visual Basic 和C/C++等
  一套脚本可供所有支持的语言使用
  内置的错误恢复系统不仅具有自定义功能,可进行无人看守的自动测试
  赛格瑞(Segue)公司是全球范围内专注于软件质量优化解决方案的领导者。2005年,赛格瑞(Segue)公司在中国设立了专门的销售服务公司,,赛格瑞(Segue)公司的软件测试产品在中国有了更好的技术支持。
  参考网站http://.segue../
  推荐指数★★★★★

 MaxQ
  MaxQ是一个免费的功能测试工具。它包括一个HTTP代理工具,可以录制测试脚本,并提供回放测试过程的命令行工具。测试结果的统计图表类似于一些较昂贵的商用测试工具。MaxQ电脑维修网希望能够提供一些关键的功能,比如HTTP测试录制回放功能,并支持脚本。
  参考网站http://maxq.tigris./ 
  推荐指数★★★☆☆
  3. Httpunit
  HttpUnit是一个开源的测试工具,是基于JUnit的一个测试框架,主要关注于测试Web应用,解决使用JUnit框架无法对远程Web内容进行测试的弊端。
  HttpUnit提供的帮助类让测试者可以通过Java类和服务器进行交互,并且将服务器端的响应当作文本或者DOM对象进行处理。HttpUnit还提供了一个模拟Servlet容器,让测试者不需要发布Servlet,就可以对Servlet的内部代码进行测试。本文中作者将详细的介绍如何使用HttpUnit提供的类完成集成测试。
  参考网站http://.httpunit./
  推荐指数★★★☆☆
  4. Junit 
  是通用的测试 java 程序的测试框架JUnit可以对Java代码进行白盒测试。通过JUnitk可以用mock objects进行隔离测试;用Cactus进行容器内测试;用Ant和Maven进行自动构建;在Eclipse内进行测试;对Java应用程序、Filter、Servlet、EJB、JSP、数据库应用程序、Taglib等进行单元测试。
  参考网站http://.junit./
  推荐指数★★★★★
  5. Jtest
  Jtest是Parasoft公司推出的一款针对java语言的自动化白盒测试工具,它通过自动实现java的单元测试和代码标准校验,来提高代码的可靠性。Jtest先分析每个java类,然后自动生成junit测试用例并执行用例,从而实现代码的最大覆盖,并将代码运行时未处理的异常暴露出来;,它还可以检查以DbC(Design by Contract)规范开发的代码的正确性。用户还可以通过扩展测试用例的自动生成器来添加更多的junit用例。Jtest还能按照现有的超过350个编码标准来检查并自动纠正大多数常见的编码规则上的偏差,用户可自定义这些标准,通过简单的几个点击,就能预防类似于未处理异常、函数错误、内存泄漏、性能问题、安全隐患这样的代码问题。
  JTest最大的优势在于静态代码分析,至于自动生成测试代码,生成测试代码框架也是不错的,但要做好单元测试用户还要做大量的工作。
  参考网站http://.parasoft./jsp/aep/aep.jsp
  推荐指数★★★★☆

6. Hansel
  Hansel 是一个测试覆盖率的工具——与用于单元测试的 JUnit frameork 相集成,很容易检查单元测试套件的覆盖情况。
  参考网站http://hansel.sourcefe./
  推荐指数★★☆☆☆
  7. Cactus 
  Cactus是一个基于JUnit框架的简单测试框架,用来单元测试服务端Java代码。Cactus框架的主要目标是能够单元测试服务端的使用Servlet对象的Java方法如HttpServletRequest,HttpServletResponse,HttpSession等针对外部可测试组件运行时,需要把JUnit测试运行为发送HTTP请求给组件的客户端进程。为了在服务器容器内部运行JUnit测试,可以用Cactus框架,它是一个免费的开源框架,是Apache Jakarta项目的一部分。Cactus 包含了关于JUnit客户端如何连接到服务器,然后使测试运行的详细信息。
  参考网站http://jakarta.apache./cactus/
  推荐指数★★★★☆
  8. JFCUnit
  JFCUnit使得你能够为Java偏移应用程序编写测试例子。它为从用代码打开的窗口上获得句柄提供了支持;为在一个部件层次定位部件提供支持;为在部件中发起事件(例如按一个按钮)以及以线程安全方式处理部件测试提供支持。
  参考网站http://jfcunit.sourcefe./
  推荐指数★★★☆☆
  9. StrutsTestCase
  StrutsTestCase(STC)框架是一个开源框架,用来测试基于 Struts 的 Web 应用程序。这个框架允许您在以下方面进行测试
  在 ActionForm 类中的验证逻辑(validate() 方法)
  在 Action 类中的业务逻辑(execute() 方法) 
  动作转发(Action Forards)。 
  转发 JSP
  STC 支持两种测试类型
  Mock 方法 —— 在这种方法中,通过模拟容器提供的对象(HttpServletRequest、 HttpServletResponse 和 ServletContext),STC 不用把应用程序部署在应用服务器中,就可以对其进行测试。
  Cactus 方法 —— 这种方法用于集成测试阶段,在这种方法中,应用程序要部署在容器中,所以可以像运行其他 JUnit 测试用例那样运行测试用例。

参考网站http:// strutstestcase.sourcefe./
  推荐指数★★★★☆
  10. TestNG
  TestNG是根据JUnit 和 NUnit思想而构建的一个测试框架,TestNG增加了许多新的功能使得它变得更加强大与容易使用比如
  支持JSR 175注释(JDK 1.4利用JavaDoc注释同样也支持)
  灵活的Test配置
  支持默认的runtime和logging JDK功能
  强大的执行模型(不再TestSuite)
  支持独立的测试方法
  参考网站http://testng./
  推荐指数★★★★☆ 

 程序员编写.java文件
javac编译成字节码文件.class(JVM只认识.class文件)
在由JVM解释成电脑认识的机器语言

JVM,JRE,JDK

 JVMJava虚拟机,运行Java字节码文件.calss的虚拟机。
Java针对不同的系统平台都开发了对应的虚拟机,实现跨平台,一次编写,多处运行。JVM使用GC垃圾回收器和自适应优化器。
JREJava运行环境是一个软件,JRE为Java运行提供了环境。内部有一个Java虚拟机,以及一些标准的类库(Class Library)。
JDKJava软件开发工具包,用于各种环境下的Java程序开发。是整个Java开发的核心,包含了JRE(JVM+Java类库Java API)和Java工具(Javac)。
JDK目录下有四个文件夹bin、include、lib、 jre。
bin:最主要的是编译器(javac.exe)
include:java和JVM交互用的头文件
lib类库
jre:java运行环境
JDK是用于java程序的开发,而jre则是只能运行class而没有编译的功能。
三、JVM内存结构

 

JVM根据存储数据划分
堆 Heap作用是存放对象实例和数组。所有线程共享的内存区域,存储程序运行时被创建的所有对象。在虚拟机启动时创建。分为新生代和老年代。GC管理的主要区域。
方法区 Method Area 存储被加载的类信息(元数据)、常量、静态变量、即时编译器编译后的代码等数据。所有线程共享的内存区域。方法区中有运行常量池,用于存放编译期的各种字面值和符号引用。别名叫作“非堆”。
栈 Stack 线程私有,存储局部变量和中间结果。Java方法执行的线程内存模型。每个线程有自己的Java栈区,所有的这些变量都是创建在他们的线程的本地变量,在线程创建时栈区被创建,所有这些本地变量被称为线程本地变量。栈的单位是栈帧,一个方法一个栈帧。
程序计数器 PC register存储当前正在执行的字节码指令的位置(行号)。在Java中,每个线程有自己独立的程序计数器。
由于JVM的多线程是通过线程轮流切换并分配处理器执行时间来实现,一个处理器只能执行一条线程中的指令。为了线程切换后能恢复到正确的执行位置,每条线程都有一个独立的程序计数器,各个线程之间计数器互不影响,独立存储。也叫线程私有的内存。
本地方法栈为虚拟机使用到的本地(Native)方法服务。Native 方法是 Java 通过 JNI 直接调用本地 C/C++ 库,如notify,hashcode,ait等都是native方法。
四、JVM垃圾回收机制

四种引用

 

强引用Object obj=ne Object(),只要强引用关联还在,垃圾回收器永不回收被引用的对象。
软引用系统将要发生内存溢出之前,软引用关联的对象会被回收。回收后还是空间不足,才会抛出内存溢出。
例如一个程序用来处理用户上传的图片。若将所有图片读入内存,这样虽然可以很快的打开图片,但内存空间使用巨大,一些使用较少的图片浪费内存空间,需要手动从内存中移除。如果每次打开图片都从磁盘文件中读取到内存再显示出来,虽然内存占用较少,但一些经常使用的图片每次打开都要访问磁盘,代价巨大。这个时候就可以用软引用构建缓存。
弱引用一些有用但并非必须,弱引用关联的对象,只能生存大下一次垃圾回收之前,GC发生时,不管内存够不够,都会被回收。
虚引用幽灵引用,最弱,随时会被回收掉。垃圾回收时收到一个通知,为了监控垃圾回收器是否正常工作。
对象存活判断
引用计算和根可达分析俩种算法。
引用计算判断对象的引用数量来决定对象是否可以被回收、每个对象实例都有一个引用计数器,被引用则+1,完成引用则-1。C++和Python采用这种算法,JVM并没有使用。
根可达分析扫描堆中的对象,沿着GC Root对象为起点的引用链找该对象,找不到则证明此对象不可用。
垃圾回收算法
当发生GC时,经过GC Roots算法判断为不可达的对象,就会进行对象回收。JVM对象回收主要有复制算法、标记清除、标记整理算法。
复制算法将可用内存按容量划分为大小相等的两块,每次只使用其中一块。垃圾回收时,将所有存活的对象复制到另一块区域。然后对该区域进行整体清除。
标记-清除算法标记所有需要回收的对象,标记完成后统一回收。
特点会存在内存碎片,导致在程序运行中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发GC,执行效率不稳定,需要清理对象越多,效率越低。
标记-整理算法
标记所有需要回收的对象,标记完成后,将存活对象整理到连续区域。然后将非存活对象清除。
特点回收后堆空间规整,没有碎片。效率低,涉及到对象移动、引用更新、需要暂停用户线程。
五、Java内存管理

Java内存管理包括内存分配和内存回收两个方面。由JVM自动完成ne一个Java对象时,即可视为为Java对象申请一个内存空间,JVM会在堆内存中为每个对象分配空间,当一个Java对象失去引用时,JVM的垃圾回收机制就会自动清除他们,并回收它们所占用的内存空间。
当Java对象被创建出来之后,垃圾回收机制GC会实时的监控每一个对象的运行状态。当监控到某个对象不在被引用变量所引用时,垃圾回收机制会立即回收它所占用的空间。
JVM的垃圾回收机制采用有向图方式来管理内存中的对象,可以方便的解决循环引用的问题。
当一个对象在堆内存中运行时,根据它有向图中的状态,可以把状态分为三种
可达状态当一个对象被创建后,有一个以上的变量引用它时。有向图中从起始顶点可以到该对象,那它就处于可达状态。程序可通过引用变量来调用该对象的属性和方法。
可恢复状态若程序中某个对象不再有任何变量引用,它先进入可恢复状态。此时,系统的垃圾回收机制准备回收该对象所占用的内存。在回收之前,系统会调用该对象的finalize方法进行资源清理,如果在调用finalize方法重新让一个以上引用变量引用该对象,则这个对象会变为可达状态。否则,该对象将进入不可达状态。
当对象变成不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。

在Java的内存分配中,总共3种常量池
Java 常量池详解(二)class文件常量池 和 Java 常量池详解(三)class运行时常量池

1.字符串常量池(String Constant Pool)
在JDK1.7之前运行时常量池逻辑包含字符串常量池存放在方法区, 此时hotspot虚拟机对方法区的实现为永久代
在JDK1.7 字符串常量池被从方法区拿到了堆中, 这里没有提到运行时常量池,也就是说字符串常量池被单独拿到堆,运行时常量池剩下的东西还在方法区, 也就是hotspot中的永久代
在JDK1.8 hotspot移除了永久代用元空间(Metaspace)取而代之, 这时候字符串常量池还在堆, 运行时常量池还在方法区, 只不过方法区的实现从永久代变成了元空间(Metaspace)

1.1:字符串常量池在Java内存区域的哪个位置?
在JDK6.0及之前版本,字符串常量池是放在Perm Gen区(也就是方法区)中;
在JDK7.0版本,字符串常量池被移到了堆中了。至于为什么移到堆内,大概是由于方法区的内存空间太小了。
(堆内是可以进行回收的,然后方法区也是能回收的,本身区域内存比较少,如果用的字符串常量太多了,也会抛java.lang.OutOfMemoryError:PermGenspace 异常)
1.2:字符串常量池是什么?
在HotSpot VM里实现的string pool功能的是一个StringTable类,它是一个Hash表,默认值大小长度是1009;这个StringTable在每个HotSpot VM的实例只有一份,被所有的类共享。字符串常量由一个一个字符组成,放在了StringTable上。
在JDK6.0中,StringTable的长度是固定的,长度就是1009,如果放入String Pool中的String非常多,就会造成hash冲突,导致链表过长,当调用String#intern()时会需要到链表上一个一个找,从而导致性能大幅度下降;
在JDK7.0中,StringTable的长度可以通过参数指定

 

 

 如何将String对象放入到常量池
“abc” 双引号String 对象会自动放入常量池
调用String的intern 方法也会将对象放入到常量池中
String 对象代码案例解析

 

public static void main(String[] args) {
    String a = "a";
    String b = "b";
    String c = "a" + "b";
    //生成两个对象 一个"ab" ,一个新的String 对象value 值是ab
    //public String(String original) {
    //   this.value = original.value;
    //   this.hash = original.hash;
    /

Copyright © 2016-2025 www.caominkang.com 曹敏电脑维修网 版权所有 Power by