转载请注明链接:https://blog.csdn.net/feather_wch/article/details/82909176
极客窝,周末交流会的知识点总结,20180930期。包括:
- 以面试题的形式提出的题目
- 问题的答案,因为工作量大,目前有半数答案还未整理。
- 知识扩展部分:在题目基础上提供进一步的扩展知识。
- 参考资料
极客窝-QQ群:779213122
每周末有技术交流会,只招募有分享精神和极客精神的小伙伴。
非诚勿扰!非诚勿扰!非诚勿扰!
目前技术点是Java、android、JVM、数据结构和算法。
极客窝技术交流会-0930
版本: 2018/09/30-23:59
文章目录
题目专区
啦啦啦
- Android中实现变声器的原理是什么?
- Android中如何获得录音?
- NDK和JNI的区别?
- NDK的实现步骤?
- 假如你去开发人工智能项目你会做什么?
小柯
- volatie关键字的意义?volatile修饰的变量的操作是否一定是原子操作?
- 下面代码会造成死锁吗?
public static void main(String[]args){
System.out.println("main");
method1();
System.out.println("main return");
}
static synchronized void method1() {
System.out.println("method1");
method2();
}
static synchronized void method2() {
System.out.println("method2");
//.....
}
-
ArrayList.getClass() 等于 ArrayList.getClass()吗?为什么?
-
线程池的工作机制
-
jvm有哪些内存分区?
-
Object obj = new Object()将有哪些内存分区的参与?对象一定是在堆上分配吗?举出一个反例
-
下面代码是否会报错?
public class Main {
private final CopyOnWriteArrayList<Integer> copyOnWriteArrayList = new CopyOnWriteArrayList<>();
public static void main(String[] args) {
Main main = new Main();
main.start();
}
private void start(){
// 1、add加入数据
for (int i = 0; i < 10; i++) {
copyOnWriteArrayList.add(i);
}
// 2、遍历List,删除某一项数据
for (Integer integer : copyOnWriteArrayList) {
if(integer == 2){
copyOnWriteArrayList.remove(integer);
System.out.println("remove 2");
continue;
}
System.out.println("" + integer);
}
}
}
循环部分等效于(两种形式可以互换):
Iterator iterator = copyOnWriteArrayList.iterator();
while(iterator.hasNext()){
Integer integer = (Integer) iterator.next();
if(integer == 2){
copyOnWriteArrayList.remove(integer);
System.out.println("remove 2");
continue;
}else{
System.out.println("" + integer);
}
}
- 循环部分修改为下面代码是否会报错?
// 1、遍历List,删除某一项数据。fori循环
for (int i = 0; i < copyOnWriteArrayList.size(); i++) {
Integer integer = copyOnWriteArrayList.get(i);
if(integer == 2){
copyOnWriteArrayList.remove(integer);
System.out.println("remove 2");
continue;
}
System.out.println("" + integer);
}
- 循环部分修改为下面代码是否会报错?
copyOnWriteArrayList.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
if(integer == 2){
copyOnWriteArrayList.remove(integer);
System.out.println("remove 2");
return;
}else{
System.out.println("" + integer);
}
}
});
- 采用ArrayList在遍历中删除数据是否会报错?
public class Main {
private static final ArrayList<Integer> arrayList = new ArrayList<>();
static{
for (int i = 0; i < 10; i++) {
arrayList.add(i);
}
}
public static void main(String[] args){
Main main = new Main();
main.start();
}
private void start(){
// 一般ArrayList在遍历中删除数据
for (Integer integer : arrayList) {
if(integer == 2){
arrayList.remove(integer);
System.out.println("remove 2");
continue;
}
System.out.println("" + integer);
}
}
}
- 采用fori的方式遍历ArrayList并且进行删除数据,是否会有问题?如下实例,是否会报错?不报错会打印出什么结果?
for (int i = 0; i < 10; i++) {
arrayList.add(i);
}
// 一般ArrayList在遍历中删除数据
for (int i = 0; i < arrayList.size(); i++) {
Integer integer = arrayList.get(i);
if(integer == 2){
arrayList.remove(integer);
System.out.println("remove 2");
continue;
}
System.out.println("" + integer);
}
- ArrayList触发ConcurrentModificationException异常的原因?
阿欢
- data-source数据源的理解,常用的都有哪些?
- 索引的分类相关知识的理解?
- 线程池的理解和运用?
两个脚丫
- float有+0.0F和-0.0F,Java内存中数值是否相等?+0.0F和-0.0F的数值是多少?
- Java中+0.0F == -0.0F 会返回true还是false?
- 基本类型是否会存储到
堆
中,如果可能会是什么情况? - 计算下面代码的平均时间复杂度、最好时间复杂度、最差时间复杂度、均摊时间复杂度
// array代表长度为n的数组
// array.length = n
int[] array = new int[n];
int count = 0;
void insert(int val){
if(count == array.length){
// 如果空间已满,求和并且将sum放置到array[0]
int sum = 0;
for (int i = 0; i < array.length; ++i) {
sum = sum + array[i];
}
array[0] = sum;
count = 1;
}
array[count] = val;
++count;
}
沉梦昂志
- Java中的面向对象
- Java中线程的含义
- Java中类与接口的区别
- Java中异常的含义和异常的分类?举例几种常见的异常
- Java中写出杨辉三角
长风
- 谈谈你对kotlin星号投影的理解
- kotlin中in、out分别代表什么含义
- kotlin中静态属性、静态方法如何定义
- kotlin中import和java中import有什么区别?
- 什么叫单项式、多项式
猎羽
- COW是什么?优缺点?
- CopyOnWriteArrayList内部的COW机制解决了访问操作和读取操作在多线程并发中的安全性问题?
- Fail-fast机制是什么?只有在多线程场景中才会触发该机制?
- Java垃圾回收中的引用计数法和可达性分析是什么?
- 可达性分析算法在多线程中遭遇的误报和漏报问题是什么?JVM如何解决该问题的?
- STW机制是什么?安全点的本质目的是让其他线程停止,从而等待GC线程的垃圾回收工作?
Sank
- 为什么可以在本地服务器上远程下载APK,而在远程服务器上就不可以?
- 学Android必须要学kotlin?它和Java有哪些区别?
- Java内存管理分为哪些部分?
- 垃圾回收都有哪些算法?Java回收机制(GC)采用的是哪种?
- JVM中哪些的内存需要回收?如何回收?
去霓虹看看
- scrollTo()和scrollBy()的区别?
- MeasureSpec是什么?有什么作用?
- onTouch()、ouTouchEvent()、onClick()的关系
- SurfaceView和View的区别
- 如何解决View的滑动冲突
- View的工作原理
满天星
- Service如何保活?
- 应用被强杀怎么办?
- IPC通信Binder原理
答案专区
啦啦啦
1、Android中实现变声器的原理是什么?
- 原理是通过AudioRecord录音,然后转成wav文件,进行变声生成变声好的wav文件。此外还可以将wav转成mp3文件。
- 利用
FMOD音频引擎
, 可以实现和QQ变声一样的功能。
2、Android中如何获得录音?
- 可以使用MediaRecorder 和 AudioRecord进行录音
- MediaRecorder: 已经集成了录音、编码、压缩等, 直接调用相关接口即可,代码量小.
- AudioRecord: 主要是实现边录边播(AudioRecord+AudioTrack)以及对音频的实时处理(如会说话的汤姆猫、语音)
3、NDK和JNI的区别?
- JNI表示
Java Native Inteface
- 是Java中定义的
一种用于连接Java和C/C++接口的一种实现方式
。- NDK表示
Native Development Kit
,是Google提供的一套用于快速创建native工程的工具。该工具能方便JNI代码的编写和调试
。
4、NDK开发的步骤?
- 安装配置NDK(配置环境变量)
- 给AS配置关联NDK: 在项目的local.properties中添加配置ndk的根目录
- 编写native方法
- 定义对应的JNI
- 指定需要编译的CPU, 如:
"armeabi", "armeabi-v7a", "x86"
- 编译生成so: 不同平台下的动态链接文件
- 加载so、调用native方法
5、假如你去开发人工智能项目你会做什么?
- 集成Google的
TensorFlow
- 做一个简单的图片分类器
小柯
1、volatie关键字的意义?volatile修饰的变量的操作是否一定是原子操作?
2、下面代码会造成死锁吗?
public static void main(String[]args){
System.out.println("main");
method1();
System.out.println("main return");
}
static synchronized void method1() {
System.out.println("method1");
method2();
}
static synchronized void method2() {
System.out.println("method2");
//.....
}
不会!
因为synchronized
是可重入锁
3、ArrayList.getClass() 等于 ArrayList.getClass()吗?为什么?
- 一样!泛型会在编译阶段确定。具有泛型擦除的特性。
- 泛型作为语法糖,作用在于提高开发者的效率。
4、线程池的工作机制
5、jvm有哪些内存分区?
- 方法区
- 堆
- PC寄存器
- Java方法栈
- 本地方法栈
6、Object obj = new Object()将有哪些内存分区的参与?对象一定是在堆上分配吗?举出一个反例。
- 如果obj是方法的局部变量: 三个区域
- 根据Object这个字面量到方法区定位到一个Class文件,加载该Class
- 在堆区分配内存给Object对象
- 虚拟机栈中创建obj引用,指向堆区中的该对象。
- 如果obj是对象的局部变量:两个区域
- 根据Object这个字面量到方法区定位到一个Class文件,加载该Class
- 在堆区分配内存给Object对象,并在堆区中有obj引用,指向该Object对象。
7、下面代码是否会报错?
不会报错!
public class Main {
private final CopyOnWriteArrayList<Integer> copyOnWriteArrayList = new CopyOnWriteArrayList<>();
public static void main(String[] args) throws IOException {
Main main = new Main();
main.start();
}
private void start(){
// 1、add加入数据
for (int i = 0; i < 10; i++) {
copyOnWriteArrayList.add(i);
}
// 2、遍历List,删除某一项数据
for (Integer integer : copyOnWriteArrayList) {
if(integer == 2){
copyOnWriteArrayList.remove(integer);
System.out.println("remove 2");
continue;
}
System.out.println("" + integer);
}
}
}
循环部分等效于(两种形式可以互换):
Iterator iterator = copyOnWriteArrayList.iterator();
while(iterator.hasNext()){
Integer integer = (Integer) iterator.next();
if(integer == 2){
copyOnWriteArrayList.remove(integer);
System.out.println("remove 2");
continue;
}else{
System.out.println("" + integer);
}
}
8、循环部分修改为下面代码是否会报错?
不会报错!
// 1、遍历List,删除某一项数据。fori循环
for (int i = 0; i < copyOnWriteArrayList.size(); i++) {
Integer integer = copyOnWriteArrayList.get(i);
if(integer == 2){
copyOnWriteArrayList.remove(integer);
System.out.println("remove 2");
continue;
}
System.out.println("" + integer);
}
9、循环部分修改为下面代码是否会报错?
不会报错!
copyOnWriteArrayList.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
if(integer == 2){
copyOnWriteArrayList.remove(integer);
System.out.println("remove 2");
return;
}else{
System.out.println("" + integer);
}
}
});
10、采用ArrayList在遍历中删除数据是否会报错?
会报错!
public class Main {
private static final ArrayList<Integer> arrayList = new ArrayList<>();
static{
for (int i = 0; i < 10; i++) {
arrayList.add(i);
}
}
public static void main(String[] args){
Main main = new Main();
main.start();
}
private void start(){
// 一般ArrayList在遍历中删除数据
for (Integer integer : arrayList) {
if(integer == 2){
arrayList.remove(integer);
System.out.println("remove 2");
continue;
}
System.out.println("" + integer);
}
}
}
11、采用fori的方式遍历ArrayList并且进行删除数据,是否会有问题?如下实例,是否会报错?不报错会打印出什么结果?
会遗漏了3
for (int i = 0; i < 10; i++) {
arrayList.add(i);
}
// 一般ArrayList在遍历中删除数据
for (int i = 0; i < arrayList.size(); i++) {
Integer integer = arrayList.get(i);
if(integer == 2){
arrayList.remove(integer);
System.out.println("remove 2");
continue;
}
System.out.println("" + integer);
}
结果: 遗漏了3
0
1
remove 2
4
5
6
7
8
9
12、ArrayList触发ConcurrentModificationException异常的原因?
触发了快速失败机制(Fast-Fail)
阿欢
1、data-source数据源的理解?
- JDBC2.0 提供了javax.sql.DataSource接口.(用于Spring?)
- 它负责建立与数据库的连接,访问数据库时不必编写连接数据库的代码
- 直接引用DataSource获取数据库的连接对象即可。
2、data-source数据源常用的都有哪些?
- postgre 数据库
- mysql数据库
- oracle数据库
3、索引的分类相关知识的理解?
- 在mysql中,索引(index)又叫键(key)
- 它是存储引擎用于快速找到所需记录的一种数据结构。在越来越大的表中,索引是对查询性能优化最有效的手段,索引对性能影响非常关键。
- mysql的索引是在存储引擎层实现,而不是在服务器层。
4、线程池的理解和运用?
- 为什么需要线程池?
- 每个线程的创建/销毁都有一定开销,通过维护一定量的线程就可以减少这些开销。
- 线程各自为政,难以控制管理。
- Executor框架的作用?
- Java 1.5开始提供Executor框架用于把
任务提交
和任务处理
解耦- 任务的提交:交给Runnable、Callable处理。
- 任务的处理:交给Executor框架。
- Executor框架核心是ThreadPoolExecutor-也就是线程池的核心实现类
- ThreadPoolExecutor的作用?
- ThreadPoolExecutor构造方法的七个重要参数的作用?
- 线程池内部的处理流程和原理?
- 使用线程池的几种方法?
两个脚丫
- float有+0.0F和-0.0F,Java内存中数值是否相等?+0.0F和-0.0F的数值是多少?
- Java中+0.0F == -0.0F 会返回true还是false?
- 基本类型是否会存储到
堆
中,如果可能会是什么情况? - 计算下面代码的平均时间复杂度、最好时间复杂度、最差时间复杂度、均摊时间复杂度
// array代表长度为n的数组
// array.length = n
int[] array = new int[n];
int count = 0;
void insert(int val){
if(count == array.length){
// 如果空间已满,求和并且将sum放置到array[0]
int sum = 0;
for (int i = 0; i < array.length; ++i) {
sum = sum + array[i];
}
array[0] = sum;
count = 1;
}
array[count] = val;
++count;
}
沉梦昂志
- Java中的面向对象
- Java中线程的含义
- Java中类与接口的区别
- Java中异常的含义和异常的分类?举例几种常见的异常
- Java中写出杨辉三角
长风
- 谈谈你对kotlin星号投影的理解
- kotlin中in、out分别代表什么含义
- kotlin中静态属性、静态方法如何定义
- kotlin中import和java中import有什么区别?
- 什么叫单项式、多项式
猎羽
- COW是什么?优缺点?
- CopyOnWriteArrayList内部的COW机制解决了访问操作和读取操作在多线程并发中的安全性问题?
- Fail-fast机制是什么?只有在多线程场景中才会触发该机制?
- Java垃圾回收中的引用计数法和可达性分析是什么?
- 可达性分析算法在多线程中遭遇的误报和漏报问题是什么?JVM如何解决该问题的?
- STW机制是什么?安全点的本质目的是让其他线程停止,从而等待GC线程的垃圾回收工作?
Sank
1、为什么可以在本地服务器上远程下载APK,而在远程服务器上就不可以?
- 学Android必须要学kotlin?它和Java有哪些区别?
- Java内存管理分为哪些部分?
- 垃圾回收都有哪些算法?Java回收机制(GC)采用的是哪种?
- JVM中哪些的内存需要回收?如何回收?
去霓虹看看
- scrollTo()和scrollBy()的区别?
- MeasureSpec是什么?有什么作用?
- onTouch()、ouTouchEvent()、onClick()的关系
- SurfaceView和View的区别
- 如何解决View的滑动冲突
- View的工作原理
知识扩展专区
ArrayList线程安全问题
1、ArrayList为什么不是线程安全的?
- 内部使用Object数组存储数据,并使用size表明当前存储的元素个数
- add()等操作可能会出现
数据越界
或者出现一个线程中添加的值,覆盖了另一个线程添加的值
如线程A-add(10), 线程B-add(20), 本来应该ArrayList中新增了10和20两个值。但是实际会出现只增加了其中一个数值。- 原因是
size++
这个操作不具有原子性,size可能被其他线程修改,导致add等写操作
遇到问题- 此外,调用get方法时,被其他线程改变了值,导致get获取到的值和设想的不一样。
2、add()可能会出现数组越界问题。
CopyOnWriteArrayList
1、CopyOnWriteArrayList是什么?
- JDK 1.5开始,Java并发包里面提供的使用COW(Copy-On-Write)机制的并发容器
- 同包提供的另一个并发容器是
CopyOnWriteArraySet
- 在并发环境下依旧能工作,也不会曝出
java.util.ConcurrentModificationException
异常
2、COW机制是什么?
- 写时复制,Copy-On-Write
- 基本思路就是,读取数据时是共享同一份内容,当需要修改时,会复制出一份新内容,然后再修改。如下图:
- 特点是最终一致性, 无法保证实时性要求。
3、COW的优点和缺点
- 优点:
- 在多个线程中并发访问,读取操作不会阻塞其他操作(常规为了线程安全性,会进行线程同步,进而产生阻塞。)
- 解决了多线程中的安全问题,都是从原始容器中读取数据。即使其他线程进行add等修改操作,都不会影响到get访问操作。
- 缺点:
- 无法保证实时性要求:写操作时,会对复制的数据进行操作,操作完成后会将引用指向
新容器
,但是这样可能会出现访问操作
读取的不是最新值的问题。
4、COW保证了CopyOnWriteArrayList的多线程中并发读取操作的安全性?也保证了写入的安全性?所以CopyOnWriteArrayList很高效,不再需要锁机制?
- 解决了不需要同步,就可以在多线程中进行并发读取的操作。
- 对于
写入
操作,还是需要锁机制,COW无法解决多个线程并发写入的覆盖问题。
5、CopyOnWriteArrayList为什么是多线程安全的?
- COW解决访问操作的安全性问题
- 内部采用
ReentrantLock lock
进行加锁,解决写入操作
的安全性问题
6、CopyOnWriteArrayList适合什么场景?不适合什么场景?
- 适合读取操作多,写入操作少的场景: 写入操作时,需要复制容器,造成的内存开销很大。
- 不适合的场景:要求数据修改后立即能被读取到,就不能用COW技术。COW技术的特点是最终一致性。
Iterator
7、Iterator内部的快照是什么?随着数据的读写,Iterator内部的快照会变吗?
1-CopyOnWriteArrayList的Iterator是COWIterator
2-SnapShot是一个final数组,因此不会再改变。
public Iterator<E> iterator() {
return new COWIterator<E>(getArray(), 0);
}
static final class COWIterator<E> implements ListIterator<E> {
// 1、快照,创建之后不会再改变
private final Object[] snapshot;
// 2、当前元素的索引值
private int cursor;
COWIterator(Object[] elements, int initialCursor) {
cursor = initialCursor;
snapshot = elements;
}
}
synchronized
8、synchronized方法和synchronized某个对象的区别?
- synchronized方法
- 非静态方法,锁是当前对象。
- 静态方法,锁是Class对象
- synchronized某个对象,锁就是该对象
9、synchronized在JVM中的体现
- synchronized方法: 方法在编译后,会有
ACC_SYNCHRONIZED
描述符,用于标识是否为同步方法
- synchronized(对象): 在对象的对象头中有一个标记字段-Mark Word,标记字段有一个锁标识位(lock),该标志为记录着对象的锁的类型
10、对象头标记字段中的锁标识位
锁标识位(lock):
01 无锁
01 偏向锁
00 轻量级锁
10 重量级锁
Fail-Fast机制
1、Fail-Fast机制机制是什么?
- Fail-Fast机制是Java集合中的一种
错误机制
- 多个线程对同一个集合的数据同时进行操作时,就会产生
Fail-Fast
事件,抛出ConcurrentModificationException
- 该机制不仅仅作用于多线程。
- 单线程如果违反了该规则,依旧会抛出该异常。
List遍历(5种)
普通for循环
增强型for
迭代器
录音处理
FMOD
1、FMOD是什么?
- fmod Ex 声音系统是为游戏开发者准备的革命性音频引擎。
- 如今采用了FMOD作为音频引擎的游戏包括孤岛惊魂、幽灵行动,甚至著名的魔兽争霸。
录音功能
2、Android如何实现录音功能?
可以通过两个系统提供的功能:
- MediaRecorder
- AudioRecord
3、MediaRecorder的功能和优缺点
- 功能:
- 已经集成了录音、编码、压缩等功能,
- 支持少量的录音音频格式:
.aac .amr .3gp
- 优点:
- 直接调用相关接口即可,代码量小
- 缺点:
- 无法实时处理音频;
- 输出的音频格式不是很多,例如没有输出mp3格式文件
4、AudioRecord的功能和优点
- 功能:
- 主要是实现边录边播(AudioRecord+AudioTrack)
- 以及对音频的实时处理(如会说话的汤姆猫、语音)
- 优点:
- 语音的实时处理,可以用代码实现各种音频的封装
- 缺点:
- 输出是PCM语音数据,如果保存成音频文件,不能通过播放器播放的
- 必须编写代码实现数据编码以及压缩
录音
参考资料
集合
- List的5种遍历方式解析
- 并发编程6:CopyOnWriteArrayList 的写时复制
- 为什么ArrayList是线程不安全的
- Fail-Fast机制
- JAVA中写时复制(Copy-On-Write)Map实现