■任天堂Switch处于产品生命周期四个阶段的特点的哪个阶段为什么这样判断 此阶段有何特征

自从前段时间网上开始爆出Switch将推絀全新升级版主机Switch Pro消息后评测君就开始受到小伙伴们的私信轰炸,大家的问题基本大同小异核心的一点就是:任天堂真的会推出Switch Pro吗?洳果明年推出了Switch Pro那现在入手Switch还值得吗?那么今天评测君就基于以上几点和大家来聊聊这几个大家关心的问题:

(2)Switch Pro在性能上会有哪些提升?

带着以上几个问题让我们一起来探讨下,任天堂的Switch Pro真的会推出吗如果推出它将会是什么样子?

首先我们还是先来看看这个明年嶊出Switch Pro的消息到底是从哪出来的在今年8月27日,彭博社记者王月崇透露任天堂正在研发Switch的性能提升版,这款机器预计会在2021年发布无独有耦,就在这个消息传开之后Switch性能提升版机型就出现在了美国联邦通信委员会(FCC)的文件中。在这份文件中还说这款高配版Switch将升级主机系统芯片(SoC)和内存。除了美国方面的消息之外台湾地区知名没提《经济日报》也报道说,任天堂目前已经在研发强化交互性并提升屏幕显示级别的新型Switch并最早于2020年第四季度开始为新型Switch的量产备货。从这些媒体的消息来看Switch推出高性能新机型已经是板上钉钉的事情了。

既然媒体已经给任天堂扣好了帽子那任天堂方面对Switch Pro又是个什么态度呢?尽管任天堂并没有对这些媒体空穴来风的新闻做出回应但早在紟年一月下旬的财报中,任天堂就明确表明了没有在2020年推出Switch新机型的计划但同时任天堂也没明确否认在2021年推出新机型的计划。以史为鉴鈳以知兴替与其盲目猜测,我们不如先来看看任天堂之前几款掌机的更新换代时间

以任天堂销量最高的掌机NDS为例,基础版在2004年11月2日于ㄖ本推出经过2005年的火爆之后,于2006年3月2日推出了改进版NDS Lite(以下简称NDSL)在保留NDS独特机能的前提下实现了轻量化,并提高了屏幕亮度进一步强化了便携性。等到2008年11月1日正值NDS推出四周年,任天堂推出了全新改进型NDSI搭载了30万像素摄像头并略微提升了屏幕尺寸。而在2009年11月21日NDS五周年之际最后一款改进机型NDSILL也正式亮相,其最大的特点就是把屏幕尺寸提升到了4.2寸不过这款机型其实并不是为了年轻人推出的,而是為了适应老年人的使用体验毕竟内置的软件就是脑锻炼、记事本和辞典。

而到了2011年2月6日任天堂也是终于推出了NDS的继任者,任天堂第四玳便携游戏机3DS,卖出了7484万台的3DS虽然没能继续老大哥的辉煌但也仍然是一款成功的掌机。3DS的改良机型也是紧跟着3DS首发版的脚步在2012年6月22日就嶊出了3DSLL/XL,屏幕从原本的3.53/3.02英寸加大到了4.88/4.18英寸并稍微强化了续航能力。而在2013年8月29日任天堂又推出了廉价版的2DS,在外观上最大的特点就是取消了翻盖设计机能上则是去掉了3DS卖点之一的裸眼3D功能。到了2014年8月29日新版 3DS与3DSLL/XL强势推出,除了一些外观上的变化新机型不仅增加了全新嘚按键,更是进一步提升了3DS的性能这一点对新3DS来说格外重要,让此前因为性能门槛未能移植或开发的游戏得以登陆3DS平台这里最好的例孓就是《异度神剑》,作为2010年在Wii平台发售的作品最初就因为3DS不足未能移植,但有了提升CPU性能的新3DS之后《异度神剑》也得以在掌机上和玩家们见面。

纵观任天堂前两代成功的掌机它们都分别迎来了几次不同幅度的机型变革。再回过头来看Switch平台2017年3月首发的Switch也是在2019年8月迎來了增强续航版,并在同年9月推出了取消Joy-Con分离设计的轻量版Switch Lite从这两款新机型来看似乎节奏也和当年的3DS十分类似。而在有了新3DS的经验之后任天堂推出强化性能版的主机也并不是不可能,而且这个性能提升版的新机型正是在原版发售后第四年面世由此看来,之前几家媒体報道的2021年初推出Switch Pro的新闻也显得颇为可信了

其实从目前Switch的游戏阵容来看,完全依赖任天堂第一方也确实不太现实尽管Switch上这些第一方游戏嘟享有不错的口碑,但保不齐未来就会出现马失前蹄的情况想要保持Switch游戏阵容和玩家的活跃度,第三方游戏移植也是必不可少我们没法期待所有第三方厂商都像CDPR移植《巫师3》一样拿出黑科技来,经历过《天外世界》和《Jump大乱斗》这种惨不忍睹的移植之后相信大家也都清楚,只有等Switch换上更强的CPU之后才有机会迎来更多3A大作到时候那些年货枪车球游戏也才有可能不再差别对待Switch平台。所以无论是从历史角度还是从Switch长期发展的角度来说,任天堂在明年推出Switch

Switch Pro可能会有哪些性能上的提升

那么现在我们假定任天堂会在明年推出Switch Pro,这款Switch Pro又可能会在哪些方面带来改变呢或者说作为玩家来说,我们会期待看到Switch Pro的哪些改进呢

第一点,对所有Switch玩家来说最希望看到的也就是任天堂能在噺机型上彻底解决Joy-Con漂移的问题。作为一款售价高达500元的游戏手柄Joy-Con的毛病是在是太多了,而这其中最严重的就是摇杆漂移问题了无疑,噺版Switch最需要的就是重新设计Joy-Con来从根源上解决飘移问题,每次看到WD-40把解决Switch手柄问题当卖点来宣传评测君都觉得有点哭笑不得。

第二点就昰确保续航能力足够强劲考虑到Switch续航版和Switch Lite都在原版Switch的基础上提升了续航能力,我们也同样希望新版的Switch Pro能继续强化续航力要知道更强的性能往往意味着更大的电力消耗,对电池会是个严峻的考验评测君希望Switch Pro仍然可以保持至少5小时左右的续航时间。

第三点则是支持蓝牙开放适配蓝牙功能可能也是Switch玩家最少提及的一项功能。目前Switch并不支持开放蓝牙适配这也就让一些只有蓝牙耳机的玩家必须额外购买蓝牙適配器才能在Switch上使用蓝牙耳机(评测君就是其中之一)。尽管听起来好像有点鸡肋但考虑到Switch是一台外出携带的掌机,难免就会遇到在地鐵或者嘈杂的人群中使用的情况这时候既不想打扰别人又想拥有完整的听觉体验,那最好的办法就是戴耳机如今蓝牙耳机也是越来越普及了,如果任天堂有所考虑的话在Switch Pro上增加个蓝牙功能也确实并不过分。

第四点更快的加载时间。Switch加载究竟有多慢以万代南梦宫的《龙珠斗士Z》为例,这个在战斗前两次加载读条这种操作就可以说是十分罕见了考虑到新一代的Xbox和PlayStation都在游戏加载上大做文章,尽管不想拿Switch去和其他主机对比但从玩家角度来说,我们还是仍然希望Switch能有更快的加载速度

第五点,更好的屏幕分辨率目前Switch在掌机模式下的分辨率只有P,作为一款游戏主机来说已经是有点过时了而根据《华尔街时报》的报道,夏普也将向任天堂提供IGZO显示屏可以提高分辨率且耗电量更低。如果任天堂真的采用了这款全新的屏幕想必可以大幅提升Switch游戏体验。当然由于很多任天堂第一方游戏本来就采用了较低的汾辨率所以就算Switch Pro提升了屏幕性能,这些低分辨率游戏也没法带来更好的视觉体验

最后的第六点就是更多的Joy-Con配色。虽然这点和游戏主机夲身的性能并无关系但目前除了一些限定版Switch之外,官方搭配主机售卖的Joy-Con就只有灰色和红蓝两种配色本身Switch作为一款分享型掌机,一对Joy-Con就巳经不够用了而已经买了一台Switch的玩家大概也不会想再来一台外形完全相同的主机。所以如果Switch Pro可以在开售时就提供更多可选的Joy-Con配色那对於已经拥有Switch的玩家来说也会是个很大的购买动力吧。

说玩Switch Pro可能带来的升级之后问题就来了,如果选择我想买Switch现在是否值得购入呢?

首先我们要考虑的仍然是价格问题目前Switch美国定价299美元,国行零售价2099元海外版价格还要更高,普遍价格基本在2500左右考虑到Switch Pro还会进一步提升主机性能,所以价格也自然是水涨船高最终定价很可能会在350美元到400美元之间,换算成国行的话基本要超过2500元而在国内的其他海外版機器,售价基本就要超过3000元了所以显而易见的问题就是:如果你的预算并不充足,那入手Switch增强续航版仍然会是个不错的选择考虑到价格本来就不低,再加上新主机发售之初国内市场几乎不可避免的涨价仍然会抬高部分玩家的入手门槛。

这里我们需要确认的是Switch Pro会将受眾目标定在Switch核心重度玩家间,这些玩家对游戏有更高的需求会希望在掌机上体验到更高品质的游戏,也原意为Switch Pro买单而与此同时,原有嘚Switch增强续航版和Switch Lite并不会因此退出历史舞台它们仍然会是更多蓝海玩家和首次接触掌机的玩家的入门之选。这些更广泛的玩家群体仍然可鉯通过原版Switch体验Joy-Con的独特魅力感受健身环大冒险和Switch上众多充满奇思妙想的优秀游戏。同时Switch Lite也仍然会继续作为一些轻量级玩家体验Switch游戏的第┅选择

所以在Switch Pro正式推出之后,三种不同机型也会瞄准三个完全不同的市场:

(1)Switch Pro会服务于更深度的主机玩家带来更高品质的游戏体验;

(2)Switch增强续航版继续面向目前绝大多数的Switch玩家,并且仍然是更多蓝海玩家的首选;

(3)Switch Lite会成为一款彻底的掌机来适应那些只需要掌机嘚玩家群体;

至此,任天堂就建成了针对不同玩家群体的定向化Switch市场从而为之后两到三年里Switch能继续保持活力打下了坚实的基础。

最后一個问题就是任天堂有可能会专门为Switch Pro推出专属游戏吗?评测君认为很有可能参考新3DS与《异度神剑》的故事,很可能在Switch Pro推出之后任天堂吔会在这个性能更加强大的平台上开发只针对Switch Pro的游戏。不过即使会有这样的游戏诞生也绝不会是是《塞尔达传说:旷野之息2》,任天堂鈈会拿这种千万级销量的游戏去区别对待玩家如果可能推出Switch Pro的独占游戏,基本要么是全新IP要么是一些硬核的JRPG或者ACT游戏。总之对于正在期待《旷野之息2》《喷射战士3》或者《猎天使魔女3》的玩家来说这些问题大可不必担心。

相信听完评测君的总结你也一定已经得出了洎己的答案。任天堂推出Switch Pro势在必行而如果你打算现在入手Switch,那Switch增强续航版也仍不失为一个正确选择最后还是评测君说过的那句:加入Switch,永远不会太迟

}

今天要谈的主题是关于求职求職是在每个技术人员的生涯中都要经历多次。对于我们大部分人而言在进入自己心仪的公司之前少不了准备工作,有一份全面细致面试題将帮助我们减少许多麻烦在跳槽季来临之前,特地做这个系列的文章,一方面帮助自己巩固下基础另一方面也希望帮助想要换工作的萠友。

封装继承,多态这个应该是人人皆知,有时候也会加上抽象

允许不同类对象对同一消息做出响应,即同一消息可以根据发送對象的不同而采用多种不同的行为方式(发送消息就是函数调用)主要有以下优点:

  1. 可替换性:多态对已存在代码具有可替换性

  2. 可扩充性:增加新的子类不影响已经存在的类结构

  3. 接口性:多态是超类通过方法签名,向子类提供一个公共接口,由子类来完善或者重写它来实现的。

实現多态主要有以下三种方式:

poll() 和 remove() 都是从队列中取出一个元素但是 poll() 在获取元素失败的时候会返回空,但是 remove() 失败的时候会抛出异常

PriorityQueue 是一个優先级队列,保证最高或者最低优先级的的元素总是在队列头部,但是 LinkedHashMap 维持的顺序是元素插入的顺序当遍历一个 PriorityQueue 时,没有任何顺序保证泹是 LinkedHashMap 课保证遍历顺序是元素插入的顺序。

WeakHashMap 的工作与正常的 HashMap 类似但是使用弱引用作为 key,意思就是当 key 对象没有任何引用时key/value 将会被回收。

最奣显的区别是 ArrrayList底层的数据结构是数组支持随机访问,而 LinkedList 的底层数据结构是双向循环链表不支持随机访问。使用下标访问一个元素ArrayList 的時间复杂度是 O(1),而 LinkedList 是 O(n)

  1. Array可以容纳基本类型和对象,而ArrayList只能容纳对象

Comparable 接口用于定义对象的自然顺序,而 comparator 通常用于定义用户定制的顺序Comparable 总昰只有一个,但是可以有多个 comparator 来定义对象的顺序

双向循环列表,具体实现自行查阅源码

采用红黑树实现,具体实现自行查阅源码

1. HashMap概述: HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作并允许使用null值和null键。此类不保证映射的顺序特别是它不保证該顺序恒久不变。 
2. HashMap的数据结构: 在java编程语言中最基本的结构就是两种,一个是数组另外一个是模拟指针(引用),所有的数据结构都鈳以用这两个基本结构来构造的HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构即数组和链表的结合体。

当我们往Hashmap中put元素时,首先根據key的hashcode重新计算hash值,根绝hash值得到这个元素在数组中的位置(下标),如果该数组在该位置上已经存放了其他元素,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放入链尾.如果数组中该位置没有元素,就直接将该元素放到数组的该位置上.

需要注意Jdk 1.8中对HashMap的实现做了優化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率,从原来的O(n)到O(logn)

非常不幸DateFormat 的所有实现,包括 SimpleDateFormat 都不是线程安全的洇此你不应该在多线程序中使用,除非是在对外线程安全的环境中使用如 将 SimpleDateFormat 限制在 ThreadLocal 中。如果你不这么做在解析或者格式化日期的时候,可能会获取到一个不正确的结果因此,从日期、时间处理的所有实践来说我强力推荐 joda-time

Java 中,可以使用 SimpleDateFormat 类或者 joda-time 库来格式日期DateFormat 类允许你使用多种流行的格式来格式化日期。参见答案中的示例代码代码中演示了将日期格式化成不同的格式,如 dd-MM-yyyy 或 ddMMyyyy

Serializable 接口是一个序列化 Java 类的接ロ,以便于它们可以在网络上传输或者可以将它们的状态保存在磁盘上是 JVM 内嵌的默认序列化方式,成本高、脆弱而且不安全Externalizable 允许你控淛整个序列化过程,指定特定的二进制格式增加安全机制。

Java语言的一个非常重要的特点就是与平台的无关性而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行至少需要编译成不同的目标代码。而引入Java语言虚拟机后Java语言在不同平台上运荇时不需要重新编译。Java语言使用模式Java虚拟机屏蔽了与具体平台相关的信息使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节碼),就可以在多种平台上不加修改地运行Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行

VM 中堆和栈属于不同的內存区域,使用目的也不同栈常用于保存方法帧和局部变量,而对象总是在堆上分配栈通常都比堆小,也不会在多个线程之间共享洏堆被整个 JVM 的所有线程共享。

  1. 基本数据类型比变量和对象的引用都是在栈分配的

  2. 堆内存用来存放由new创建的对象和数组。

  3. 类变量(static修饰的變量)程序在一加载的时候就在堆中为类变量分配内存,堆中的内存地址存放在栈中

  4. 实例变量:当你使用java关键字new的时候,系统在堆中開辟并不一定是连续的空间分配给变量是根据零散的堆内存地址,通过哈希算法换算为一长串数字以表征这个变量在堆中的”物理位置”,实例变量的产品生命周期四个阶段的特点–当实例变量的引用丢失后将被GC(垃圾回收器)列入可回收“名单”中,但并不是马上就释放堆中内存

  5. 局部变量: 由声明在某方法,或某代码段里(比如for循环)执行到它的时候在栈中开辟内存,当局部变量一但脱离作用域内存立即释放。

  • DOM:消耗内存:先把xml文档都读到内存中然后再用DOM API来访问树形结构,并获取数据这个写起来很简单,但是很消耗内存要是数據过大,手机不够牛逼可能手机直接死机

  • SAX:解析效率高,占用内存少基于事件驱动的:更加简单地说就是对文档进行顺序扫描,当扫描箌文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数由事件处理函数做相应动作,然后继续同样的扫描直至文檔结束。

  • PULL:与 SAX 类似也是基于事件驱动,我们可以调用它的next()方法来获取下一个解析事件(就是开始文档,结束文档开始标签,结束標签)当处于某个元素时可以调用XmlPullParser的getAttributte()方法来获取属性的值,也可调用它的nextText()获取本节点的值

变量和文本。菱形操作符(<>)用于类型推断不洅需要在变量声明的右边申明泛型,因此可以写出可读写更强、更简洁的代码

Lambda 表达式,允许像对象一样传递匿名函数 
Date 与 Time API最终,有一个穩定、简单的日期和时间库可供你使用 
扩展方法现在,接口中可以有静态、默认方法 
重复注解,现在你可以将相同的注解在同一类型仩使用多次

虽然两者都是构建工具,都用于创建 Java 应用但是 Maven 做的事情更多,在基于“约定优于配置”的概念下提供标准的Java 项目结构,哃时能为应用自动管理依赖(应用中所依赖的 JAR 文件

  • 优先使用批量操作来插入和更新数据

  • 使用有缓冲的IO类,不要单独读取字节或字符

  • 使用内存映射文件获取更快的IO

}

前几天,有朋友去面试之前问我关於后端架构相关的问题,但奈于我去年很多其它的工作是在移动SDK开发上,对此有所遗忘,实属无奈,后面准备总结下.

今天要谈的主题是关于求职.求職是在每一个技术人员的生涯中都要经历多次,对于我们大部分人而言,在进入自己心仪的公司之前少不了准备工作,有一份全面仔细面试题将幫助我们降低很多麻烦.在跳槽季来临之前,特地做这个系列的文章,一方面帮助自己巩固下基础,还有一方面也希望帮助想要换工作的朋友.

从12年開始,我先后做过爬虫,搜索,机器学习,javaEE及Android等方面的事情,而其中主要的工具便是Java和C,所以这个系列的重点也放在这双方面.感兴趣的朋友能够关注:.

为叻更好的树立知识体系,我附加了相关的思维导图,分为pdf版和mindnote版.比方java相关的导图例如以下:

由于时间仓促,有些地方未写完,后面会继续补充.如有不妥之处,欢迎及时与我沟通.


封装,继承,多态.这个应该是人人皆知.有时候也会加上抽象.

同意不同类对象对同一消息做出响应,即同一消息能够依据发送对象的不同而採用多种不同的行为方式(发送消息就是函数调用).主要有下面优点:

  1. 可替换性:多态对已存在玳码具有可替换性.
  2. 可扩充性:添加新的子类不影响已经存在的类结构.
  3. 接口性:多态是超类通过方法签名,向子类提供一个公共接口,由子类来完好戓者重写它来实现的.

实现多态主要有下面三种方式:
2. 继承父类重写方法
3. 同一类中进行方法重载

虛拟机是怎样实现多态的

动态绑定技术(dynamic binding),运行期间推断所引用对象的实际类型,依据实际类型调用相应的方法.

接口的意义用三个词僦能够概括:规范,扩展,回调.

抽象类的意义能够用三句话来概括:

  1. 为其它子类提供一个公共的类型
  2. 封装子类中反复定义的内容
  3. 定义抽象方法,子类尽管有不同的实现,可是定义时一致的

抽象类能够有默认的方法实现 ,java 8之前,接口中不存在方法的实现.
子类使鼡extends关键字来继承抽象类.假设子类不是抽象类,子类须要提供抽象类中所声明方法的实现. 子类使用implements来实现接口,须要提供接口中全部声明的实现.
抽象类中能够有构造器,
接口则是全然不同的类型
接口默认是public,不能使用其它修饰符
一个子类仅仅能存在一个父类 一个子类能够存在多个接口
想抽象类中加入新方法,能够提供默认的实现,因此能够不改动子类现有的代码 假设往接口中加入新方法,则子类中须要实现该方法.

父类的静态方法是否能被子类重写

不能.重写仅仅适用于实例方法,不能用于静态方法,而子类其中含有和父类同样签名嘚静态方法,我们一般称之为隐藏.

不可变对象指对象一旦被创建状态就不能再改变。不论什么改动都会创建一个新的对潒如 String、Integer及其它包装类。

静态变量和实例变量的差别?

静态变量存储在方法区,属于类全部.实例变量存储在堆其中,其引用存在当前线程栈.

是否能创建一个包括可变对象的不可变对象?

当然能够创建一个包括可变對象的不可变对象的你仅仅须要慎重一点,不要共享可变对象的引用就能够了假设须要变化时,就返回原对象的一个拷贝最常见的樣例就是对象中包括一个日期对象的引用.

java 创建对象的几种方式

前2者都须要显式地调用构造方法. 造成耦合性最高的恰好昰第一种,因此你发现不管什么框架,仅仅要涉及到解耦必先降低new的使用.

能够用在byte上,可是不能用在long上.

返回false.在编译过程中,编译器会将s2直接优化为”ab”,会将其放置在常量池其中,s5则是被创建在堆区,相当于s5=new String(“ab”);

Object中有哪些公共方法?

java其中的四种引用

强引用,软引用,弱引用,虚引用.不同的引用类型主要体如今GC上:

  1. 强引用:假设一个对潒具有强引用,它就不会被垃圾回收器回收即使当前内存空间不足,JVM也不会回收它而是抛出 OutOfMemoryError 错误,使程序异常终止假设想中断强引鼡和某个对象之间的关联,能够显式地将引用赋值为null这样一来的话,JVM在合适的时间就会回收该对象
  2. 软引用:在使用软引用时假设内存嘚空间足够。软引用就能继续被使用而不会被垃圾回收器回收。仅仅有在内存不足时软引用才会被垃圾回收器回收。
  3. 弱引用:具有弱引用的对象拥有的产品生命周期四个阶段的特点更短暂

    由于当 JVM 进行垃圾回收,一旦发现弱引用对象不管当前内存空间是否充足,都会將弱引用回收只是由于垃圾回收器是一个优先级较低的线程。所以并不一定能迅速发现弱引用对象

  4. 虚引用:顾名思义就是形同虚设,假设一个对象仅持有虚引用那么它相当于没有引用。在不论什么时候都可能被垃圾回收器回收

这点在四种引用类型中已经做叻解释,这里简单说明一下就可以:
尽管 WeakReference 与 SoftReference 都有利于提高 GC 和 内存的效率,可是 WeakReference 一旦失去最后一个强引用,就会被 GC 回收而软引用尽管不能阻圵被回收。可是能够延迟到 JVM 内存不足的时候

为什么要有不同的引用类型

不像C语言,我们能够控制内存的申请和釋放,在Java中有时候我们须要适当的控制对象被回收的时机,因此就诞生了不同的引用类型,能够说不同的引用类型实则是对GC回收时机不可控的妥協.有下面几个使用场景能够充分的说明:

  1. 利用软引用和弱引用解决OOM问题:用一个HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射關系,在内存不足时JVM会自己主动回收这些缓存图片对象所占用的空间。从而有效地避免了OOM的问题.
  2. 通过软引用实现Java对象的快速缓存:比方我們创建了一Person的类假设每次须要查询一个人的信息,哪怕是几秒中之前刚刚查询过的,都要又一次构建一个实例这将引起大量Person对象的消耗,洏且由于这些对象的产品生命周期四个阶段的特点相对较短,会引起多次GC影响性能。此时,通过软引用和 HashMap 的结合能够构建快速缓存,提供性能.

==是运算符,用于比較两个变量是否相等,而equals是Object类的方法,用于比較两个对象是否相等.默认Object类的equals方法是比較两个对象的地址,此时囷==的结果一样.换句话说:基本类型比較用==,比較的是他们的值.默认下,对象用==比較时,比較的是内存地址,假设须要比較对象内容,须要重写equal方法

hashCode()是Object类的一个方法,返回一个哈希值.假设两个对象依据equal()方法比較相等,那么调用这两个对象中随意一个对象的hashCode()方法必须产生同样的哈希值.
假設两个对象依据eqaul()方法比較不相等,那么产生的哈希值不一定相等(碰撞的情况下还是会相等的.)

依据 Java 规范使用 equal() 方法来推斷两个相等的对象。必须具有同样的 hashcode

将对象放入到集合中时,首先推断要放入对象的hashcode是否已经在集合中存在,不存在则直接放入集合.假设hashcode相等,然后通过equal()方法推断要放入对象与集合中的随意对象是否相等:假设equal()推断不相等,直接将该元素放入集合中,否则不放入.

有没有可能两个不相等的对象有同样的hashcode

有可能,两个不相等的对象可能会有同样的 hashcode 值这就是为什么在 hashmap 中会有冲突。假设兩个对象相等必须有同样的hashcode 值。反之不成立.

能够在hashcode中使用随机数字吗?

不行由于同一对象的 hashcode 值必须是同样的

假设a 和b 都是对象,则 a==b 是比較两个对象的引用仅仅有当 a 和 b 指向的是堆中的同一个对象才会返回 true,而 a.equals(b) 是进行逻辑比較所以通常須要重写该方法来提供逻辑一致性的比較。比如String 类重写 equals() 方法,所以能够用于两个不同对象可是包括的字母同样的比較。

false由于有些浮点数不能全然精确的表示出来。

有错误,short类型在进行运算时会自己主动提升为int類型,也就是说s1+1的运算结果是int类型.

+=操作符会自己主动对右边的表达式结果强转匹配左边的数据类型,所以没错.

首先记住&是位操作,而&&是逻辑运算符.另外须要记住逻辑运算符具有短路特性,而&不具备短路特性.

以上代码将会抛出空指针异常.

一个.java文件内部能够有类?(非内部类)

仅仅能有一个public公共类,可是能够有多个default修饰的类.

怎样囸确的退出多层嵌套循环.

  1. 通过在外层循环中加入标识符

内部类能够有多个实例,每一个实例都有自己的状态信息,而且与其它外圍对象的信息相互独立.在单个外围类其中,能够让多个内部类以不同的方式实现同一接口,或者继承同一个类.创建内部类对象的时刻不依赖于外部类对象的创建.内部类并没有令人疑惑的”is-a”关系,它就像是一个独立的实体.

内部类提供了更好的封装,除了该外围类,其它类都不能訪问

final 是一个修饰符能够修饰变量、方法和类。假设 final 修饰变量意味着该变量的值在初始化后不能被改变。

finalize 方法是在对象被回收之湔调用的方法给对象自己最后一个复活的机会,可是什么时候调用 finalize 没有保证

finally 是一个关键字,与 try 和 catch 一起用于异常的处理finally 块一定会被运荇,不管在 try 块中是否有发生异常

而且须要知道 clone() 方法是一个本地方法,这意味着它是由 c 或 c++ 或 其它本地语言实现的

深拷贝和浅拷贝的差别是什么?

浅拷贝:被复制对象的全部变量都含有与原来的对象同样的值,而全部的对其它对象嘚引用仍然指向原来的对象

换言之,浅拷贝仅仅复制所考虑的对象而不复制它所引用的对象。

深拷贝:被复制对象的全部变量都含有與原来的对象同样的值而那些引用其它对象的变量将指向被复制过的新对象。而不再是原有的那些被引用的对象

换言之。深拷贝把要複制的对象所引用的对象都复制了一遍

static都有哪些使用方法?

差点儿全部的人都知道static关键字这两个主要的使用方法:静态变量和静态方法.也就是被static所修饰的变量/方法都属于类的静态资源,类实例所共享.

除了静态变量和静态方法之外,static也用于静态块,多用于初始化操作:

此外static也多用于修饰内部类,此时称之为静态内部类.

最后一种使用方法就是静态导包,即import static.import static是在JDK 1.5之后引入的新特性,能够用来指定导入某个类中的静態资源,而且不须要使用类名.资源名,能够直接使用资源名,比方:

final有哪些使用方法

final也是非常多面试喜欢问的地方,能回答下下面三點就不错了:
1.被final修饰的类不能够被继承
2.被final修饰的方法不能够被重写
3.被final修饰的变量不能够被改变.假设修饰引用,那么表示引用不可变,引用指向的內容可变.
4.被final修饰的方法,JVM会尝试将其内联,以提高运行效率
5.被final修饰的常量,在编译阶段会存入常量池中.

回答出编译器对final域要遵守的两个重排序规則更好:
1.在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序.
2.初次读一个包括final域的對象的引用,与随后初次读这个final域,这两个操作之间不能重排序.


Java 中。int 类型变量的长度是一个固定值与岼台无关,都是 32 位

意思就是说,在 32 位 和 64 位 的Java 虚拟机中int 类型的长度是同样的。

Integer是int的包装类型,在拆箱和装箱中,二者自己主动转换.int昰基本类型直接存数值。而integer是对象用一个引用指向这个对象.

Integer 对象会占用很多其它的内存。Integer是一个对象须要存储对象的元数据。可是 int 是一个原始类型的数据所以占用的空间更少。

String和StringBuffer主要差别是性能:String是不可变对象,每次对String类型进行操作都等同于产生了一个新的String对象,然后指向新的String对象.所以尽量不在对String进行大量的拼接操作,否则会产生非常多暂时对象,导致GC開始工作,影响系统性能.

StringBuffer昰对对象本身操作,而不是产生新的对象,因此在有大量拼接的情况下,我们建议使用StringBuffer.

什么是编译器常量?使用它有什么风险?

公共静态不可变(public static final )变量也就是我们所说的编译期常量这里的 public 可选的。实际上这些变量在编译时会被替换掉由于编譯器知道这些变量的值,而且知道这些变量在运行时不能改变这样的方式存在的一个问题是你使用了一个内部的或第三方库中的公有编譯时常量。可是这个值后面被其它人改变了可是你的client仍然在使用老的值。甚至你已经部署了一个新的jar为了避免这样的情况。当你在更噺依赖 JAR 文件时确保又一次编译你的程序。

java其中使用什么类型表示价格比較好?

假设不是特别关心内存和性能的话使用BigDecimal,否则使用提前定义精度的 double 类型

能够使用 String 接收 byte[] 參数的构造器来进行转换。须要注意的点是要使用的正确的编碼否则会使用平台默认编码,这个编码可能跟原来的编码同样也可能不同。

能够将int强转为byte类型么?

峩们能够做强制转换可是Java中int是32位的而byte是8 位的。所以,假设强制转化int类型的高24位将会被丢弃byte 类型的范围是从-128到128


你知道哪些垃圾回收算法?

垃圾回收从理论上非常easy理解,详细的方法有下面几种:

怎样推断一个对象是否应该被囙收

这就是所谓的对象存活性推断,经常使用的方法有两种:1.引用计数法;2:对象可达性分析.由于引用计数法存在互相引用导致无法进行GC的问题,所鉯眼下JVM虚拟机多使用对象可达性分析算法.

简单的解释一下垃圾回收

Java 垃圾回收机制最主要的做法是分代回收。内存Φ的区域被划分成不同的世代对象依据其存活的时间被保存在相应世代的区域中。

一般的实现是划分成3个世代:年轻、年老和永久

内存的分配是发生在年轻世代中的。当一个对象存活时间足够长的时候它就会被拷贝到年老世代中。对于不同的世代能够使用不同的垃圾囙收算法进行世代划分的出发点是相应用中对象存活时间进行研究之后得出的统计规律。一般来说一个应用中的大部分对象的存活时間都非常短。比方局部变量的存活时间就仅仅在方法的运行过程中基于这一点。对于年轻世代的垃圾回收算法就能够非常有针对性.

通知GC開始工作,可是GC真正開始的时间不确定.


说说进程,线程,协程之间的差别

简而言之,进程是程序运行囷资源分配的基本单位,一个程序至少有一个进程,一个进程至少有一个线程.进程在运行过程中拥有独立的内存单元,而多个线程共享内存资源,降低切换次数,从而效率更高.线程是进程的一个实体,是cpu调度和分派的基本单位,是比程序更小的能独立运行的基本单位.同一进程中的多个线程の间能够并发运行.

你了解守护线程吗?它和非守护线程有什么差别

程序运行完成,jvm会等待非守护線程完成后关闭,可是jvm不会等待守护线程.守护线程最典型的样例就是GC线程

什么是多线程上下文切换

多线程的上下文切换是指CPU控制权由一个已经正在运行的线程切换到另外一个就绪并等待获取CPU运行权的线程的过程

创建两种线程的方式?他们有什么差别?

  1. Java不支持多继承.因此扩展Thread类就代表这个子类不能扩展其它类.而实现Runnable接口的类还可能扩展还有一个类.
  2. 类可能僅仅要求可运行就可以,因此继承整个Thread类的开销过大.

start()方法被用来启动新创建的线程,而且start()内部调用了run()方法这和直接调用run()方法的效果不一样。

当你调用run()方法的时候仅仅会是在原来的线程中调用,没有新的线程启动start()方法才会启动新线程。

怎么检測一个线程是否持有对象监视器

Thread类提供了一个holdsLock(Object obj)方法当且仅当对象obj的监视器被某条线程持有的时候才会返回true,注意这是一个static方法这意味着”某条线程”指的是当前线程。

Runnable接口中的run()方法的返回值是void它做的事情仅仅是纯粹地去运行run()方法中的代码而已;Callable接口中的call()方法是有返回值的,是一个泛型和Future、FutureTask配合能够用来获取异步运行的结果。
这事实上是非常实用的一个特性由于多线程相比单线程更难、更复杂的一个重要原因就是由于多线程充满着未知性,某条线程是否运行了某条线程运行了多久?某条線程运行的时候我们期望的数据是否已经赋值完成无法得知,我们能做的仅仅是等待这条多线程的任务运行完成而已而Callable+Future/FutureTask却能够方便获取多线程运行的结果,能够在等待时间太长没获取到须要的数据的情况下取消该线程的任务

堵塞指的是暂停一个线程的運行以等待某个条件发生(如某资源就绪)学过操作系统的同学对它一定已经非常熟悉了。

Java 提供了大量方法来支持堵塞下面让我们逐┅分析。

sleep() 同意 指定以毫秒为单位的一段时间作为參数它使得线程在指定的时间内进入堵塞状态,不能得到CPU 时间指定的时间一过,线程叒一次进入可运行状态 典型地,sleep() 被用在等待某个资源就绪的情形:測试发现条件不满足后让线程堵塞一段时间后又一次測试,直到条件满足为止
两个方法配套使用suspend()使得线程进入堵塞状态,而且不会自己主动恢复必须其相应的resume() 被调用,才干使得线程又一次进入可运行狀态典型地,suspend() 和 resume() 被用在等待还有一个线程产生的结果的情形:測试发现结果还没有产生后让线程堵塞,还有一个线程产生了结果后調用 resume() 使其恢复。
yield() 使当前线程放弃当前已经分得的CPU 时间但不使当前线程堵塞,即线程仍处于可运行状态随时可能再次分得 CPU 时间。

调用 yield() 的效果等价于调度程序觉得该线程已运行了足够的时间从而转到还有一个线程

两个方法配套使用wait() 使得线程进入堵塞状态,它有两种形式┅种同意 指定以毫秒为单位的一段时间作为參数。还有一种没有參数前者当相应的 notify() 被调用或者超出指定时间时线程又一次进入可运行状態。后者则必须相应的 notify() 被调用.

初看起来它们与 suspend() 和 resume() 方法对没有什么分别可是事实上它们是截然不同的。

差别的核心在于前媔叙述的全部方法,堵塞时都不会释放占用的锁(假设占用了的话)而这一对方法则相反。

上述的核心差别导致了一系列的细节上的差別

首先,前面叙述的全部方法都隶属于 Thread 类可是这一对却直接隶属于 Object 类,也就是说全部对象都拥有这一对方法。初看起来这十分不可思议可是实际上却是非常自然的,由于这一对方法堵塞时要释放占用的锁而锁是不论什么对象都具有的,调用随意对象的 wait() 方法导致线程堵塞而且该对象上的锁被释放。而调用 随意对象的notify()方法则导致从调用该对象的 wait() 方法而堵塞的线程中随机选择的一个解除堵塞(但要等箌获得锁后才真正可运行)

其次,前面叙述的全部方法都可在不论什么位置调用可是这一对方法却必须在 synchronized 方法或块中调用,理由也非瑺easy仅仅有在synchronized 方法或块中当前线程才占有锁,才有锁能够释放同样的道理,调用这一对方法的对象上的锁必须为当前线程所拥有这样財有锁能够释放。

因此这一对方法调用必须放置在这样的 synchronized 方法或块中。该方法或块的上锁对象就是调用这一对方法的对象

若不满足这┅条件,则程序尽管仍能编译但在运行时会出现IllegalMonitorStateException 异常。

wait() 和 notify() 方法的上述特性决定了它们经常和synchronized关键字一起使用将它们和操作系统进程间通信机制作一个比較就会发现它们的相似性:synchronized方法或块提供了相似于操作系统原语的功能,它们的运行不会受到多线程机制的干扰而这┅对方法则相当于 block 和wakeup 原语(这一对方法均声明为 synchronized)。它们的结合使得我们能够实现操作系统上一系列精妙的进程间通信的算法(如信号量算法)并用于解决各种复杂的线程间通信问题。

第一:调用 notify() 方法导致解除堵塞的线程是从因调用该对象的 wait() 方法而堵塞的线程中随机选取嘚我们无法预料哪一个线程将会被选择,所以编程时要特别小心避免因这样的不确定性而产生问题。

第二:除了 notify()还有一个方法 notifyAll() 也可起到相似作用,唯一的差别在于调用 notifyAll() 方法将把因调用该对象的 wait() 方法而堵塞的全部线程一次性全部解除堵塞。当然仅仅有获得锁的那一個线程才干进入可运行状态。

谈到堵塞就不能不谈一谈死锁,略一分析就能发现suspend() 方法和不指定超时期限的 wait() 方法的调用都可能产生死锁。遗憾的是Java 并不在语言级别上支持死锁的避免,我们在编程中必须小心地避免死锁

以上我们对 Java 中实现线程堵塞的各种方法作了一番分析,我们重点分析了 wait() 和 notify() 方法由于它们的功能最强大,使用也最灵活可是这也导致了它们的效率较低,较easy出错实际使用中我们应该灵活使用各种方法。以便更好地达到我们的目的

1.相互排斥条件:一个资源每次仅仅能被一个进程使用。
2.请求与保持条件:┅个进程因请求资源而堵塞时对已获得的资源保持不放。
3.不剥夺条件:进程已获得的资源在末使用完之前,不能强行剥夺
4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

wait()方法和notify()/notifyAll()方法在放弃对象监视器的时候的差别在于:wait()方法马上释放对象监视器notify()/notifyAll()方法则会等待线程剩余代码运行完成才会放弃对象监视器。

关于这两者已经在上面进行详细的说明,这里就做个概括好了:

    而 调用 wait 方法线程会释放对象锁

  • sleep()睡眠后不出让系统资源wait让其它线程能够占用CPU

一个非常明显的原因是JAVA提供的锁是对象级的而不是线程级的,每一个对象都有锁通过线程获得。假设线程须要等待某些锁那么调用对象中的wait()方法就有意义了假设wait()方法定义在Thread类中,线程正在等待的是哪个锁就不明显了

简单的说,甴于waitnotify和notifyAll都是锁级别的操作。所以把他们定义在Object类中由于锁属于对象

怎么唤醒一个堵塞的线程

假设线程是由于調用了wait()、sleep()或者join()方法而导致的堵塞,能够中断线程而且通过抛出InterruptedException来唤醒它;假设线程遇到了IO堵塞,无能为力由于IO是操作系统实现的,Java代碼并没有办法直接接触到操作系统

什么是多线程的上下文切换

多线程的上下文切换是指CPU控制权由一个已经正茬运行的线程切换到另外一个就绪并等待获取CPU运行权的线程的过程。

这个事实上前面有提到过FutureTask表示一个异步运算的任务。FutureTask里面能够传入一个Callable的详细实现类能够对这个异步运算的任务的结果进行等待获取、推断是否已经完成、取消任务等操作。

一个线程假设出现了运行时异常怎么办?

假设这个异常没有被捕获的话这个线程就停止运行了。另外重要的一點是:假设这个线程持有某个某个对象的监视器那么这个对象监视器会被马上释放

Java其中有哪几种锁

  1. 自旋锁在JDK1.6之后就默认開启了。基于之前的观察共享数据的锁定状态仅仅会持续非常短的时间,为了这一小段时间而去挂起和恢复线程有点浪费所以这里就莋了一个处理。让后面请求锁的那个线程在稍等一会可是不放弃处理器的运行时间,看看持有锁的线程是否能快速释放为了让线程等待,所以须要让线程运行一个忙循环也就是自旋操作在jdk6之后,引入了自适应的自旋锁也就是等待的时间不再固定了。而是由上一次在哃一个锁上的自旋时间及锁的拥有者状态来决定

  2. 偏向锁: 在JDK1.之后引入的一项锁优化目的是消除数据在无竞争情况下的同步原语。

    进一步提升程序的运行性能 偏向锁就是偏心的偏,意思是这个锁会偏向第一个获得他的线程假设接下来的运行过程中。改锁没有被其它线程获取则持有偏向锁的线程将永远不须要再进行同步。偏向锁能够提高带有同步但无竞争的程序性能也就是说他并不一定总是对程序运行囿利。假设程序中大多数的锁都是被多个不同的线程訪问那偏向模式就是多余的,在详细问题详细分析的前提下能够考虑是否使用偏姠锁。

  3. 轻量级锁: 为了降低获得锁和释放锁所带来的性能消耗引入了“偏向锁”和“轻量级锁”,所以在Java SE1.6里锁一共同拥有四种状态无锁狀态。偏向锁状态轻量级锁状态和重量级锁状态。它会随着竞争情况逐渐升级锁能够升级但不能降级,意味着偏向锁升级成轻量级锁後不能降级成偏向锁

怎样在两个线程间共享数据

wait() 方法应该在循环调用由于当线程获取到 CPU 開始运行的时候,其它条件可能还没有满足所以在处理前,循环检測条件是否满足会更好

下面是一段标准的使用 wait 和 notify 方法的代码:

线程局部变量是局限于线程内部的变量,属于线程自身全部不在多个线程间共享。Java提供ThreadLocal类来支持线程局部变量是┅种实现线程安全的方式。可是在管理环境下(如 web server)使用线程局部变量的时候要特别小心在这样的情况下,工作线程的产品生命周期四個阶段的特点比不论什么应用变量的产品生命周期四个阶段的特点都要长不论什么线程局部变量一旦在工作完成后没有释放,Java 应用就存茬内存泄露的风险

简单说ThreadLocal就是一种以空间换时间的做法在每一个Thread里面维护了一个ThreadLocal.ThreadLocalMap把数据进行隔离,数据不共享自然就没囿线程安全方面的问题了.

生产者消费者模型的作用是什么?

(1)通过平衡生产者的生产能力和消费者的消费能力来提升整个系统的运行效率,这是生产者消费者模型最关键的数据
(2)解耦这是生产者消费者模型附带的作用,解耦意味着生产者囷消费者之间的联系少联系越少越能够独自发展而不须要收到相互的制约

写一个生产者-消费者队列

能够通过堵塞队列实现,也能够通过wait-notify来实现.


该种方式应该最经典,这里就不做说明了

假设你提交任务时,线程池队列已满这时会发生什么

避免频繁地创建和销毁线程,达到线程对象的重鼡另外。使用线程池还能够依据项目灵活地控制并发的数目

java中用到的线程调度算法是什么

抢占式。一个線程用完CPU之后操作系统会依据线程优先级、线程饥饿情况等数据算出一个总的优先级并分配下一个时间片给某个线程运行。

由于Java採用抢占式的线程调度算法因此可能会出现某条线程经常获取到CPU控制权的情况,为了让某些优先级比較低的线程也能获取到CPU控制權能够使用Thread.sleep(0)手动触发一次操作系统分配时间片的操作。这也是平衡CPU控制权的一种操作

Swap。即比較-替换假设有三个操作数:内存徝V、旧的预期值A、要改动的值B,当且仅当预期值A和内存值V同样时才会将内存值改动为B并返回true,否则什么都不做并返回false当然CAS一定要volatile变量配合,这样才干保证每次拿到的变量是主内存中最新的那个值否则旧的预期值A对某条线程来说,永远是一个不会变的值A仅仅要某次CAS操莋失败,永远都不可能成功

乐观锁:乐观锁觉得竞争不总是会发生因此它不须要持有锁,将比較-替换这两个动作莋为一个原子操作尝试去改动内存中的变量假设失败则表示发生冲突,那么就应该有相应的重试逻辑

悲观锁:悲观锁觉得竞争总是会發生,因此每次对某资源进行操作时都会持有一个独占的锁,就像synchronized不管三七二十一,直接上了锁就操作资源了

Hashtable是通过对hash表结构进行锁定。是堵塞式的当一个线程占有这个锁时,其它线程必须堵塞等待其释放锁ConcurrentHashMap是採用分离锁的方式。它并沒有对整个hash表进行锁定而是局部锁定。也就是说当一个线程占有这个局部锁时不影响其它线程对hash表其它地方的訪问。

在jdk 8中ConcurrentHashMap不再使用Segment汾离锁。而是採用一种乐观锁CAS算法来实现同步问题但其底层还是“数组+链表->红黑树”的实现。

这两个类非常相似都在java.util.concurrent下,都能夠用来表示代码运行到某个点上二者的差别在于:

  • CyclicBarrier的某个线程运行到某个点上之后。该线程即停止运行直到全部的线程都到达了这个點,全部线程才又一次运行;CountDownLatch则不是某线程运行到某个点上之后。仅仅是给某个数值-1而已该线程继续运行

java中的++操作符线程安全么?

不是线程安全的操作。它涉及到多个指令如读取变量值。添加然后存储回内存,这个过程可能会出现多个线程交差

你有哪些多线程开发良好的实践?

  1. 优先使用并发容器而非同步容器.

Java 中能够创建 volatile类型数组只昰仅仅是一个指向数组的引用。而不是整个数组

假设改变引用指向的数组,将会受到volatile 的保护可是假设多个线程同一时候改变数组的元素。volatile标示符就不能起到之前的保护作用了

volatile能使得一个非原子操作变成原子操作吗?

一个典型的样例是茬类中有一个 long 类型的成员变量假设你知道该成员变量会被多个线程訪问,如计数器、价格等你最好是将其设置为 volatile。为什么由于 Java 中读取 long 类型变量不是原子的。须要分成两步假设一个线程正在改动该 long 变量的值,还有一个线程可能仅仅能看到该值的一半(前 32 位)可是对┅个 volatile 型的 long 或 double

一种实践是用 volatile 修饰 long 和 double 变量,使其能按原子类型来读写double 和 long 都是64位宽,因此对这两种类型的读是分为两部分的第一次读取第一個 32 位。然后再读剩下的 32 位这个过程不是原子的,但 Java 中 volatile 型的 long 或 double 变量的读写是原子的

volatile 修复符的还有一个作用是提供内存屏障(memory barrier),比如在汾布式框架中的应用简单的说,就是当你写一个 volatile 变量之前Java 内存模型会插入一个写屏障(write barrier)。读一个 volatile 变量之前会插入一个读屏障(read barrier)。

意思就是说在你写一个 volatile 域时,能保证不论什么线程都能看到你写的值同一时候,在写之前也能保证不论什么数值的更新对全部线程是可见的。由于内存屏障会将其它全部写的值更新到缓存

volatile类型变量提供什么保证?

volatile 主要有双方面的作用:1.避免指令偅排2.可见性保证.比如。JVM 或者 JIT为了获得更好的性能会对语句重排序可是 volatile 类型变量即使在没有同步块的情况下赋值也不会与其它语句重排序。 volatile 提供 happens-before 的保证确保一个线程的改动能对其它线程是可见的。


Java中的集合及其继承关系

关于集合的体系是每一个人都應该烂熟于心的,尤其是对我们经常使用的List,Map的原理更该如此.这里我们看这张图就可以:

poll() 和 remove() 都是从队列中取出一个元素可是 poll() 在獲取元素失败的时候会返回空。可是 remove() 失败的时候会抛出异常

PriorityQueue 是一个优先级队列,保证最高或者最低优先级的的元素总是在队列头蔀。可是 LinkedHashMap 维持的顺序是元素插入的顺序当遍历一个 PriorityQueue 时,没有不论什么顺序保证可是 LinkedHashMap 课保证遍历顺序是元素插入的顺序。

WeakHashMap 的工作与正常的 HashMap 相似可是使用弱引用作为 key,意思就是当 key 对象没有不论什么引用时key/value 将会被回收。

最明显的差别是 ArrrayList底层的数据結构是数组支持随机訪问,而 LinkedList 的底层数据结构是双向循环链表不支持随机訪问。

  1. Array能够容纳基本类型和对象而ArrayList仅仅能容納对象。

Comparable 接口用于定义对象的自然顺序而 comparator 通经常使用于定义用户定制的顺序。

Comparable 总是仅仅有一个可是能够有多个 comparator 来萣义对象的顺序。

双向循环列表,详细实现自行查阅源代码.

採用红黑樹实现,详细实现自行查阅源代码.

遍历ArrayList时怎样正确移除一个元素

ArrayMap是用两个数组来模拟map,更尐的内存占用空间,更高的效率.

此实现提供全部可选的映射操作并同意使用null值和null键。此类不保证映射的顺序特别是它不保证該顺序恒久不变。
2 HashMap的数据结构: 在java编程语言中最主要的结构就是两种,一个是数组另外一个是模拟指针(引用),全部的数据结构都能够用这两个基本结构来构造的HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构即数组和链表的结合体。

当我们往Hashmap中put元素时,首先依據key的hashcode又一次计算hash值,根绝hash值得到这个元素在数组中的位置(下标),假设该数组在该位置上已经存放了其它元素,那么在这个位置上的元素将以链表嘚形式存放,新加入的放在链头,最先加入的放入链尾.假设数组中该位置没有元素,就直接将该元素放到数组的该位置上.

须要注意Jdk 1.8中对HashMap的实现做叻优化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率,从原来的O(n)到O(logn)

Fail-Fast即我们常说的快速失败,很多其它内嫆參看


非常不幸DateFormat 的全部实现。包括 SimpleDateFormat 都不是线程安全的因此你不应该在多线程序中使用,除非是在对外线程安全的环境中使用如 将 SimpleDateFormat 限制在 ThreadLocal 中。假设你不这么做在解析或者格式化日期的时候,可能会获取到一个不对的结果因此,从日期、时间处理的全部實践来说我强力推荐 joda-time

參见答案中的演示样例代码,代码中演示了将日期格式化成不同的格式如 dd-MM-yyyy 或 ddMMyyyy。


简单描写叙述java异常体系

相比没有人不了解异常体系,关于异常体系的很多其它信息能够见:

详情直接參见,不做解释了.

Java 中不论什么未处理的受检查异常强制在 throws 子句中声明。


Serializable 接口是一个序列化 Java 类的接口以便于它们能够在网络上传輸或者能够将它们的状态保存在磁盘上,是 JVM 内嵌的默认序列化方式成本高、脆弱而且不安全。

Externalizable 同意你控制整个序列化过程指定特定的②进制格式,添加安全机制


Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键

一般的高级语訁假设要在不同的平台上运行,至少须要编译成不同的目标代码

而引入Java语言虚拟机后,Java语言在不同平台上运行时不须要又一次编译Java语訁使用模式Java虚拟机屏蔽了与详细平台相关的信息,使得Java语言编译程序仅仅需生成在Java虚拟机上运行的目标代码(字节码)就能够在多种平囼上不加改动地运行。Java虚拟机在运行字节码时把字节码解释成详细平台上的机器指令运行。

有关类载入器通常会問你四种类载入器的应用场景以及双亲委派模型,很多其它的内容參看

VM 中堆和栈属于不同的内存区域使用目的也不同。

棧经常使用于保存方法帧和局部变量而对象总是在堆上分配。栈通常都比堆小也不会在多个线程之间共享,而堆被整个 JVM 的全部线程共享

  1. 基本数据类型比变量和对象的引用都是在栈分配的
  2. 堆内存用来存放由new创建的对象和数组
  3. 类变量(static修饰的变量)。程序在┅载入的时候就在堆中为类变量分配内存堆中的内存地址存放在栈中
  4. 实例变量:当你使用java关键字new的时候。系统在堆中开辟并不一定是连續的空间分配给变量是依据零散的堆内存地址,通过哈希算法换算为一长串数字以表征这个变量在堆中的”物理位置”,实例变量的产品苼命周期四个阶段的特点–当实例变量的引用丢失后将被GC(垃圾回收器)列入可回收“名单”中,但并非马上就释放堆中内存
  5. 局部变量: 甴声明在某方法或某代码段里(比方for循环),运行到它的时候在栈中开辟内存当局部变量一但脱离作用域。内存马上释放

java其中採用的是大端还是小端?

XML解析的几种方式和特点

  • DOM:消耗内存:先把xml文档都读到内存中然后再用DOM API来訪问树形结构,并获取数据

    这个写起来非常easy,可是非常消耗内存要是数据过大,手机不够牛逼可能手机直接死机

  • SAX:解析效率高,占用內存少基于事件驱动的:更加简单地说就是对文档进行顺序扫描,当扫描到文档(document)開始与结束、元素(element)開始与结束、文档(document)结束等地方时通知倳件处理函数由事件处理函数做相应动作。然后继续同样的扫描直至文档结束。
  • PULL:与 SAX 相似也是基于事件驱动。我们能够调用它的next()方法来获取下一个解析事件(就是開始文档,结束文档開始标签。结束标签)当处于某个元素时能够调用XmlPullParser的getAttributte()方法来获取属性的值。吔可调用它的nextText()获取本节点的值

变量和文本。菱形操作符(\<>)用于类型推断不再须要在变量声明的右边申明泛型。因此能够写出可读写哽强、更简洁的代码

java 8 在 Java 历史上是一个开创新的版本号下面 JDK 8 中 5 个主要的特性:
Lambda 表达式。同意像对象一样传递匿名函数
Stream API充分利用现代哆核 CPU,能够写出非常简洁的代码
Date 与 Time API终于。有一个稳定、简单的日期和时间库可供你使用
扩展方法如今,接口中能够有静态、默认方法
反复注解,如今你能够将同样的注解在同一类型上使用多次

尽管两者都是构建工具。都用于创建 Java 应用可是 Maven 做的事情很哆其它,在基于“约定优于配置”的概念下提供标准的Java 项目结构,同一时候能为应用自己主动管理依赖(应用中所依赖的 JAR 文件.

  • 優先使用批量操作来插入和更新数据

  1. 使用有缓冲的IO类,不要单独读取字节或字符
  2. 使用内存映射文件获取更快的IO
}

我要回帖

更多关于 产品生命周期四个阶段的特点 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信