从高频笔/面试题思考Android学习/进阶路线(Java篇)
写在前面
标题谈进阶,属实有一些夸大。
我一直在思考什么样的文章才是一篇好文章,我的定义是首先要有人看,其次重要的是内部有价值。所以针对于这个出发点,我决定从大家比较关注的面试题入手,然后尝试从中分析对Android进阶路线的帮助。
虽然我只是一个应届生,但是我善于总结别人的经验,不要脸的去向别人请教。我实习的公司有蚂蚁金服技术专家,360浏览器技术负责人...在与他们的请教(后来他们见到我都躲着走,哈哈)中,我学到了很多东西。因此我会结合这一系列的内容,把这篇文章写出来。算是即使一种开源分析,也是一种供我个人复盘的场所。
所以我起了这么一个很飘的名字,当然我也把这个名字告诉了我的基友们,让他们提提意见:
我们看你是:飘了,拽了,感觉自己个头都不矮了;疯了,狂了,打算在宇宙之间称王了。
可能这是一个长久的任务,会时不时的更新,会不会开GitHub,或者其他还不好说。不过点个赞,整个关注,肯定不迷路。哈哈~
开始
Java篇
毫无疑问,我们大多数入坑都是因为这门综合性复合毒品:Java(当然可能还有像RN这种技术,不过因为我不了解所以这部分暂不涉及),因此开始部分将从Java基础入手。
当然也会涉及到最近风头正盛的Kotlin。关于Kotlin的部分我还在思考怎么把它写下来,因为只针对Kotlin的面试还真没有,所以通过面试点去总结Kotlin显然不现实。所以Kotlin相关的部分,我会暂时以笔记的形式接入。
知识点大杂烩
1、谈一谈多态?
这种问题相当的宽泛,而且随便百度就可以搜到一大堆的内容。但是我觉得仅仅是背诵概念真的没有意思。更多的应该从实战中去理解概念的含义。毕竟它们算是叩开Java大门的第一个概念,但又是贯穿我们整个开发生涯的概念。
由其当我们阅读优秀框架是,这种思想就会潜移默化的帮我们化解很多设计上的难题。
2、常见集合?
对于常用集合的源码分析是很高频的问题。而且也能被问得很细。
比如:
- 我在面试实习岗的时候,也就是被我之后的导师问过这方面的问题。当时从ArrayList聊到LinkedList再到HashMap,甚至问到了JDK1.8的改版,进而问到红黑树(虽然也没怎么答好)。
- 还有在面知乎的时候,被问到:HashMap,index重复后,新Node结点挂在这个链表的头还是尾....
- 再有的就是被问到,ConcurrentHashMap以及分段锁的...当时我被问到这个东西的时候是一脸懵逼?锁还能分段?优秀优秀,惹不起...
所以关于常见集合其实只能靠自己去看源码去总结。毕竟他们属于我们日常开发的熟客,还不深入的了解一番?
3、线程同步相关
同步相关的内容,问的比较多的是synchronized和Lock的异同点。关于区别还是很好回答的,不过一旦面试官追问,那考察的就是我们的积累问题了。
比如:
- synchronized是怎么实现的?
- 写一套单例,为什么要加锁?不加不行么?volatile关键字在这做什么用?其他方式不行么?只用static可不可以保证单例?了解过枚举写单例么?
- 自旋锁、悲观锁、乐观锁、分段锁了解么?CAS了解么?AtomicInteger相关的类为了解决什么问题?
必须要插嘴,这些问题我都被问过,我是一个2018年的应届生。不知道看官觉得难不难,反正我是很懵的...因为在我看来,Android开发好像很少用到同步。其实针对这个问题我有问过我的Leader。以下是我Leader的原话:
很少用到?你才开发了几天?做了几个项目?...等你做久了,你才真正的发现就是TM的很少用。但是我给你解释一下为什么。有些Android面试官是Java转过来的,问一些同步内容很正常;其实更多的是现在狼多肉少,面试官为了更好的筛选候选人。日常开发用的的确很少,就像咱们这种小项目框架都能做...不过你不学,总有人学,那你就被刷掉呗。其实当你去尝试编写涉及到网络的框架时,你会发现同步是一个比较重的环节,如果做UI或作是普通业务,同步的考虑并不多。
4、JVM相关
其实最开始我是一直不理解// 最初我一直不理解学习JVM对做Android有什么帮助,但是现在明白了,它本身就不是Android层面的内容,所以学习它的意义并不是在于直接的对Android能力进行提升,但是JVM可以帮助我们更好的理解Java运行机制,所以也就间接的帮助我们提升对开发Android的理解。
入坑写了第一行代码时,一直不明白这一行行代码是怎么运行起来的。当开始尝试学习和理解JVM后,这个疑问就烟消云散了因为之前是会写代码,而不懂原理,现在连代码也不会写了~
当然这只是开玩笑,接下来,我谈一谈我在学习JVM后,对Java的理解(如有不当之处,还望评论区指出,谢谢啦)。首先,我们的代码都是一个个.java文件,通过编译后变成.class文件,当我们需要这个类时,就会将这个包含二进制文件的class文件装载到内存中。将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。而我们的new就是通知JVM去给这个类,分配内存,构建内存地址,并赋值给引用。当我们执行对应的方法时,我们的方法便被封装成了JVM中栈帧的概念,而栈帧运行在栈中,随着方法的结束和开始,对应了栈帧的弹出和压入。
5、int和Integer的坑。
public class Main{ public static void main(String[] args) { //例子1 Integer i1 = 66, i2 = 66, i3 = 166, i4 = 166; System.out.println(i1 == i2);//true System.out.println(i3 == i4);//false } }
导致这个的原因是自动拆装箱机制。说白了就是JVM帮我们对int提升为Integer,或者把Integer拆为int。
因为==比较的是对象的地址是否相同,所以这个问题就转化为了f1和f2的内存地址是否相同。这里就引入了装箱机制。 因为是把100赋值给了一个Integer类型的引用,所以这里产生了一次装箱操作,而装箱的本质就是调用了Integer.valueOf(int i)。
//而这里的low和high,在IntegerCache被初始化的时候分别给赋值成了-128和127 public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
看了源码,这个问题很清晰,因为在装箱过程中使用了IntegerCache,而100正好是这个范围,所以不会去new对象,而166则相反。
那么再让我们看另一个例子:
//例子2 Integer a = new Integer(6); Integer b = 6; // 将6自动装箱成Integer类型 int c = 6; System.out.println(a == b); // false 两个引用没有引用同一对象 System.out.println(a == c); // true a自动拆箱成int类型再和c比较
而Double和Float则没有缓存:
public static Double valueOf(double d) { return new Double(d); } public static Float valueOf(String s) throws NumberFormatException { return new Float(FloatingDecimal.getThreadLocalInstance().readJavaFormatString(s).floatValue()); }
尾声
暂时想到了这么多,就先写这么多,如果以后找到其他更好的内容,再更新一个《补充篇》吧。
推荐一个立志减少IT面试踩坑的公众号
因为身边的同学从事互联网相关职业的比较多,并且大家闲时聊天时总会吐槽找工作有很多坑,所以打算把身边同学找工作的经验(包括Android/Java/Web),统统收集起来。提供给想从事这方面同学,希望圈内好友可以共同进步,共同少踩坑。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
为什么说Web开发和Vue.js是如此的有趣?
我想告诉你,我开始享受使用Vue.js和进行前端开发的故事。这不应该被理解为一篇关于为什么Vue.js可能比React,Angular或任何你正在考虑的其他Web框架更好的文章。Vuejs是令人惊叹的,但我们生活在一个作为前端开发人员同样令人惊叹的时代。 如果你几年前和我交谈过,我会把自己定位为一个后端开发人员,掌握服务器和数据库管理。面向对象的语言,java和c #,我想找到一种自己需要交付程序时使用的唯一的开发语言,我逐渐了解到更多关于.NET和SQL服务器的堆栈技术。当时我有这样一个概念,前端开发者只是使用右脑的附庸风雅的人,并不是“真正的”编程。 但是,在我最后一次求职,选择很少。特别是工作面试,我看到了自己是如何失败的。那次失败非常令人沮丧,但我从中吸取了不少教训。我获得了一个职位,利用了我在SharePoint的经验。我在SharePoint的经验并不特别:用GUI、工作流等设计页面这个不是我理想中的工作,而是为了生活不得不做的工作。 当我刚开始的时候,我接触过像我过去做过的任何类似的项目。我依靠GUI设计用户界面。幸运的是,使用数据库的经验使我能够以规范化的方式设计列表,...
- 下一篇
初学Python——Socket网络编程
认识socket socket本质上就是在2台网络互通的电脑之间,架设一个通道,两台电脑通过这个通道来实现数据的互相传递。我们知道网络 通信 都 是基于 ip+port(端口) 方能定位到目标的具体机器上的具体服务,操作系统有0-65535个端口,每个端口都可以独立对外提供服务,如果 把一个公司比做一台电脑 ,那公司的总机号码就相当于ip地址, 每个员工的分机号就相当于端口, 你想找公司某个人,必须 先打电话到总机,然后再转分机 。 建立一个socket必须至少有2端, 一个服务端,一个客户端, 服务端被动等待并接收请求,客户端主动发起请求, 连接建立之后,双方可以互发数据。 基本参数 Socket Families(地址簇) socket.AF_UNIX 本机进程间通信 socket.AF_INET IPV4(默认) socket.AF_INET6 IPV6 Socket Types(类型) socket.SOCK_STREAM 流式socket,代表TCP协议(默认) socket.SOCK_DGRAM 数据报式socket,代表UDP协议 socket方法 sk = sock...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS8编译安装MySQL8.0.19
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题