8种基本数据类型
总结:byte=boolean(1)<char=short(2)<int =float(4)<long=double(8)
每个类型所占bit数=字节*8(bit) 1byte=8bit
java的特性
封装、继承、多态(三大特性)、抽象
什么是多态
多态机制是依靠继承机制实现的
理解面向对象编程思想
static可修饰什么?有什么作用?
static可修饰方法、变量、类、代码块:被static修饰的变量和方法是独立于该类的,它不依赖于某个特定的实例变量,也就是说它被该类的所有实例共享。
静态变量:在类加载时被完成初始化,它在内存中仅有一个,且JVM也只会为它分配一次内存
静态方法:在类加载的时候就存在了,它不依赖于任何实例,所以static方法必须实现,也就是说他不能是抽象方法abstract。
static修饰类时,只可修饰内部类。
被static修饰的代码块,我们称之为静态代码块,静态代码块会随着类的加载一块执行,而且他可以随意放,可以存在于该了的任何地方。
静态的就是共享的
静态方法中不可调用非静态方法
final可修饰什么?有什么作用?
final可修饰类、方法、变量
被final修饰的类不能被继承
被final修饰的方法不可被重写,可以被重载(也必须是final方法)
被final修饰的变量载声明的时候必须进行初始化,之后不可被修改
方法的重载、重写
重载:overload->同一个类中有多个同名的方法(参数个数或参数类型或参数顺序不一样);好处是提高效率,省时省力;
重写:override->重写通常是重写父类方法,当父类方法不能满足业务需求时,可以对父类中的方法进行重写
sleep与wait的区别?
wait是Object的一个函数,指线程处于进入等待状态,此时线程不占用任何资源,不增加时间限制。wait可以被notify和notifyAll函数唤醒(这两个也是Object的函数)。
sleep则是Thread的一个函数,指线程被调用时,占着CPU不工作.此时,系统的CPU部分资源被占用,其他线程无法进入,会增加时间限制。
区别:
1、sleep()不会释放同步资源对象锁,wait()会释放对象锁
2、sleep()可以在任何地方使用,wait()只能在同步方法或代码块使用(synchronized)
3、sleep()是Thread类中的方法(调用时会暂停此线程指定的时间,监控依旧,不会释放对象锁,到时自动恢复),wait()是Object类中的方法(调用会放弃对象锁,进入等待队列,待调用notify()/notifyAll()唤醒指定的线程或者所有线程,才会进入锁池,
不再次获得对象锁才会进入运行状态)
1、equals 是方法,而 == 是操作符(基本数据类型比较只能用==来判断)
2、equals()方法是用来判断其他的对象是否和该对象相等(equals方法没有被重写时比较的是它们在内存中的存放地址,若重写了则按自定义的规则来判断)
线程
1、通过继承Thead类并重写写run()函数的方式
2、通过实现Runnable接口的方法
方式1:
public class CreateThreadOne extends Thread {
@Override
public void run() {
super.run();
}
}
方式2:
public class CreateThreadTwo implements Runnable {
@Override
public void run() {
}
}
用法:
new CreateThreadOne().start();
new CreateThreadTwo();
阻塞状态分类
等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
同步阻塞:线程在获取synchronized同步锁失败(因为锁被其它线程占用),它会进入到同步阻塞状态;
其他阻塞:通过调用线程的sleep()或join()或发出I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
线程同步的有几种方法 详细介绍传送门:
https://blog.csdn.net/scgyus/article/details/79499650
1、使用synchronized关键字
2、wait和notify
3、使用特殊域变量volatile实现线程同步
4、使用重入锁实现线程同步
5、使用局部变量来实现线程同步
6、使用阻塞队列实现线程同步
7、使用原子变量实现线程同步
java中多线程通信方式
在java中多线程间的通信使用的是等待/通知机制来实现的
android中线程间通信:Handle(2种创建方式:主线程、子线程)、接口、广播等
synchronied关键字等待/通知机制:是指一个线程A调用了对象O的wait()方法进入等待状态,而另一个线程B调用了对象O的notify()或者notifyAll()方法,线程A收到通知后从对象O的wait()方法返回,进而执行后续操作。上述的两个线程通过对象O来完成交互,而对象上的wait()和notify()/notifyAll()的关系就如同开关信号一样,用来完成等待方和通知方之间的交互工作。
等待/通知机制主要是用到的函数方法是notify()/notifyAll(),wait()/wait(long),wait(long,int),这些方法在上一篇文章都有说明过,这里就不重复了。当然这是针对synchronied关键字修饰的函数或代码块,因为要使用notify()/notifyAll(),wait()/wait(long),wait(long,int)这些方法的前提是对调用对象加锁,也就是说只能在同步函数或者同步代码块中使用。
条件对象的等待/通知机制:所谓的条件对象也就是配合前面我们分析的Lock锁对象,通过锁对象的条件对象来实现等待/通知机制。那么条件对象是怎么创建的呢?
Condition conditionObj=ticketLock.newCondition();
线程共享的区域有哪些
由所有线程共享的数据区是:方法区和堆
线程死锁的原因?来源-那个人
https://juejin.im/post/59e9ac446fb9a045167c520a
死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.由于线程被无限期地阻塞,因此程序不能正常运行。
导致死锁的根源在于不适当地运用“synchronized”关键词来管理线程对特定对象的访问.“synchronized”关键词的作用是,确保在某个时刻只有一个线程被允许执行特定的代码块,因此,被允许执行的线程首先必须拥有对变量或对象的排他性访问权.当线程访问对象时,线程会给对象加锁,而这个锁导致其它也想访问同一对象的线程被阻塞,直至第一个线程释放它加在对象上的锁
出现死锁可能的原因
当我们了解在什么情况下会产生死锁,以及什么是死锁的时候,我们在写代码的时候应该尽量的去避免这个误区.产生死锁必须同时满足以下四个条件,只要其中任一条件不成立,死锁就不会发生.
1、 互斥条件:线程要求对所分配的资源进行排他性控制,即在一段时间内某 资源仅为一个进程所占有.此时若有其他进程请求该资源.则请求进程只能等待.
2、不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的线程自己来释放(只能是主动释放).
3、请求和保持条件:线程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他线程占有,此时请求线程被阻塞,但对自己已获得的资源保持不放.
4、循环等待条件:存在一种线程资源的循环等待链,链中每一个线程已获得的资源同时被链中下一个线程所请求。
1.加锁顺序
http://ifeve.com/deadlock-prevention/#ordering
2.加锁时限
http://ifeve.com/deadlock-prevention/#timeout
3.死锁检测
http://ifeve.com/deadlock-prevention/#detection
参考资料
http://www.cnblogs.com/vinozly/p/5240204.html
https://www.diycode.cc/topics/597
内存管理机制
进程
java中的多进程
线程与进程的区别
线程是进程的组成部分,一个进程可以有很多线程,每条线程并行执行不同的任务。
不同的进程使用不同的内存空间,而线程与父进程的其他线程共享父进程的所拥有的全部资源。这样编程方便了,但是要更加小心。
每个线程都拥有单独的栈内存用来存储本地数据。线程拥有自己的堆栈、自己的程序计数器和自己的局部变量,但不拥有系统资源。别把内存空间和栈内存搞混
线程的调度和管理由进程本身负责完成。操作系统对进程进行调度,管理和资源分配。
多线程优势
进程之间不能共享内存,但线程之间共享内存。
系统创建进程时需要为该进程重新分配系统资源,但创建线程则代价小很多,效率高。
资源利用率更好
程序设计更简单
程序响应更快
进程间通讯方式
(1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
(2)命名管道(named pipe):命名管道克服了管道没有名字的限制,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。
(3)信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送 信号给进程本身。
(4)消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。
(5)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。
(6)内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。
(7)信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
(8)套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。
java中GC回收机制
HashMap与HashTable的区别
hashMap线程不安全,hashtable线程安全
hashMap允许key=null,value=null;hashTable不允许
hashTable的方法是被synchronized的,hashMap不是,多线程同时操作hashMap时会出现问题,需要设置实现同步方法
HashTable 继承自 Dictionary 类,而 HashMap 是 Java1.2 引进的 Map interface 的一个实现
Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable
HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
abstract class AbstractMapimplements Map,v>
了解更多一点Map
https://blog.csdn.net/qq_30683329/article/details/80455779
HashMap的底层实现
I/O操作为什么要用缓冲流
目的:提高处理(复制)文件的效率
字节缓冲流:BufferedInputStream,BufferedOutputStream
字符缓冲流:BufferedReader,BufferedWriter
缓冲流类属于处理流,因此必须结合节点流来使用
字节缓冲流类结合 : FileInputStream, FileOutputStream
字符缓冲流类结合:FileReader,FileWriter
String是不可变字符串通过“+”看上去字符串变了,实际上在内存中生成了 多个字符串对象
StringBuffer与StringBuilder都是可变字符串.append("追加的字符")
StringBuffer线程安全,效率较低
StringBuilder线程不安全,效率较高
ArrayList元素在位置上有序,可以重复,插入或删除元素较慢,查找效率 高,采用队列来管理元素
LinkedList元素在位置上有序,可以重复,插入或删除元素较快,查找效率较 低,采用链表原理管理所有元素
Android中Context的子类
context是一个抽象类(public abstract class Context {})
这篇介绍Context的文章很详细类
https://blog.csdn.net/guolin_blog/article/details/47028975
设计模式
三个分类 摘自博客
https://www.cnblogs.com/pony1223/p/7608955.html
image.png
TCP/IP协议四层模型
tcp与udp
http
https
http与http区别
public static void sort(int[] arr) {
int i, j, temp, len = arr.length;
for (i = 0; i < len - 1; i++)
for (j = 0; j < len - 1 - i; j++)
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
public class Node {
public int data;
public Node next;
public Node() {
}
public Node(int data) {
this.data = data;
}
public Node(int data, Node next) {
this.data = data;
this.next = next;
}
}
四大组件
activity
要知道四种启动模式都是什么,有什么区别,各个生命周期方法,主题修改等
service
如何使用,2种不同启动方式,有什么不同,生命周期,运行在那个线程
ContentProvider
如何使用
BroadcastReceiver
使用方法,2种注册(AndroidManifest.xml种静态注册、动态注册)方式及区别
IntentService
Fragment
application的生命周期
Service生命周期及用法
support包下有哪些新控件
自定义View
Touch事件分发
View的渲染过程
android开机启动流程
进程保活
IPC
ThreadLocal原理
Handler的创建方式
1、在主线程(UI线程)创建
public class ThreadDemo extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
}
MyHandler handler = new MyHandler();
private static class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
}
private void initData() {
new Thread(new Runnable() {
@Override
public void run() {
SystemClock.sleep(1000);
handler.sendEmptyMessage(0);
}
}).start();
}
}
2、在子线程中创建
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
Handler myHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
myHandler.sendEmptyMessage(1);
Looper.loop();
}
}).start();
mvp mvc mvvm
JNI流程
指针作用,占多少内存
二级指针作用,占多少内存
如何生成so库文件
如何选用三方框架
Lambda 表达式
lambada表达式的java8的新特性,lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)
基本语法:
(parameters) -> expression 或 (parameters) ->{ statements; }
appName.setOnClickListener(v -> {
appName.setOnClickListener(v -> Toast.makeText(this, "这是一个吐司", Toast.LENGTH_SHORT).show());
adb的使用,如何查看cpu内存情况
无线连接手机的原理
安全性怎么保证
如何保证一个app的稳定性
git相关命令
git:如何解决冲突,命令行指令(手写)
依赖关系(dependence)
泛化关系
关联关系
聚合关系
组合关系
实现关系(implementation)
(仅供参考)
1、公司目前的业务是做什么的?(大体了解)
2、公司目前的项目面临的最大困难是什么?(如果面试成功,这很有可能是你要面对的了;还有就是很多面试官也会问你同样的问题,哈哈….相信很多人都被问过吧)
3、如果能进入公司,主要工作是做什么?(了解工作内容看是否能够胜任吧)
4、通过这次面试,您觉得我还有哪些不足?能给点建议和指导吗?(成长)
5、对于离职率大的公司,问:您觉得离职率这么大的主要原因是什么呢?(更一步了解)
说说你未来的职业规划(5年、10年)
1、专精技术路线(工程师->初级工程师->中级工程师->高级工程师->资深工程师->技术专家->行业科学家)
2、技术与某一具体行业结合 深入耕耘成为某一行业的顶尖技术人才
3、先做技术,在合适的时机(机遇到来时)转向管理岗
4、积累一笔资金去创业
其他
由于个人掌握知识的水平有限,如有表达有误或不够完善的,欢迎大家评论指出
内容很多,工作很忙,所以正在逐步完善中,欢迎大家一起来共同完善~
如果您觉得不错,请别忘了转发、分享、点赞让更多的人去学习, 您的举手之劳,就是对小乐最好的支持,非常感谢!