从高频笔/面试题思考Android学习/进阶路线(Java篇)

简介: 写在前面标题谈进阶,属实有一些夸大。我一直在思考什么样的文章才是一篇好文章,我的定义是首先要有人看,其次重要的是内部有价值。所以针对于这个出发点,我决定从大家比较关注的面试题入手,然后尝试从中分析对Android进阶路线的帮助。

写在前面

标题谈进阶,属实有一些夸大。
我一直在思考什么样的文章才是一篇好文章,我的定义是首先要有人看,其次重要的是内部有价值。所以针对于这个出发点,我决定从大家比较关注的面试题入手,然后尝试从中分析对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),统统收集起来。提供给想从事这方面同学,希望圈内好友可以共同进步,共同少踩坑。

img_89788b3a8f3f86257453cbc8264959f6.png
求关注,不迷路
目录
相关文章
|
9月前
|
IDE Java 编译器
java编程最基础学习
Java入门需掌握:环境搭建、基础语法、面向对象、数组集合与异常处理。通过实践编写简单程序,逐步深入学习,打牢编程基础。
446 1
|
10月前
|
Java API 容器
Java基础学习day08-2
本节讲解Java方法引用与常用API,包括静态、实例、特定类型方法及构造器引用的格式与使用场景,并结合代码示例深入解析。同时介绍String和ArrayList的核心方法及其实际应用。
255 1
|
9月前
|
存储 Oracle Java
java零基础学习者入门课程
本课程为Java零基础入门教程,涵盖环境搭建、变量、运算符、条件循环、数组及面向对象基础,每讲配示例代码与实践建议,助你循序渐进掌握核心知识,轻松迈入Java编程世界。
725 0
|
9月前
|
负载均衡 Java API
grpc-java 架构学习指南
本指南系统解析 grpc-java 架构,涵盖分层设计、核心流程与源码结构,结合实战路径与调试技巧,助你从入门到精通,掌握高性能 RPC 开发精髓。
873 8
|
10月前
|
Java
Java基础学习day08-作业
本作业涵盖Java中Lambda表达式的应用,包括Runnable与Comparator接口的简化实现、自定义函数式接口NumberProcessor进行加减乘及最大值操作,以及通过IntProcessor处理整数数组,实现遍历、平方和奇偶判断等功能,强化函数式编程实践。
151 5
|
10月前
|
Java 程序员
Java基础学习day08
本节讲解Java中的代码块(静态与实例)及其作用,深入介绍内部类(成员、静态、局部及匿名)的定义与使用,并引入函数式编程思想,重点阐述Lambda表达式及其在简化匿名内部类中的应用。
234 5
|
10月前
|
Java
Java基础学习day07-作业
本作业包含六个Java编程案例:1)动物类继承与多态;2)加油卡支付系统;3)员工管理类设计;4)学生信息统计接口;5)USB设备控制;6)家电智能控制。综合运用抽象类、接口、继承、多态等面向对象技术,强化Java基础编程能力。
319 3
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!