精华内容
下载资源
问答
  • 最新葵花宝典

    2012-01-09 12:29:31
    最新葵花宝典,涵盖JAVA基础和高级,面试过程中所遇到的有关技术的全部问题,在这里都可以的到答案,JAVA面试必备
  • 软件工程师面试必备:最新葵花宝典。囊括了目前java方向上,从基础到后学变化的几个阶段的知识。
  • 最新葵花宝典.Java软件工程师笔试面试必备
  • 鉴别3G iPhone翻新机器最新葵花宝典.doc
  • java最新面试葵花宝典

    2013-04-28 16:51:48
    java最新面试葵花宝典
  • 新版java面试葵花宝典

    2012-07-28 14:52:37
    新版java面试葵花宝典 为你JAVA面试提供很大的帮助
  • java最新面试之葵花宝典 java,jsp,集合框架,SSH面试题,
  • 最(全)面试葵花宝典 2012最新最全
  • 考研kira高数葵花宝典,原版的电子文件,不是扫描版,19考研最新
  • JAVA面试葵花宝典最新整理
  • java葵花宝典

    2012-09-01 10:59:57
    最新版的java葵花宝典,面试程序员职位的必备资源!
  • 葵花宝典

    万次阅读 2019-11-11 16:29:05
    target:用于指定链接页面的打开方式,其取值有_self和_blank两种,其中_self为默认值,_blank为在窗口中打开方式。 注意: 1.外部链接 需要添加 http:// www.baidu.com 2.内部链接 直接链接内部页面名称...

    WEB简介

    1.1web的诞生

    1986年美国国家科学基金会在政府的资助下,用TCP/IP协议建立了NSFNET网络。NSFNET网络与1989年改名为Internet,且向公众开放。从此,Internet便在全球各地普及起来。

    时至今日,Internet常用的服务可以概括至一下几种

    • E-mail:电子邮件

    • FTP:文件传输,用户可以通过该协议进行文件传输或者访问,由于安全问题,其使用场景越来越少

    • BBS:电子公告,最早主要用来是公布信息,现在的BBS已经发展成功能齐全的社区,可以实现信息公告、线上交谈、分类讨论、经验交流、文件共享等

    • WWW:world wide Web 中文名称万维网,也被称为Web,是Internet中发展最迅速的部分

    • Web是Internet的一个应用,它的诞生也是极其富有戏剧性的,具体同学们自己去了解

    1.2WEB相关概念

    1.2.1WWW

    ​ WWW,World Wide Web 的缩写,也可写为W3、Web,中文名为万维网。WWW是Internet的最核心部分。它是Internet上哪些支持WWW服务和HTTP协议的服务器集合

    ​ WWW在使用上分为Web客户端和Web服务器,用户可以使用Web客户端(即我们常说的浏览器)访问Web服务器上的页面

    1.2.2WebSite

    ​ WebSite,中文名为网站,是指在Internet上根据一定的规则,使用HTML等工具制作的用于展示特定内容相关网页的集合

    1.2.3URL

    ​ URL,Uniform Resource Locator的缩写,中文名为统一资源定位符,俗称网址,他是可以从互联网上得到的资源的位置和访问方法的一种简介的表示,是互联网上标准资源的地址。在WWW上浏览或者查询信息,必须在网页浏览器上输入查询目标的地址

    ​ URL的格式一般如下

    ​ 协议://主机地址(IP地址)+目录路径+参数 (主机地址和IP地址详解见两天讲AJAX的教案,属于计算机网络知识)

    ​ 常见的协议有

    http Hyper Text Transfer Protocol 超文本传输协议,适用于从万维网服务器传输超文本到本地浏览器的传输协议
    file 主要用于访问本地计算机中的文件(就是咱们平常通过sublime打开html文件时域名中的协议)
    ftp File Transfer Protocol 文件传输协议
    telent 允许用户通过一个协商过程与一个远程设备进行通信

    需要注意的是

    ​ 1.URL只能用ASCII字符集通过因特网进行发送,如果包含非ASCII字符集的字符,则需要进行转换。例如 中文会被转成一些带有%的字符串。(这就是为什么在处理get请求时咱们需要处理乱码问题的原因)

    ​ 2.URL中不能包括空格,URL编码通常会使用"+"替换空格,如“hello world”会转换成“hello+world”

    1.2.4 Web标准

    Web应用开发需要遵循的标准就是Web Standard(Web标准),这里Web标准是一系列标准的集合。网页主要由三部分组成:结构标准(XML、HTML、和XHTML),表现标准(CSS),行为标准(DOM,JavaScript)

    1.2.5Web浏览器

    ​ Web浏览器,简称浏览器,是一个显示网页服务器或者档案系统内的HTML文件,并让用户与这些文件互动的软件。主流浏览器有下列

    年份 所属人 浏览器名称 现状 内核
    1996 Microsoft Internet Explorer 2016年1月12日停止维护,由于历史原因,依然留存 Trident(IE内核)
    1996 TeleNor挪威电信 Oprea 现存 Presto,2013换成Blink
    2003 Apple Safari 现存 Webkit
    2004 Mozilla组织 FireFox 现存 Gecko
    2008 Google Google Chrome 现存 之前是webkit,2013年换成Blink
    2015 MicroSoft MicroSoft Edge 现存 EdgeHTML,2018年12月宣布换成Blink

    1.2.6Web服务器

    Web服务器的主要功能是提供网上信息浏览服务。Web服务器可以解析HTTP协议,当Web服务器接收到一个HTTP请求时,会返回一个HTTP响应,这样客户端就可与从服务器上获取网页(HTML),包括CSS JS 音频 视频等资源

    2019.11.5===============

    HTML

    1.1HTML简介

    超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言。

    • 基本组成标签
      • 声明为 HTML5 文档
      • 元素是 HTML 页面的根元素
      • 元素包含了文档的元(meta)数据,如 定义网页编码格式为 utf-8
      • 元素包含了可见的页面内容
    • 什么是HTML标签
      • HTML 指的是超文本标记语言: HyperText Markup Language
      • HTML 不是一种编程语言,而是一种标记语言
      • 标记语言是一套标记标签 (markup tag)
      • HTML 使用标记标签来描述网页
      • HTML 文档包含了HTML 标签文本内容
      • HTML文档也叫做 web 页面

    1.2HTML版本

    从初期的网络诞生后,已经出现了许多HTML版本:

    版本 发布时间
    HTML 1991
    HTML+ 1993
    HTML 2.0 1995
    HTML 3.2 1997
    HTML 4.01 1999
    XHTML 1.0 2000
    HTML5 2012
    XHTML5 2013

    1.2.1通用声明

    • HTML5
      • < !DOCTYPE html>
    • HTML 4.01
      • < !DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
        “http://www.w3.org/TR/html4/loose.dtd”>
    • XHTML 1.0
      • < !DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
        “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

    1.2.2字符集

    < meta charset=“UTF-8”>

    utf-8是目前最常用的字符集编码方式,常用的字符集编码方式还有gbk和gb2312。

    gb2312 简单中文 包括6763个汉字

    BIG5 繁体中文 港澳台等用

    GBK包含全部中文字符 是GB2312的扩展,加入对繁体字的支持,兼容GB2312

    UTF-8则包含全世界所有国家需要用到的字符

    通常我们一般都使用utf-8
    

    1.3HTML标签的语义化

    白话: 所谓标签语义化,就是指标签的含义。

    为什么要有语义化标签

    1. 方便代码的阅读和维护
    2. 同时让浏览器或是网络爬虫可以很好地解析,从而更好分析其中的内容
    3. 使用语义化标签会具有更好地搜索引擎优化

    核心:合适的地方给一个最为合理的标签。

    语义是否良好: 当我们去掉CSS之后,网页结构依然组织有序,并且有良好的可读性。

    不管是谁都能看懂这块内容是什么。

    遵循的原则:先确定语义的HTML ,再选合适的CSS。

    1.4HTML标签(重要)

    1.4.1排版标签

    排版标签主要和css搭配使用,显示网页结构的标签,是网页布局最常用的标签。

    1.4.1.1标题标签 (熟记)

    单词缩写: head 头部. 标题

    为了使网页更具有语义化,我们经常会在页面中用到标题标签,HTML提供了6个等级的标题,即

    <h1>、<h2>、<h3>、<h4>、<h5>和<h6>

    标题标签语义:  作为标题使用,并且依据重要性递减
    

    其基本语法格式如下:

    <hn>   标题文本   </hn>
    

    注意: h1 标签因为重要,尽量少用,不要动不动就向你扔了一个h1。 一般h1 都是给logo使用。

    1.4.1.2段落标签( 熟记)

    单词缩写: paragraph 段落

    在网页中要把文字有条理地显示出来,离不开段落标签,就如同我们平常写文章一样,整个网页也可以分为若干个段落,而段落的标签就是

    <p>  文本内容  </p>
    

    是HTML文档中最常见的标签,默认情况下,文本在一个段落中会根据浏览器窗口的大小自动换行。

    1.4.1.3水平线标签

    单词缩写: horizontal 横线

    在网页中常常看到一些水平线将段落与段落之间隔开,使得文档结构清晰,层次分明。这些水平线可以通过插入图片实现,也可以简单地通过标签来完成,


    就是创建横跨网页水平线的标签。其基本语法格式如下:

    <hr />是单标签
    

    在网页中显示默认样式的水平线。

    1.4.1.4换行标签(熟记)

    单词缩写: break 打断 ,换行

    在HTML中,一个段落中的文字会从左到右依次排列,直到浏览器窗口的右端,然后自动换行。如果希望某段文本强制换行显示,就需要使用换行标签

    <br />
    

    这时如果还像在word中直接敲回车键换行就不起作用了。

    1.4.1.5div span标签(重点)

    div span 是没有语义的 是我们网页布局主要的2个盒子

    div 就是 division 的缩写 分割, 分区的意思 其实有很多div 来组合网页。

    span, 跨度,跨距;范围

    语法格式:

    <div> 这是头部 </div>    <span>今日价格</span>
    

    1.4.1.6文本格式化标签(熟记)

    在网页中,有时需要为文字设置粗体、斜体或下划线效果,这时就需要用到HTML中的文本格式化标签,使文字以特殊的方式显示。

    b i s u 只有使用 没有 强调的意思 strong em del ins 语义更强烈

    1.4.1.7标签属性

    属性就是特性 比如 手机的颜色 手机的尺寸 ,总结就是手机的。。

    使用HTML制作网页时,如果想让HTML标签提供更多的信息,可以使用HTML标签的属性加以设置。其基本语法格式如下:

    <标签名 属性1="属性值1" 属性2="属性值2" > 内容 </标签名>
    

    语法规则(牢记)

    1.标签可以拥有多个属性,必须写在开始标签中,位于标签名后面。

    2.属性之间不分先后顺序,标签名与属 性、属性与属性之间均以空格分开。

    3.任何标签的属性都有默认值,省略该属性则取默认值。

    采取 键值对 的格式 key=“value” 的格式

    比如:

    <hr width="400" />   
    

    1.4.1.8图像标签img (重点)

    单词缩写: image 图像

    HTML网页中任何元素的实现都要依靠HTML标签,要想在网页中显示图像就需要使用图像标签,接下来将详细介绍图像标签以及和他相关的属性。其基本语法格式如下:

    该语法中src属性用于指定图像文件的路径和文件名,他是img标签的必需属性。

    <img src="图像URL" />
    

    1.4.1.9链接标签(重点)

    单词缩写: anchor 的缩写 。基本解释 锚, 铁锚 的

    在HTML中创建超链接非常简单,只需用标签环绕需要被链接的对象即可,其基本语法格式如下:

    <a href="跳转目标" target="目标窗口的弹出方式">文本或图像</a>
    

    href:用于指定链接目标的url地址,当为标签应用href属性时,它就具有了超链接的功能。 Hypertext Reference的缩写。意思是超文本引用

    target:用于指定链接页面的打开方式,其取值有_self和_blank两种,其中_self为默认值,_blank为在新窗口中打开方式。

    注意:

    1.外部链接 需要添加 http:// www.baidu.com

    2.内部链接 直接链接内部页面名称即可 比如 < a href=“index.html”> 首页

    3.如果当时没有确定链接目标时,通常将链接标签的href属性值定义为“#”(即href="#"),表示该链接暂时为一个空链接。

    4.不仅可以创建文本超链接,在网页中各种网页元素,如图像、表格、音频、视频等都可以添加超链接。

    1.4.1.9.1锚点定位 (难点)

    通过创建锚点链接,用户能够快速定位到目标内容。
    创建锚点链接分为两步:

    1.使用“a href=”#id名>“链接文本"</a>创建链接文本。
    
    2.使用相应的id名标注跳转目标的位置。
    

    1.4.1.9.2base 标签

    base 可以设置整体链接的打开状态

    base 写到 之间

    1.4.1.10特殊字符标签

    1.4.1.11注释标签

    在HTML中还有一种特殊的标签——注释标签。如果需要在HTML文档中添加一些便于阅读和理解但又不需要显示在页面中的注释文字,就需要使用注释标签。其基本语法格式如下:

        <!-- 注释语句 -->
    

    注释内容不会显示在浏览器窗口中,但是作为HTML文档内容的一部分,也会被下载到用户的计算机上,查看源代码时就可以看到。

    1.5路径

    路径可以分为: 相对路径和绝对路径

    1.5.1对路径

    1. 图像文件和HTML文件位于同一文件夹:只需输入图像文件的名称即可,如<img src=“logo.gif” />。
    2. 图像文件位于HTML文件的下一级文件夹:输入文件夹名和文件名,之间用“/”隔开,如<img src=“img/img01/logo.gif” />。
    3. 图像文件位于HTML文件的上一级文件夹:在文件名之前加入“…/” ,如果是上两级,则需要使用 “…/ …/”,以此类推,如<img src="…/logo.gif" />。

    1.5.2绝对路径

    绝对路径

    “D:\web\img\logo.gif”,或完整的网络地址,例如“http://www.itcast.cn/images/logo.gif”。

    1.6列表标签

    什么是列表?

    把数据制成表,以表显示

    容器里面装载着文字或图表的一种形式,叫列表。

    列表最大的特点就是 整齐 、整洁、 有序

    1.6.1无序列表 ul (重点)

    无序列表的各个列表项之间没有顺序级别之分,是并列的。其基本语法格式如下:

    <ul>
      <li>列表项1</li>
      <li>列表项2</li>
      <li>列表项3</li>
      ......
    </ul>
    

    注意

     1. <ul></ul>中只能嵌套<li></li>,直接在<ul></ul>标签中输入其他标签或者文字的做法是不被允许的。
     2. <li>与</li>之间相当于一个容器,可以容纳所有元素。
     3. 无序列表会带有自己样式属性,可以用css清楚样式
    

    1.6.2有序列表 ol

    有序列表即为有排列顺序的列表,其各个列表项按照一定的顺序排列定义,有序列表的基本语法格式如下:

    <ol>
      <li>列表项1</li>
      <li>列表项2</li>
      <li>列表项3</li>
      ......
    </ol>
    

    所有特性基本与ul 一致。

    但是实际工作中, 较少用 ol ,但1+X的缘故,同学们也要将其记住

    1.6.3自定义列表

    定义列表常用于对术语或名词进行解释和描述,定义列表的列表项前没有任何项目符号。其基本语法如下:

    <dl>
      <dt>名词1</dt>
      <dd>名词1解释1</dd>
      <dd>名词1解释2</dd>
      ...
      <dt>名词2</dt>
      <dd>名词2解释1</dd>
      <dd>名词2解释2</dd>
      ...
    </dl>
    
    展开全文
  • 初等代数从最简单的一元一次方程开始,初等代数一方面进而讨论二元及三元的一次方程组,另一方面研究二次以上及可以转化为二次的方程组。沿着这两个方向继续发展,代数在讨论任意多个未知数的一次方程组,也叫线性...
  • 2019最新java面试葵花宝典 转载自:作者 the Rune Mage 原文地址:https://blog.csdn.net/weixin_38405770/article/details/86657613 [转] 15年毕业到现在也近四年了,最近面试了阿里集团(菜鸟网络...

    转载自:作者 the Rune Mage
    原文地址:https://blog.csdn.net/weixin_38405770/article/details/86657613

    [转] 15年毕业到现在也近四年了,最近面试了阿里集团(菜鸟网络,蚂蚁金服),网易,滴滴,点我达,最终收到点我达,网易offer,蚂蚁金服二面挂掉,菜鸟网络一个月了还在流程中,最终有幸去了网易。
    但是要特别感谢点我达的领导及HR,真的非常非常好,很感谢他们一直的关照和指导。
    回家后,我对这次面试经历,做了总结,希望对想要跳槽的朋友们有个借鉴。

    面试整体事项

    1.简历要准备好,联系方式一定要正确清晰醒目,项目经历按照时间倒序阐述,注意描述自己在项目中承担的职责,简历的模板尽量选择简洁的,毕竟程序员大部分还是喜欢简单明了的。
    2.推荐boss直聘,我觉得很好用(不是广告)。
    3.一般的整体面试流程都是电面->现场面->HR面->等着。
    4.不要觉得HR说让你回去等消息就是GG了,他们也要跟你之前的面试官讨论,再向领导汇报,如果说不急可能还要和其他候选人比较,所以HR让你回去等消息绝对不是说明你完蛋了。
    5.面试前准备好自我介绍,1分钟左右就可以,可以写在纸上,电面可以照着念,等你到了现场面了基本也都快背下来你的自我介绍了。
    6.准备好扎实的基础,这是一切的根源,没实力怎么都没用的。
    7.面试中你可以把你的面试官往你会的知识上引导(我遇到过你会什么他不问什么的)。
    8.遇到了设计类题目不要着急,面试官不是为了让你几分钟设计一个高并发高可用设计模式完美的架构,只是想看看你的思路,看看你应变的能力,然后给你些提示看看你能否迅速的调整。
    9.offer都会有的,不要着急,把面试当成一个交流的过程。

    需要准备的知识

    以下为在近期面试中比较有印象的问题,也就不分公司了,因为没什么意义,大致分类记录一下,目前只想起这么多,不过一定要知道这些问题只是冰山一角,就算都会了也不能怎么样,最最重要的,还是坚实的基础,清醒的头脑。

    java面试题

    Java基础

    1.HashMap的源码,实现原理,JDK8中对HashMap做了怎样的优化。

    点击查看HashMap原理浅析

    2.HaspMap扩容是怎样扩容的,为什么都是2的N次幂的大小。

    点击查看HashMap扩容

    3.HashMap,HashTable,ConcurrentHashMap的区别。

    点击查看

    4.极高并发下HashTable和ConcurrentHashMap哪个性能更好,为什么,如何实现的。

    • HashTable使用一把锁处理并发问题,当有多个线程访问时,需要多个线程竞争一把锁,导致阻塞
    • ConcurrentHashMap则使用分段,相当于把一个HashMap分成多个,然后每个部分分配一把锁,这样就可以支持多线程访问

    5.HashMap在高并发下如果没有处理线程安全会有怎样的安全隐患,具体表现是什么。

    • 多线程put时可能会导致get无限循环,具体表现为CPU使用率100%;

      原因:在向HashMap put元素时,会检查HashMap的容量是否足够,如果不足,则会新建一个比原来容量大两倍的Hash表,然后把数组从老的Hash表中迁移到新的Hash表中,迁移的过程就是一个rehash()的过程,多个线程同时操作就有可能会形成循环链表,所以在使用get()时,就会出现Infinite Loop的情况

    • 多线程put时可能导致元素丢失

      原因:当多个线程同时执行addEntry(hash,key ,value,i)时,如果产生哈希碰撞,导致两个线程得到同样的bucketIndex去存储,就可能会发生元素覆盖丢失的情况

    6.java中四种修饰符的限制范围。

    访问权限 本类 本包 不同包子类 不同包非子类
    public
    protected
    default
    private

    7.Object类中的方法。

    • 1),构造函数

    • 2),hashCode和equale函数用来判断对象是否相同,

      equale()用于确认两个对象是否相同。hashCode()用于获取对象的哈希值,这个值的作用是检索,具体的作用可以参考这里。哈希值相同的对象不一定equale(),equale()返回true的两个对象一定相同。

    • 3),wait(),wait(long),wait(long,int),notify(),notifyAll()

      这几个函数体现的是Java的多线程机制
      在使用的时候要求在synchronize语句中使用
      wait()用于让当前线程失去操作权限,当前线程进入等待序列
      notify()用于随机通知一个持有对象的锁的线程获取操作权限
      notifyAll()用于通知所有持有对象的锁的线程获取操作权限
      wait(long) 和wait(long,int)用于设定下一次获取锁的距离当前释放锁的时间间隔

    • 4),toString()和getClass,

      toString()返回一个String对象,用来标识自己
      getClass()返回一个Class对象,如果打印出来会发现结果是如下格式

      class package.name.xxx 
      

        因为返回的是一个class对象,后面可以跟class类的方法。用的是谁的构造函数,那么getClass返回的就是谁的类型。
        getClass()经常用于java反射机制

      • 5),clone()

        clone()函数的用途是用来另存一个当前存在的对象。

      • 6),finalize()用于在垃圾回收

        这个函数在进行垃圾回收的时候会用到,匿名对象回收之前会调用到,具体的例子如下所示

       package com.ziyear;
       
       public class Test{
       	public static void main(String[] args) {
       		new Test();
       		System.gc();
       	}
      
      	@Override
      	protected void finalize() throws Throwable {
      		System.out.println("This is Test finalize()");
      	}
      }
        
      

      输出:

      This is Test finalize()
      

      8.接口和抽象类的区别,注意JDK8的接口可以有实现。

      参数 抽象类 接口
      默认的方法实现 它可以有默认的方法实现 接口完全是抽象的,他不存在方法的实现,1.8后它可以有默认的方法实现
      实现 子类使用extends关键字来继承抽象类,如果子类不是抽象类的话,他需要提供抽象类中所有声明的方法的实现 子类使用关键字implements来实现接口,他需要提供接口中所有生命的方法的实现,1.8排除默认实现的方法
      构造器 抽象类中可以有构造器 接口中不能有构造器
      与正常java类的区别 除了你不能实例化抽象类外,它和普通java类没有任何区别 接口是完全不同的类型
      访问修饰符 抽象方法可以有pubic,protected这些修饰符 接口方法默认修饰符是public,你不可以使用其他修饰符,1.8增加default修饰默认实现
      main方法 抽象类中可以有main方法并可以运行它 接口中没有main方法,因此我们不能运行它
      多继承 抽象类可以继承一个类实现多个接口 接口只能继承一个或多个接口
      速度 它比接口速度要快 接口速度稍慢,因为它需要时间去寻找在类中实现的方法
      添加新方法 如果你往抽象类中添加新方法,你可以给他提供默认的实现,因此你不需要改变你现在的代码 如果你往接口中添加新的方法,你必须改变实现接口的实现类,1.8后如果在接口中添加默认实现的方法则不需要.
      变量 和普通java类相同 接口中只能有static、final变量,不能有其他变量。

      9.动态代理的两种方式,以及区别。

      • 若目标对象实现了若干接口,使用JDK的java.lang.reflect.Proxy类代理。

        利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
        优点:因为有接口,所以使系统更加松耦合
        缺点:为每一个目标类创建接口

      • 若目标对象没有实现任何接口,使用CGLIB库生成目标对象的子类。

        利用ASM(开源的Java字节码编辑库,操作字节码)开源包,将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
        优点:因为代理类与目标类是继承关系,所以不需要有接口的存在。
        缺点:因为没有使用接口,所以系统的耦合性没有使用JDK的动态代理好。

      • 总结:
        JDK代理只能对实现接口的类生成代理,CGlib是针对类实现代理,对指定的类生成一个子类,并覆盖其中的方法,这种通过继承类的实现方式,不能代理final修饰的类。
        JDK代理使用的是反射机制实现aop的动态代理,CGLIB代理使用字节码处理框架asm,通过修改字节码生成子类。所以jdk动态代理的方式创建代理对象效率较高,执行效率较低,cglib创建效率较低,执行效率高;
        JDK动态代理机制是委托机制,具体说动态实现接口类,在动态生成的实现类里面委托hanlder去调用原始实现类方法,CGLIB则使用的继承机制,具体说被代理类和代理类是继承关系,所以代理类是可以赋值给被代理类的,如果被代理类有接口,那么代理类也可以赋值给接口。

      10.Java序列化的方式。

      11.传值和传引用的区别,Java是怎么样的,有没有传值引用。

      传值还是传引用?

      ​ Java中没有引用传递,Java所有操作都是传值操作!都是传值操作!都是传值操作!重要的事情说三遍。

      12.一个ArrayList在循环过程中删除,会不会出问题,为什么。

      一个ArrayList在循环过程中删除,会不会出问题,为什么?

      ​ for循环遍历,存在漏删

      ​ foreach循环删除,抛出异常ConcurrentModificationException

      foreach循环删除集合中倒数第二个对象时不会发生ConcurrentModificationException异常

      13.@transactional注解在什么情况下会失效,为什么。

      @transactional注解在什么情况下会失效,为什么。

      ​ 默认情况下,Spring会对unchecked异常进行事务回滚

      ​ 类似的还有norollbackFor,自定义不回滚的异常 等;

      数据结构和算法

      1.B+树。

      B树和B+树的插入、删除图文详解

      2.快速排序,堆排序,插入排序(其实八大排序算法都应该了解)

      八种常见经典排序算法

      3.一致性Hash算法,一致性Hash算法的应用。

      对一致性Hash算法,Java代码实现的深入研究
      白话解析:一致性哈希算法

      JVM

      1.JVM的内存结构。

      全面理解Java内存模型

      全面理解Java内存模型(JMM)及volatile关键字

      JDK1.8 JVM运行时数据区域划分

      2.JVM方法栈的工作过程,方法栈和本地方法栈有什么区别。

      • 虚拟机栈(方法栈)
        与程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期与线程相同。虚拟机描述的是Java方法执行的内存模型:
        每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,就对应这一个栈帧在虚拟机栈中入栈到出栈的过程。
        局部变量表存放了编译器可知的各种基本数据类型,对象引用类型,它不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置和returnAddress类型(指向了同一条字节码指令的地址)。
        其中64位长度的long和double类型的数据会占用2个局部变量空间,其余的数据类型只占用一个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配出多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变脸表的大小。
        在Java虚拟机规范中,对这个区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展(当前大部分的Java虚拟机都可以动态扩展,只不过Java虚拟机规范中也允许固定长度的虚拟机栈),如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

      • 本地方法栈
        本地方法栈和虚拟机栈所发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈是非虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机执行Native方法服务的。在虚拟机规范中对本地方法栈中方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它。甚至有的虚拟机直接将本地方法栈和虚拟机栈合二为一。与虚拟机栈一样,本地方法栈区域会抛出StackOverflowError异常和OutOfMemoryError异常。

      3.JVM的栈中引用如何和堆中的对象产生关联。

      ​ 对象生成时,产生的首地址存储在栈中,这样两者就关联起来了。

      4.可以了解一下逃逸分析技术。

      Java之JVM逃逸分析

      5.GC的常见算法,CMS以及G1的垃圾回收过程,CMS的各个阶段哪两个是Stop the world的,CMS会不会产生碎片,G1的优势。

      JVM 垃圾回收机制和常见算法

      常见GC算法,CMS以及G1的垃圾回收过程,CMS的各个阶段哪两个是Stop the world的,CMS会不会产生碎片,G1的优势。

      G1和CMS垃圾收集器

      为什么CMS两次标记时要 stop the world
      详解 JVM Garbage First(G1) 垃圾收集器
      ​ CMS-initial-mark 初始标记和CMS-remark 重新标记会Stop the world

      ​ 由于CMS采用标记清除算法,默认并不使用标记整理算法,可能会产生很多碎片,因此,这些碎片无法完成大对象向老年带转移,因此需要进行CMS在老年带的Full GC来合并碎片。

      • ​G1是一款面向服务端应用的垃圾收集器。G1具备如下特点:
        1、并行于并发:G1能充分利用CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短stop-The-World停顿时间。部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让java程序继续执行。
        2、分代收集:虽然G1可以不需要其他收集器配合就能独立管理整个GC堆,但是还是保留了分代的概念。它能够采用不同的方式去处理新创建的对象和已经存活了一段时间,熬过多次GC的旧对象以获取更好的收集效果。
        3、空间整合:与CMS的“标记–清理”算法不同,G1从整体来看是基于“标记整理”算法实现的收集器;从局部上来看是基于“复制”算法实现的。
        4、可预测的停顿:这是G1相对于CMS的另一个大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,
        5、G1运作步骤:
        1、初始标记;2、并发标记;3、最终标记;4、筛选回收
        上面几个步骤的运作过程和CMS有很多相似之处。初始标记阶段仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS的值,让下一个阶段用户程序并发运行时,能在正确可用的Region中创建新对象,这一阶段需要停顿线程,但是耗时很短,并发标记阶段是从GC Root开始对堆中对象进行可达性分析,找出存活的对象,这阶段时耗时较长,但可与用户程序并发执行。而最终标记阶段则是为了修正在并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录,虚拟机将这段时间对象变化记录在线程Remenbered Set Logs里面,最终标记阶段需要把Remembered Set Logs的数据合并到Remembered Set Logs里面,最终标记阶段需要把Remembered Set Logs的数据合并到Remembered Set中,这一阶段需要停顿线程,但是可并行执行。最后在筛选回收阶段首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划。

      6.标记清除和标记整理算法的理解以及优缺点。

      • 第一种:标记清除
        它是最基础的收集算法。
        原理:分为标记和清除两个阶段:首先标记出所有的需要回收的对象,在标记完成以后统一回收所有被标记的对象。
        特点:(1)效率问题,标记和清除的效率都不高;(2)空间的问题,标记清除以后会产生大量不连续的空间碎片,空间碎片太多可能会导致程序运行过程需要分配较大的对象时候,无法找到足够连续内存而不得不提前触发一次垃圾收集。
        地方 :适合在老年代进行垃圾回收,比如CMS收集器就是采用该算法进行回收的。

      • 第二种:标记整理
        原理:分为标记和整理两个阶段:首先标记出所有需要回收的对象,让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。
        特点:不会产生空间碎片,但是整理会花一定的时间。
        地方:适合老年代进行垃圾收集,parallel Old(针对parallel scanvange gc的) gc和Serial old收集器就是采用该算法进行回收的。

      7.eden survivor区的比例,为什么是这个比例,eden survivor的工作过程? JVM如何判断一个对象是否该被GC,可以视为root的都有哪几种类型? Java有没有主动触发GC的方式(没有)?Java是否可以GC直接内存。?

      [JVM] java虚拟机内存管理机制及垃圾收集

      8.强软弱虚引用的区别以及GC对他们执行怎样的操作。

      从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用。

      • 强引用
        如果一个对象具有强引用,那么垃圾回收器绝不会回收它。哪怕内存空 间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。

      • 软引用
        如果一个对象只具有软引用,如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。

      • 弱引用
        如果一个对象只具有弱引用,垃圾回收器一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。

      • 虚引用
        "虚引用"顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。 虚引用主要用来跟踪对象被垃圾回收的活动。

      9.Java类加载的过程。

      java中类的加载顺序介绍(ClassLoader)

      10.双亲委派模型的过程以及优势。

      JVM类加载机制之双亲委派模型

      类加载器与双亲委派模型

      • 双亲委派模型的实现过程:

        实现双亲委派模型的代码都集中在java.lang.ClassLoader的loadClass()方法中:
        首先会检查请求加载的类是否已经被加载过;
        若没有被加载过:
        递归调用父类加载器的loadClass();
        父类加载器为空后就使用启动类加载器加载;
        如果父类加载器和启动类加载器均无法加载请求,则调用自身的加载功能。

      • 双亲委派模型的优点:
        Java类伴随其类加载器具备了带有优先级的层次关系,确保了在各种加载环境的加载顺序。
        保证了运行的安全性,防止不可信类扮演可信任的类。

      11.常用的JVM调优参数。

      JVM解读-调优常用参数

      JVM-调优参数-JDK1.8

      12.dump文件的分析。

      Java内存泄漏分析系列之六:JVM Heap Dump(堆转储文件)的生成和MAT的使用
      JConsole
      Jhat
      GcViewer
      IBM Heap Analyzer

      多线程

      1.Java实现多线程有哪几种方式。

      2.Callable和Future的了解。

      Java多线程编程:Callable、Future和FutureTask浅析

      3.线程池的参数有哪些,在线程池创建一个线程的过程。

      Java并发编程:线程池的使用

      4.volitile关键字的作用,原理。

      volatile关键字的作用、原理

      5.synchronized关键字的用法,优缺点。

      synchronized关键字用法

      6.Lock接口有哪些实现类,使用场景是什么。

      Java并发编程:Lock

      7.悲观锁,乐观锁,优缺点,CAS有什么缺陷,该如何解决。

      悲观锁、乐观锁 乐观锁的一种实现方式-CAS

      8.ABC三个线程如何保证顺序执行。

      三个线程轮流执行顺序打印ABC

      如何确保三个线程顺序执行?

      9.线程的状态都有哪些。

      线程的五大状态

      10.sleep和wait的区别。

      1. 对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。
      2. sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。
      3. 在调用sleep()方法的过程中,线程不会释放对象锁。
      4. 而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

      11.notify和notifyall的区别。

      先说两个概念:锁池和等待池

      • 锁池:假设线程A已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用这个对象的某个synchronized方法(或者synchronized块),由于这些线程在进入对象的synchronized方法之前必须先获得该对象的锁的拥有权,但是该对象的锁目前正被线程A拥有,所以这些线程就进入了该对象的锁池中。
      • 等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池中

      Reference:java中的锁池和等待池

      然后再来说notify和notifyAll的区别

      • 如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁
      • 当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争
      • 优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用 wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。

      Reference:线程间协作:wait、notify、notifyAll

      ​ 综上,所谓唤醒线程,另一种解释可以说是将线程由等待池移动到锁池,notifyAll调用后,会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则留在锁池等待锁被释放后再次参与竞争。而notify只会唤醒一个线程。

      12.ThreadLocal的了解,实现原理。

      深入剖析ThreadLocal实现原理以及内存泄漏问题

      揭秘ThreadLocal

      13.Fork/Join框架介绍及实例讲解
      Fork/Join框架详解
      JAVA中的Fork/Join框架
      Fork/Join框架及其性能介绍
      运用ForkJoin多线程框架实现归并排序
      14.CountDownLatch、CyclicBarrier和 Semaphore
      CountDownLatch、CyclicBarrier和 Semaphore

      15.AQS
      Java并发之AQS详解

      Java并发之AQS详解

      数据库相关

      1.常见的数据库优化手段

      sql优化的几种方法

      2.索引的优缺点,什么字段上建立索引

      建立数据库索引的优缺点,分析一张表上如何建立索引

      Mysql性能优化

      3.数据库连接池。

      Druid 介绍及配置

      Druid数据库连接池两种简单使用方式

      4.数据库事务。

      MySQL——事务(Transaction)详解

      5.数据库锁。

      数据库死锁分析与解决

      计算机网络

      1.TCP,UDP区别。

      • TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
      • TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
      • TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
      • 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
      • TCP首部开销20字节;UDP的首部开销小,只有8个字节
      • TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

      2.三次握手,四次挥手,为什么要四次挥手。

      理解TCP/IP三次握手与四次挥手的正确姿势

      3.长连接和短连接。

      • 在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。

      • 而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:

      Connection:keep-alive
      
      • 1
      • 在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。

      • HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

      4.连接池适合长连接还是短连接。

      ​ 我的的理解最大连接数减去最小连接数为短连接,最小连接数是长连接。

      设计模式

      1.观察者模式

      JAVA设计模式之观察者模式

      2.代理模式

      设计模式—代理模式

      3.单例模式,有五种写法,可以参考文章单例模式的五种实现方式

      单例模式的八种写法比较

      4.可以考Spring中使用了哪些设计模式

      spring中的设计模式

      分布式相关

      1.分布式事务的控制。

      一篇文章带你学习分布式事务

      常用的分布式事务解决方案

      分布式事务几种实现方式

      2.分布式锁如何设计。

      【分布式缓存系列】集群环境下Redis分布式锁的正确姿势

      【分布式缓存系列】Redis实现分布式锁的正确姿势

      3.分布式session如何设计。

      集群/分布式环境下5种session处理策略

      分布式集群系统下的高可用session解决方案—Session共享

      Shiro集成Redis实现分布式集群Session共享

      4.dubbo的组件有哪些,各有什么作用。

      • Dubbo需要四大基本组件:Registry、Monitor、Provider、Consumer。
      • Provider:提供者
      • Consumer:消费者
      • registry:注册中心(相当于中介)
      • monitor:监控中心

      5.dubbo是如何利用接口就可以通信的。

      Dubbo基本原理机制

      6.Zookeeper的负载均衡算法有哪些。

      zookeeper 负载均衡 核心机制-实现原理 包含ZAB协议

      缓存相关

      1.Redis有哪些适合的场景?

      • ​(1)、会话缓存(Session Cache)

        最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?

        幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。

      • (2)、全页缓存(FPC)

        除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。

        再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。

        此外,对WordPress的用户来说,Pantheon有一个非常好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。

      • (3)、队列

        Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。

        如果你快速的在Google中搜索“Redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用Redis创建非常好的后端工具,以满足各种队列需求。例如,Celery有一个后台就是使用Redis作为broker,你可以从这里去查看。

      • (4),排行榜/计数器

        Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:

        当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行:

        ZRANGE user_scores 0 10 WITHSCORES

        Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你可以在这里看到。

      • (5)、发布/订阅

        最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!(不,这是真的,你可以去核实)。

      2.redis支持哪些数据结构。

      ​ String、List、Set、Sorted Set、hashes

      3.redis是单线程的么,所有的工作都是单线程么。

      ​ 是的,都是单线程

      ​ redis为什么不用多线程(不划算呗)

      ​ (1)纯内存操作;

      ​ (2)多线程仍然会有上下文切换的损耗,虽然比进程切换损耗小;

      ​ (3)采用了非阻塞I/O多路复用机制

      4.使用过Redis分布式锁么,它是什么回事?
      先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。
      这时候对方会告诉你说你回答得不错,然后接着问如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?
      这时候你要给予惊讶的反馈:唉,是喔,这个锁就永远得不到释放了。紧接着你需要抓一抓自己得脑袋,故作思考片刻,好像接下来的结果是你主动思考出来的,然后回答:我记得set指令有非常复杂的参数,这个应该是可以同时把setnx和expire合成一条指令来用的!对方这时会显露笑容,心里开始默念:嗯,这小子还不错。

      5.redis的部署方式,主从,集群。

      redis单例、主从模式、sentinel以及集群的配置方式及优缺点对比

      6.redis持久化策略。

      Redis学习笔记9–Redis持久化

      框架相关

      1.SpringMVC请求流程

      一张图理清SpringMVC工作原理

      2.Mybatis如何找到指定的Mapper的,如何完成查询的。

      mybatis如何通过接口查找对应的mapper.xml及方法执行详解

      3.Quartz是如何完成定时任务的。

      Quartz的定时任务实现

      4.自定义注解的实现。

      注解Annotation实现原理与自定义注解例子

      5.Spring使用了哪些设计模式。

      spring中的设计模式

      6.Spring的IOC有什么优势。

      谈谈对Spring IOC的理解

      Spring IoC有什么好处呢?

      6.Spring的AOP有什么优势。

      AOP——SpringAOP

      Spring3:AOP

      我们使用AOP的好处

      7.Spring如何维护它拥有的bean。

      Spring Bean的生命周期

      8.常用框架整理。
      SpringIOC

      SpringMVC常见面试题总结(超详细回答)

      Struts2相关面试题

      Spring常见面试题总结

      Mybatis 框架实现原理

      Mybatis 的常见面试题

      Mybatis常见面试题总结

      java面试——Hibernate常见面试题

      Hibernate面试精华知识点---------不看你会后悔

      Other

      1.JDK8的新特性,流的概念及优势,为什么有这种优势。

      【读书笔记】《写给大忙人看的Java SE 8》——Java8新特性总结

      Java8新特性

      一些小建议

      1.可以去leetcode上刷题换换思路。
      2.八大排序算法一定要手敲一遍(快排,堆排尤其重要)。
      3.了解一些新兴的技术。
      4.面试之后面试官都会问你有没有什么问题,千万不要没问题,也别傻乎乎的问一些敏感问题。
      5.了解你要面试的公司的产品及竞争产品。

      无论是哪家公司,都很重视高并发高可用的技术、重视基础和JVM。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,这样会不利于自己的发挥。在面试过程中也不应该只看中薪资,还要看你是不是真的喜欢这家公司,是不是能真的得到锻炼。
      最后,希望大家都能找到适合自己的公司,开开心心的撸代码。

      展开全文
    • Java葵花宝典

      2012-12-28 11:57:10
      Java程序员面试过程中应付笔试的必备书籍。根据我多年的面试经验,公司招聘Java程序员,70%以上的题都囊括在本书中,甚至直接就...如果想顺利的找一份Java程序员的工作,吃透了这本《葵花宝典》,一般的笔试不在话下。
    • 乾颐堂泰克最新HCIE6.0 面试宝典 葵花宝典背过必过,花了很多钱整理的资料,分享给大家学习,很牛逼的,很不错
    • java面试葵花宝典

      2013-03-23 22:31:21
      最新版本!java面试葵花宝典的最新版本,不错的参考东西,想踏入程序猿的们尽情下载
    • 由于这套面试题涉及的范围很泛,很广,很杂,大家不可能一天两天就看完和学完这套面试宝典,即使你已经学过了有关的技术,那么至少也需要一个月的时间才能消化和掌握这套面试宝典,所以,大家应该早作准备,从拿到这...
    • JavaScript葵花宝典

      2016-11-17 15:56:52
      面向对象思想,新手看看
    • try-finally终于形成肌肉记忆了,不出牌了 Java SDK的版本不断升级,这门语言始终在飞速发展,我们玩技术的也应该多多与时俱进,无论是的语法糖还是内部实现(多表现为性能提升),都应多多关注,比如jdk7以后,...

      软件编程语言琳琅满目,Java、C/C++、.Net、Node.js、Python、JavaScript、PHP、Rust、Go,适用范围、哲学流派也是百花齐放,客户端、前端、后端、移动端,脚本式、面向过程/对象、函数式编程,这些词藻甩出来瞬间刷屏,就此打住。我们不妨来关注下这些语言背后的 "万变不离其宗"之术吧,无论什么语言,异常处理无疑都是重中之重,本篇我们就来聊聊Java中的异常处理。

      所谓优良程序,我认为其编程过程,少说,60%以上都是在和异常战斗,正所谓,“Bug千千万,测试第一条,异常不重视,岂止两行泪”。

      1. 异常处理,老夫就是一把梭

      在写Java代码时,有些代码是编译器要你强行捕获处理的,如下:

      正例:

      try {  String ip = "某ip";  int port = 8080;  // 通过socket,连接网络中的某个节点  new Socket().connect(new InetSocketAddress(ip, port));} catch (Exception e) {  // 一把梭,出错打印,爱咋咋滴  e.printStackTrace();}

      反例:

      String ip = "某ip";int port = 8080;try {  // 通过socket,连接网络中的某个节点  new Socket().connect(new InetSocketAddress(ip, port));} catch (SocketException e) {  //日志记录,同时输出异常堆栈  logger.log("网络连接异常 目标节点[ip={} port={}], 已连接或连接已关闭", ip, port, e);  /*陷入深沉的思考中...    *1.这个异常在当前语境下会造成什么影响    *2.抛不抛出,不抛出我要做什么处理,如果抛出,除了记录日志,我还应该做些什么   *3.虽然exception被我catch到了,但有没有可能遗漏其它异常   *4.等等...   */} catch (Exception e) {  logger.log("发生了不可预计的网络连接异常 目标节点[ip={} port={}]", ip, port, e);  /*陷入深沉的思考中 again...  *重复以上思考过程...  *在当前场景中,我认为网络连接异常本就是个checked exception,也就是说,  *我要让调用我的人必须知道这点,由他决定怎么处理,兄弟对不住,我这把锅甩出去了  *throw e;  *又或者,根据业内最新思潮,万错皆可视为RuntimeException,  * 不过事没完,接下来我得在当前方法的throws子句中显式声明这些异常,好让别人知道...  throw new RuntimeException(e);}//吾日三省吾身...//单元测试搞一搞?//覆盖度测试搞一搞?//代码有没有重复,是不是优雅,重构搞一搞?

      2. JDK基础运行时异常,轻松捕获

      Java开发的基本类库JDK定义了一些开箱即用的运行时异常(RuntimeException),比如NullPointerException、IndexOutOfBoundsException等,这些异常不应该通过try-catch捕获来处理,而应该通过主动预检查来处理,如下:

      正例:

      Biz biz = null;try {  biz.run();} catch (NullPointerException e) {  //轻松捕获臭名昭著的空指针异常,编程我最行!}int[] arrays = new int[]{1, 2, 3};try {int a = arrays[4];} catch (IndexOutOfBoundsException e) {  //轻松捕获臭名昭著的数组越界异常,编程我最行!}

      反例:

      Biz biz = null;if (biz == null) {  return;}biz.run();int[] array = new int[] {};if (array == null || array.length == 0) {  return;}array[0] = 1;

      3. 我也不知道哪会出错,try-catch罩起来,万无一失

      catch时要分清,哪些代码不可能出错,哪些代码可能出错,不可能出错的不用try-catch(对新手来说,这点其实比较难做到),对于可能出错的代码进行try-catch,并尽可能针对异常分类处理,示例代码参考上文第1.条 ,此外,举两个栗子,如下:

      • 包括且不限于 语言层面的赋值语句、简单的getter/setter调用,根本不可能报错,不用try-catch
      • 某些第三方api/类库文档有时候会写某某方法抛出啥异常,你难道相信它永远按文档那样工作? 所以,建议try-catch(除非你是大牛钻进去看透代码,版本变化了你还得跟着)

      最后记住,用try-catch包裹的代码是有性能开销的

      4. 编译器老是报错,烦的一批,try-catch罩起来,世界安静了

      在Java中,对于checked异常,编译器会提示你进行try-catch,编译器那么体贴,你一定要好好处理啊,如下:

      a0c3baa0a96e2beb16e100a30c8d0763.png

      编译器报错高清无码图

      发红了,赶紧try-catch起来,压压惊, 如下:

      正例:

      try {  Thread.sleep(休眠毫秒数);} catch (InterruptedException e) {  e.printStackTrace();}

      反例:

      try {  Thread.sleep(休眠毫秒数);} catch (InterruptedException e) {  logger.warn("线程{} 发生了中断", Thread.currentThread(), e);  //传递中断信号(什么鬼?)  Thread.currentThread().interrupt();}

      5. 用异常来控制程序流程,神乎其技

      异常就是异常,它代表程序的意外情况,不要仗着try-catch能捕获异常,用这个机制来处理正常的程序流程,如下:

      正例:

      public static void check(String param) {  if (param == null)    throw new ParamExcetpion("参数为空!");  if (param.indexOf("敏感词") != -1)    throw new SensitiveWordException("发现敏感词");}public static void handleParamError() {  System.out.println("执行参数为空后的业务逻辑");}public static void handleSensitiveWord() {  System.out.println("执行发现敏感词后的业务逻辑");}public static void main(String[] args) {  String param = null;  try {    check(param);  } catch (ParamExcetpion e) {    handleParamError();  } catch (SensitiveWordException e) {    handleSensitiveWord();  }}

      反例:

      String param = "未知值";if (param == null) {  handleNull();  return;}if (param.indexOf("敏感词") != -1) {  handleSensitiveWord();}

      6.finally中别忘记资源对象的关闭和释放,我知道啊

      finally块必须对资源型对象进行关闭,以防泄漏,在这个过程中,针对某个特定资源对象的关闭,有任何异常都要做try-catch,防止close意外被miss掉,如下:

      正例:

      FileInputStream in = null;FileOutputStream out = null;try {  in = new FileInputStream("in.txt");  out = new FileOutputStream("out.txt");} catch (Exception e) {  e.printStackTrace();} finally {  try {    //妥妥关闭in和out    in.close();    out.close();  } catch (IOException e) {    e.printStackTrace();  }}

      反例:

      FileInputStream in = null;FileOutputStream out = null;try {  in = new FileInputStream("in.txt");  out = new FileOutputStream("out.txt");} catch (Exception e) {  // log略  throw new RuntimeException("文件读写错误", e);} finally {  if (in != null) {    try {      in.close();    } catch (Exception e) {      // 主动吞咽异常 log略    }  }  if (out != null) {    try {      out.close();    } catch (Exception e) {      // 主动吞咽异常 log略    }  }}

      7. try-finally终于形成肌肉记忆了,不出牌了

      Java SDK的版本不断升级,这门语言始终在飞速发展,我们玩技术的也应该多多与时俱进,无论是新的语法糖还是内部实现(多表现为性能提升),都应多多关注,比如jdk7以后,支持try-with-resources语法糖,类只要实现了java.io.Closable接口,都可以受惠,这种语法糖直接在语言层面为你简化了 陈旧冗长的try-finally处理范式,来看:

      正例:

      FileInputStream in = null;try {  in = new FileInputStream("in.txt");} catch (Exception e) {  throw new RuntimeException("文件读写错误", e);} finally {  if (in != null) {    try {      in.close();    } catch (Exception e) {      // 主动吞咽异常 log略    }  }}

      反例:

      try (FileInputStream in = new FileInputStream("in.txt")) {} catch (Exception e) {  // log略  throw new RuntimeException("文件读写错误", e);}

      8. 任何异常,只要能捕获住Exception兜底处理下,满满健壮感

      在某些情况下,程序抛出的root异常并不一定都是Exception,要知道Java中还有一种异常的root叫做java.lang.Error,当潜在地,可能有Error抛出时,必须捕获Throwable。

      正例:

      static void weird1() throws NoSuchMethodError {  throw new NoSuchMethodError("weird1");}static void weird2() throws Exception {  weird2();}public static void main(String[] args) {  try {    weird1();  } catch (Exception e) {    System.out.println("妥妥抓住weird1异常,妥妥滴!");  }  try {    weird2();  } catch (Exception e) {    System.out.println("妥妥抓住weird2异常,奥利给!");  }}

      反例:

      try {  weird1();} catch (Throwable e) {  System.out.println("妥妥抓住weird1异常,妥妥滴!");}try {  weird2();} catch (Throwable e) {  System.out.println("妥妥抓住weird2异常,奥利给!");}

      9. 自定义异常,吃饱了撑的吧

      在适当的时候,或者说在业务变得越来越复杂的时候,自定义异常这件事就是顺理成章的了,来看:

      正例:

      static void bizA() throws RuntimeException {  throw new RuntimeException("sth error");}static void bizB() throws RuntimeException {  throw new RuntimeException("sth error");}static void call() {  bizA();  bizB();}public static void main(String[] args) {  try {    call();  } catch (Exception e) {    //现在就把这个异常show给你看,当看到sth error时,你一定不会关心是bizA还是bizB的错,easy life!    System.out.println(e);  }}

      反例:

      static class ExceptionOfA extends RuntimeException {  public ExceptionOfA(String message) {    super(message);  }}static class ExceptionOfB extends RuntimeException {  public ExceptionOfB(String message) {    super(message);  }}static void bizA() throws ExceptionOfA {  throw new ExceptionOfA("sth error");}static void bizB() throws ExceptionOfB {  throw new ExceptionOfB("sth error");}static void call() {  bizA();  bizB();}public static void main(String[] args) {  try {    call();  } catch (ExceptionOfA e) {    //针对bizA的异常,我们用方案xxx来应对  } catch (ExceptionOfB e) {    //针对bizB的异常,我们用方案yyy来应对  }}

      10. DRY原则,别整那洋玩意儿

      DRY原则,Don't Repeat Yourself,拒绝重复代码!

      正例:

      static class ExceptionOfA extends RuntimeException {}static class ExceptionOfB extends RuntimeException {}static void bizA() throws ExceptionOfA {}static void bizB() throws ExceptionOfB {}static void call() {  bizA();  bizB();}//我是异常处理方案xxxstatic void handleError(Exception e) {}public static void main(String[] args) {  try {    call();  } catch (ExceptionOfA e) {    //针对bizA的异常,我们用方案xxx来应对    handleError(e);  } catch (ExceptionOfB e) {    //针对bizB的异常,我们也用方案xxx来应对    handleError(e);  }}

      反例:

      public static void main(String[] args) {  try {    call();  } catch (ExceptionOfA | ExceptionOfB e) {    //针对bizA和bizB的异常,我们都用方案xxx来应对    handleError(e);  }}

      11. 异常没写文档,遗漏处理,怪我咯?

      异常文档化,这样让调用者或者维护者能够更清晰地知道你这个方法的约定、细节等等,这不仅仅体现在javadoc上,还体现在你的throws子句上(P.S. 这点不是强制的),现代的IDE还可以为有throws子句声明的异常自动生成try-catch处理的模版代码

      正例:

      static class AaException extends RuntimeException {}static class BbException extends RuntimeException {}static void biz(boolean a, boolean b) {  if (a) throw new AaException();  if (b) throw new BbException();}public static void main(String[] args) {  //程序员小明引入了某个jar包,biz方法是该jar包中某类的某方法  //小明扫了眼javadoc,没有任何关于参数和异常的描述,调用无忧!  biz(false, true);}

      反例:

      /** * @throws AaException 这是一个xxx异常,发生它时,通常意味着你应该... * @throws BbException 这是一个yyy异常,发生它时,通常意味着你应该... * */static void biz(boolean a, boolean b) throws AaException, BbException {  if (a)    throw new AaException();  if (b)    throw new BbException();}public static void main(String[] args) {  // 程序员小明引入了某个jar包,biz方法是该jar包中某类的某方法  // 小明扫了眼javadoc,发现有关于异常的详细描述,他赶紧使用IDE的自动生成try/catch处理块功能,编写更为健壮的程序  try {    biz(false, true);  } catch (AaException e) {    //处理略...  } catch (BbException e) {    //处理略...  }}

      12. 根因异常,这又是什么鬼

      抛出异常的同时,应带上底层的异常堆栈,不要埋没根因(root cause,即追本溯源,根本原因异常)

      正例

      static class ServiceException extends RuntimeException {  public ServiceException(String message) {    super(message);  }}static class DbException extends RuntimeException {  public DbException(String message) {    super(message);  }}static void service() throws ServiceException {  try {    dbOps();  } catch (Exception e) {    throw new ServiceException("业务异常");  }}static void dbOps() throws DbException {  throw new DbException("删库异常");}public static void main(String[] args) {  try {    service();  } catch (Exception e) {    //业务异常而已,小场面!    e.printStackTrace();  }}

      反例

      static class ServiceException extends RuntimeException {  public ServiceException(String message, Throwable cause) {    super(message, cause);  }}static class DbException extends RuntimeException {  public DbException(String message) {    super(message);  }  public DbException(String message, Throwable cause) {    super(message, cause);  }}static void service() throws ServiceException {  try {    dbOps();  } catch (Exception e) {    //抛出异常的同时,带上底层的异常堆栈,不要埋没根因(root cause,根本原因异常)    throw new ServiceException("业务异常", e);  }}static void dbOps() throws DbException {  throw new DbException("删库异常");}public static void main(String[] args) {  try {    service();  } catch (Exception e) {    //业务异常而已,小场面!等一等、删库了!!!    e.printStackTrace();  }}

      13. 喂,你这接口返回了个啥,你品你细品(TBD)

      14. 大俗大雅,说说null

      编程经验越来越丰富的同学们,开始喜欢在方法有返回值时,给个空的list、对象什么的了,而不是直接返回null,这样可以防止调用者调用你这个方法时,收到空指针异常,其实这倒不是强制的。本来调用者对null的处理就是他的责任所在,况且空对象、空list都是对象,有内存开销。还有就是,处理空list、空对象还有一些高级技巧,并不简单的。所以,脑细胞留给其它问题吧,骚年!

      15. 和NPE的世界大战(TBD)

      16. Spring事务,大佬罩着,异常无忧

      Spring的事务中,如果抛出了异常,那么事务是可以自动回滚的,但那有个前提,抛出的异常得是RuntimeException(或其子类)

      正例

      @Transactionalvoid service() {  //1.往db里insert了条记录  //2.往db里update了条记录  //3.模拟抛出异常,外面有Spring的@Transactional老大哥罩着,之前对db的操作定能回滚,easy life!  throw new Exception("调用失败");}

      反例

      //此处必须显式声明,对Exception也需要按需回滚//(老大哥:我只能自动识别到RuntimeException,而对于Exception,你不说我怎么知道你想要?)@Transactional(rollbackFor=Exception.class)void service() {  //1.往db里insert了条记录  //2.往db里update了条记录  //3.模拟抛出异常,外面有Spring的@Transactional老大哥罩着,之前对db的操作定能回滚,easy life!  throw new Exception("调用失败");}

      本文部分参考了阿里巴巴Java开发手册,融入了自己的一些解读和扩展,愿对你有所帮助

      ___________________________我是一条分割线之:第一重已成___________________________

      神功未成,继续修炼...


      历史文章:

      管理类

      软件行业从起步到转型,你所要了解的妙点

      项目经理的升迁之道

      技术类

      Java异常处理葵花宝典(第一重)

      展开全文
    • 改动比较大,重新作了整理,删去了习题部分,版面上力求简洁+美观。

    空空如也

    空空如也

    1 2 3 4 5 ... 20
    收藏数 5,530
    精华内容 2,212
    关键字:

    新葵花宝典