目录

JVM(Java虚拟机)

Java内存分配回收

分布式

Java-HashMap原理

Java日期时间格式

Java设计模式

数据库

Java基础


JVM(Java虚拟机)

Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。Java编译器只要面向JVM,生成JVM能理解的代码或字节码文件。Java源文件经编译成字节码程序,通过JVM将每一条指令翻译成不同平台机器码,通过特定平台运行。

JVM执行程序的过程:加载 .class 文件,管理并分配内存,执行垃圾收集。

JRE(Java运行时环境)就是由JVM构造的Java程序的运行环境。

JVM主要包括四个部分:

1.类加载器(ClassLoader):在JVM启动时或者在类运行时将需要的class加载到JVM中;

2.执行引擎:负责执行.class文件中包含的字节码指令;

3.内存区(也叫运行时数据区):是在JVM运行的时候操作所分配的内存区。运行时内存区主要可以划分为5个区域:①方法区(Method Area):用于存储类结构信息的地方,包括常量池、静态变量、构造函数等。虽然JVM规范把方法区描述为堆的一个逻辑部分, 但它却有个别名non-heap(非堆)。方法区还包含一个运行时常量池。②Java堆(Heap):存储Java实例或者对象的地方。这块是GC(垃圾回收)的主要区域。从存储的内容我们可以很容易知道,方法区和堆是被所有Java线程共享的。③Java栈(Stack):Java栈总是和线程关联在一起,每当创建一个线程时,JVM就会为这个线程创建一个对应的Java栈。在这个Java栈中又会包含多个栈帧,每运行一个方法就创建一个栈帧,用于存储局部变量表、操作栈、方法返回值等。每一个方法从调用直至执行完成的过程,就对应一个栈帧在Java栈中入栈到出栈的过程。所以Java栈是现成私有的。④程序计数器(PC Register):用于保存当前线程执行的内存地址。由于JVM程序是多线程执行的(线程轮流切换),所以为了保证线程切换回来后,还能恢复到原先状态,就需要一个独立的计数器,记录之前中断的地方,可见程序计数器也是线程私有的。⑤本地方法栈(Native Method Stack):和java栈的作用差不多,只不过是为JVM使用到的native方法服务的。

4.本地方法接口:主要是调用C或C++实现的本地方法及返回结果。

Java内存分配回收

Java的内存分配原理与C/C++不同,C/C++每次申请内存时都要malloc进行系统调用,而系统调用发生在内核空间,每次都要中断进行切换,这需要一定的开销,而Java虚拟机是先一次性分配一块较大的空间,然后每次new时都在该空间上进行分配和释放,减少了系统调用的次数,节省了一定的开销,这有点类似于内存池的概念;二是有了这块空间过后,如何进行分配和回收就跟GC机制有关了。Java一般内存申请有两种:静态内存和动态内存。很容易理解,编译时就能够确定的内存就是静态内存,即内存是固定的,系统一次性分配,比如int类型变量;动态内存分配就是在程序执行时才知道要分配的存储空间大小,比如Java对象的内存空间。根据上面我们知道,Java栈、程序计数器、本地方法栈都是线程私有的,线程生就生,线程灭就灭,栈中的栈帧随着方法的结束也会撤销,内存自然就跟着回收了。所以这几个区域的内存分配与回收是确定的,我们不需要管的。但是Java堆和方法区则不一样,我们只有在程序运行期间才知道会创建哪些对象,所以这部分内存的分配和回收都是动态的。一般我们所说的垃圾回收也是针对的这一部分。

Stack的内存管理是顺序分配的,而且定长,不存在内存回收问题;而Heap 则是为Java对象的实例随机分配内存,不定长度,所以存在内存分配和回收的问题。垃圾收集器一般必须完成两件事:检测出垃圾;回收垃圾。

检测垃圾的方法有:

1.引用计数法:给一个对象添加引用计数器,每当有个地方引用它,计数器就加1;引用失效就减1。好了,问题来了,如果我有两个对象A和B,互相引用,除此之外,没有其他任何对象引用它们,实际上这两个对象已经无法访问,即是我们说的垃圾对象。但是互相引用,计数不为0,导致无法回收,所以还有另一种方法。

2.可达性分析算法:以根集对象为起始点进行搜索,如果有对象不可达的话,即是垃圾对象。这里的根集一般包括Java栈中引用的对象、方法区常量池中引用的对象、本地方法中引用的对象等。

JVM在做垃圾回收的时候,会检查堆中的所有对象是否会被这些根集对象引用,不能够被引用的对象就会被垃圾收集器回收。一般回收算法也有如下几种:

1.标记-清除(Mark-sweep):算法和名字一样,分为两个阶段:标记和清除。标记所有需要回收的对象,然后统一回收。这是最基础的算法,后续的收集算法都是基于这个算法扩展的。不足:效率低;标记清除之后会产生大量碎片

2.复制(Copying):此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。此算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不会出现“碎片”问题。当然,此算法的缺点也是很明显的,就是需要两倍内存空间。

3.标记-整理(Mark-Compact):此算法结合了“标记-清除”和“复制”两个算法的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把清除未标记对象并且把存活对象“压缩”到堆的其中一块,按顺序排放。此算法避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。

4.分代收集算法:这是当前商业虚拟机常用的垃圾收集算法。分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率。在Java程序运行的过程中,会产生大量的对象,因每个对象所能承担的职责不同所具有的功能不同所以也有着不一样的生命周期,有的对象生命周期较长,比如Http请求中的Session对象,线程,Socket连接等;有的对象生命周期较短,比如String对象,由于其不变类的特性,有的在使用一次后即可回收。试想,在不进行对象存活时间区分的情况下,每次垃圾回收都是对整个堆空间进行回收,那么消耗的时间相对会很长,而且对于存活时间较长的对象进行的扫描工作等都是徒劳。因此就需要引入分治的思想,所谓分治的思想就是因地制宜,将对象进行代的划分,把不同生命周期的对象放在不同的代上使用不同的垃圾回收方式。①年轻代:是所有新对象产生的地方。年轻代被分为3个部分——Enden区和两个Survivor区(From和to)当Eden区被对象填满时,就会执行Minor GC。并把所有存活下来的对象转移到其中一个survivor区(假设为from区)。Minor GC同样会检查存活下来的对象,并把它们转移到另一个survivor区(假设为to区)。这样在一段时间内,总会有一个空的survivor区。经过多次GC周期后,仍然存活下来的对象会被转移到年老代内存空间。通常这是在年轻代有资格提升到年老代前通过设定年龄阈值来完成的。需要注意,Survivor的两个区是对称的,没先后关系,from和to是相对的。②年老代:在年轻代中经历了N次回收后仍然没有被清除的对象,就会被放到年老代中,可以说他们都是久经沙场而不亡的一代,都是生命周期较长的对象。对于年老代和永久代,就不能再采用像年轻代中那样搬移腾挪的回收算法,因为那些对于这些回收战场上的老兵来说是小儿科。通常会在老年代内存被占满时将会触发Full GC,回收整个堆内存。③持久代:用于存放静态文件,比如Java类、方法等。持久代对垃圾回收没有显著的影响。

分布式

分布式就是把一个系统/业务拆分成多个子系统/子业务去协同处理,这个过程就叫分布式。

Java-HashMap原理

哈希表有多种不同的实现方法,最常用的一种方法是拉链法,可以理解为“链表的数组”。

哈希表是由数组+链表组成的,一个长度为16的数组中,每个元素存储的是一个链表的头结点。那么这些元素是按照什么样的规则存储到数组中呢。一般情况是通过hash(key)%len获得,也就是元素的key的哈希值对数组长度取模得到。比如上述哈希表中,12%16=12,28%16=12,108%16=12,140%16=12。所以12、28、108以及140都存储在数组下标为12的位置。

HashMap其实也是一个线性的数组实现的,所以可以理解为其存储数据的容器就是一个线性数组。

首先HashMap里面实现一个静态内部类Entry,其重要的属性有 key , value, next,从属性key,value我们就能很明显的看出来Entry就是HashMap键值对实现的一个基础bean,我们上面说到HashMap的基础就是一个线性数组,这个数组就是Entry[],Map里面的内容都保存在Entry[]里面。

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。

2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。

3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

Java日期时间格式

CST :China Standard Time, UTC+8:00 中国标准时间(北京时间),在东八区。

GMT :Greenwich Mean Time,格林威治标准时间,指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。

UTC :Universal Time Coordinated,世界协调时间,又称世界标准时间、世界统一时间。UTC 提供了一种与时区无关(或非特定于时区)的时间。

世界上的所有时区都可以表示为 UTC 加上或减去一个偏移量。因此,UTC是0时区的时间,如北京为早上八点(东八区),UTC时间就为零点,时间比北京时晚八小时。

数据库的时间字段starts存的是datetime类型,它是一个和时区相关的string(显然:string都是和时区相关的),而且数据库是按照CST时区存的时间。

Java.util.Date代表一个时间点,其值为距公元1970年1月1日 00:00:00的毫秒数,所以它是没有时区和Locale概念的。public long getTime() 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。

Java中通过如下形式取得当前时间点:Date now =new Date(); //这个时间点与本地系统的时区无关,而正因为其与时区的无关性,才使得我们的存储数据(时间)是一致的(时区一致性)。一般的我们将now存储于数据库中,当我们需要展现数据时,将now格式化成想要的格式,如:2011-12-04 21:22:24。而这个功能一般交由Java.text.DateFormat来实现。例如:默认情况下,SimpleDateFormat 取得本地系统的时区(我的时区为GMT+8北京),然后按照 pattern("yyyy-MM-dd HH:mm:ss")格式化now,此时输出的就是 GMT+8 区的时间了。如果想支持国际化时间,则先指定时区,然后再格式化date数据。

我们在开发和设计系统的时候注意三点:1.自己写公用类的时候,要对多线程调用情况下的后果在注释里进行明确说明。2.对线程环境下,对每一个共享的可变变量都要注意其线程安全性。3.我们的类和方法在做设计的时候,要尽量设计成无状态的。

关于SimpleDateFormat安全的时间格式化线程安全问题的解决办法:1.需要的时候创建新实例:在需要用到SimpleDateFormat 的地方新建一个实例,不管什么时候,将有线程安全问题的对象由共享变为局部私有都能避免多线程问题,不过也加重了创建对象的负担。在一般情况下,这样其实对性能影响比不是很明显的。2.使用同步:同步SimpleDateFormat对象。当线程较多时,当一个线程调用该方法时,其他想要调用此方法的线程就要block,多线程并发量大的时候会对性能有一定的影响。3.使用ThreadLocal:使用ThreadLocal, 也是将共享变量变为独享,线程独享肯定能比方法独享在并发环境中能减少不少创建对象的开销。如果对性能要求比较高的情况下,一般推荐使用这种方法。4.抛弃JDK,使用其他类库中的时间格式化类:①使用Apache commons 里的FastDateFormat,宣称是既快又线程安全的SimpleDateFormat, 可惜它只能对日期进行format, 不能对日期串进行解析。②使用Joda-Time类库来处理时间相关问题。

Java设计模式

设计模式来源众多专家的经验和智慧,它们是从许多优秀的软件系统中总结出的成功的、能够实现可维护性复用的设计方案,使用这些方案将可以让我们避免做一些重复性的工作;设计模式提供了一套通用的设计词汇和一种通用的形式来方便开发人员之间沟通和交流,使得设计方案更加通俗易懂;大部分设计模式都兼顾了系统的可重用性和可扩展性,这使得我们可以更好地重用一些已有的设计方案、功能模块甚至一个完整的软件系统,避免我们经常做一些重复的设计、编写一些重复的代码,许多设计模式将有助于提高系统的灵活性和可扩展性,让我们在不修改或者少修改现有系统的基础上增加、删除或者替换功能模块;合理使用设计模式并对设计模式的使用情况进行文档化,将有助于别人更快地理解系统;学习设计模式将有助于初学者更加深入地理解面向对象思想,让你知道:如何将代码分散在几个不同的类中?为什么要有“接口”?何谓针对抽象编程?何时不应该使用继承?如果不修改源代码增加新功能?同时还让你能够更好地阅读和理解现有类库(如JDK)与其他系统中的源代码。

在学习每一个设计模式时至少应该掌握如下几点:这个设计模式的意图是什么,它要解决一个什么问题,什么时候可以使用它;它是如何解决的,掌握它的结构图,记住它的关键代码;能够想到至少两个它的应用实例,一个生活中的,一个软件中的;这个模式的优缺点是什么,在使用时要注意什么。当你能够回答上述所有问题时,恭喜你,你了解一个设计模式了,至于掌握它,那就在开发中去使用吧,用多了你自然就掌握了。

模式从不保证任何东西,它不能保证你一定能够做出可复用的软件,提高你的生产率,更不能保证世界和平。模式并不能替代人来完成软件系统的创造,它们只不过会给那些缺乏经验但却具备才能和创造力的人带来希望。

观察者模式,有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。将一个系统分割成一个一些类相互协作的类有一个不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。

菜鸟教程有详细的设计模式学习教程。

数据库

一条sql执行过长的时间,要如何优化:

1、查看sql是否涉及多表的联表或者子查询,如果有,看是否能进行业务拆分,相关字段冗余或者合并成临时表(业务和算法的优化)。

2、涉及链表的查询,是否能进行分表查询,单表查询之后的结果进行字段整合。

3、如果以上两种都不能操作,非要链表查询,那么考虑对相对应的查询条件做索引,加快查询速度。

4、针对数量大的表进行历史表分离(如交易流水表)。

5、数据库主从分离,读写分离,降低读写针对同一表同时的压力,至于主从同步,mysql有自带的binlog实现主从同步。

6、explain分析sql语句,查看执行计划,分析索引是否用上,分析扫描行数等等。

7、查看mysql执行日志,看看是否有其他方面的问题。

8、从根本上来说,查询慢是占用mysql内存比较多,那么可以从这方面去考虑。

Java基础

==比较是否是同一个对象(纯指针操作);equals比较对象的内容。

重写equals为何要重写hashCode?回答:判断两个对象是否相等,比较的就是其hashCode, 如果你重载了equals,比如说是基于对象的内容实现的,而保留hashCode的实现不变,那么很可能某两个对象明明是“相等”,而hashCode却不一样。  hashcode不一样,就无法认定两个对象相等了。

表示不同文件类型的魔术数字,指定是文件的最开头的几个用于唯一区别其它文件类型的字节,有了这些魔术数字,我们就可以很方便的区别不同的文件,这也使得编程变得更加容易,因为减少了用于区别一个文件的文件类型所要花费的时间。

计算机专业基础 -- Java语言相关基础知识相关推荐

  1. 2,Java语言基础-Java语言基本程序设计知识

    Java语言基础 Java语言基本程序设计知识 1,JavaAPI概述 1.1,什么是API API是指应用程序接口( Application Program Interface, API),故名思意 ...

  2. 计算机专业毕业设计—JAVA语言系统设计(共80套打包)

    JAVA SMART系统-系统框架设计与开发(源代码+论文).rar java Smart系统-题库及试卷管理模块的设计与开发(源代码+论文) java Smart系统-题库及试卷管理模块的设计与开发 ...

  3. 1,Java语言基础-Java语言概述和必要计算机知识

    Java语言基础 Java语言概述 1,Java语言发展史 Java语言本质 Java是面向对象的高级语言,它是由c和c++发展而来. Java发展语言历史概述 Java 是由 James Gosli ...

  4. 计算机二级考试c语言公共知识,2016年电大最新计算机二级考试c语言公共基础题知识点.doc...

    2016年电大最新计算机二级考试c语言公共基础题知识点 计算机二级考试c语言公共基础题知识点第一章 数据结构与算法 1.1 算法 算法:是指解题方案的准确而完整的描述. 算法不等于程序,也不等计算机方 ...

  5. 晋中计算机专业对口大学,山西晋中计算机专业学校排名太重基础差也能上好学校...

    山西晋中计算机专业学校排名太重基础差也能上好学校.选专业的目标之一就是为未来的就业做准备.但在运用"就业率"作为参考依据时,不能仅凭就业率的数字高低来判断.专业不完全等同于职业,不 ...

  6. 2.1JAVA基础复习——JAVA语言的基础组成注释和常量变量

    JAVA语言的基础组成有: 1.关键字:被赋予特殊含义的单词. 2.标识符:用来标识的符号. 3.注释:用来注释说明程序的文字. 4.常量和变量:内存存储区域的表示. 5.运算符:程序中用来运算的符号 ...

  7. Java语言程序设计 基础篇 原书第10版 ,梁勇著,百度云链接及密码

    一本好书,对java小白来说是一本非常不错的书.第一次分享,请大家多多指教, Java语言程序设计 基础篇 原书第10版 ,梁勇著 链接:https://pan.baidu.com/s/1-MN_AS ...

  8. 计算机专业学不会C语言的 N 种死法!赶紧看看,你中了几条?

    以下是计算机专业学不会C语言的 N 种死法!学生党请进,老师们请绕路!(以免看到你学生学C语言时的真实情况) 1.听说明天就要开始学习C语言了,晚上睡不着觉兴奋死! 2.在C语言课上,老师讲得口沫横飞 ...

  9. java语言程序设计考点_计算机二级考试Java语言程序设计考点:关键字

    大家回忆一下我们在学习汉语的时候,开始学的是什么?肯定是先学一些单个的字,只有认识了单个的字,然后才能组成词,然后才能慢慢的到句子,然后到文章.学习同计算机交流跟这个过程是一样的,首先我们得学习一些计 ...

  10. 计算机专业英语外文翻译,计算机专业英语JAVA介绍外文翻译[共28页]

    <计算机专业英语JAVA介绍外文翻译[共28页]>由会员分享,可在线阅读,更多相关<计算机专业英语JAVA介绍外文翻译[共28页](28页珍藏版)>请在读根文库上搜索. 1.荆 ...

最新文章

  1. 计数排序之python
  2. BCH期货要来了?这家公司想让BCH成为第二大加密货币
  3. c++ 输入输出流  ios::out 和ios::trunc有什么区别
  4. CSS3实现漂亮ToolTips
  5. 【云快讯】之五十五《IBM推出Data Warehouse数据仓库云服务》
  6. How to Leak a Context: Handlers Inner Classes
  7. 使用ajax怎么解决乱码问题,一句话解决AJAX中文乱码问题[推荐]
  8. 性能测试之实现接口关联的两种方式:正则表达式提取器和json提取器
  9. arguments.callee弃用与webuploader
  10. 1.2 Illustrator多文档的几种排列方式
  11. CAJViwer安装提示:请求的操作需要提升
  12. Linux 添加一块新硬盘
  13. 高防服务器如何防御?
  14. 《大数据可视化》课后习题答案-何光威版
  15. 中国会计科目的中英文对照
  16. linux挂载u盘出错_linux挂载U盘、移动硬盘后无法更改权限
  17. 用python实现erp出入库_ERP采购入库成品入库流程(精)
  18. Doris:部署Broker
  19. UINO优诺:数字孪生可视化管理GIV,打造统览全局大视野
  20. 《大唐姻缘传》(李治篇) 第一章 天妒人眷 皇限将至

热门文章

  1. grafana安装配置 influxdb安装配置
  2. 授权其他数据库用户kill session
  3. [WCF编程]10.操作:请求/应答操作
  4. VBA读取固定文件夹中txt内容
  5. 公司周刊-非常6+1—营销平台小组
  6. [招聘]期待您的加盟,与博客园一起成长
  7. 群体智能优化算法之和声搜索(Harmony Search,HS)-附源码
  8. 洛谷——P1219 [USACO1.5]八皇后 Checker Challenge
  9. ArcGIS TIN地表面与栅格地表面的生成与互相转换
  10. c语言图像处理毕业设计,基于matlab数字图像处理毕业设计论文.doc