注:以下问题答案都是自己在网上找的一些答案,如若存在问题,请指正,感谢。
Java相关
问:
Socket
和Http
有什么关联
答:Socket
本身并不是协议,而是一个调用接口API
。Socket
是对Tcp/Ip
协议(传输层协议)的封装和应用。所以Socket
跟Tcp/Ip
协议没有必然的联系。Socket
出现使得程序员更方便的使用Tcp/Ip
协议栈。另位:Socket
是传输层和网络层的。
而Http
是应用层协议,位于Tcp/Ip
协议(传输层协议)上层。Http
最显著的特点是客户端发送的每次请求都需要服务器响应,请求结束之后会主动释放链接,从建立连接到关闭连接的过程称为“一次连接”
综上:Http
要基于Socket
实现,发出一个http请求就相当于建立一个socket通信的过程。*
拓展:Http
协议传输的数据都是未加密的,也就是明文的。为了保证这些隐私数据能加密传输,于是网景公司设计了 SSL
(Secure Sockets Layer)协议对http协议传输的数据进行加密。从而诞生了Https
。实际上现在的Https
都是采用TSL
协议。
问: Https加密如何实现:
答:Https
在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握手过程中将确立双方加密传输数据的密码信息。TLS/SSL
协议不仅仅是一套加密传输的协议,更是一件经过艺术家精心设计的艺术品,TLS/SSL
中使用了非对称加密,对称加密以及HASH算法。
问:
String
的值可变吗;String StringBuilder StringBuffer
区别
答:String
由final修饰,所以不可变;
StringBuilder StringBuffer
的值可变。StringBuilder
线程不安全,StringBuffer
线程安全。
运行速度:StringBuilder
> StringBuffer
>String
问:如有线程1,线程2,线程3 等3个线程,现如线程1或者线程2执行完任务,如何通知线程3执行任务?
答:
常见的单例模式有哪些写法?请手写一种单例模式。
答:
面向对象的特征有哪些,
多态
如何体现?
答:
问:
Get
和Post
的区别
答:
问:创建线程有哪些方式?
问:谈谈对wait和notify关键字的理解?
问:Java 中
fail-fast
和fail-safe
的区别?
答:当多个线程对同一个集合
Android 篇
问:能否在
Activity
的OnCreate()
方法中进行控件宽高测量,如不能有哪些方式可以进行测量?OnResume()
能否进行测量?
答:OnCreate()
和OnResume()
都不能进行测量。我自己找到的具体测量方法目前有三:
方法一:
// 设置监听
tv.viewTreeObserver.addOnGlobalLayoutListener(this)
@RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
override fun onGlobalLayout() {
if (tv.viewTreeObserver.isAlive) {
tv.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
Log.d(TAG,"onGlobalLayout ---> width:" + tv.width + " height:" + tv.height)
}
方法二:
tv.viewTreeObserver.addOnPreDrawListener(this)
override fun onPreDraw(): Boolean {
if (tv.viewTreeObserver.isAlive) {
tv.viewTreeObserver.removeOnPreDrawListener(this)
}
Log.d(TAG,"onPreDraw ---> width:" + tv.width + " height:" + tv.height)
return true
}
方法三:
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
Log.d(TAG,"onWindowFocusChanged ---> width:" + tv.width + " height:" + tv.height)
}
image.png
问:常见的
Activity
的Intent Flag
答:
问:如何实现自定义view ;自定义view绘制过程;UI刷新重绘方法中,invalidate() 、postInvalidate()、requestLayout() 区别。
答:
invalidate、postInvalidate和requestLayout区别
问:如何实现数据库中数据迁移
答:
问:使用glide碰到的问题
答:
问:简单介绍一下 android性能优化。
答:
-
布局优化
- 采用<include>标签,<merge>标签,ViewStub。
- 避免多度绘制
-
绘制优化:避免
onDraw
执行大量操作-
onDraw
中不要创建新的局部对象。 -
onDraw
方法中不要做耗时的任务,也不能执行成千上万次的循环操作
-
-
内存泄漏优化
- 通过
LeakCanary
来检测内存泄漏
- 通过
-
响应速度优化:避免在主线程中做耗时操作 ,或者轻微的耗时操作。
- Activity如果5秒钟之内无法响应屏幕触摸事件或者键盘输入事件就会出现ANR;BroadcastReceiver如果10秒钟之内还未执行完操作也会出现ANR
-
ListView/RecycleView及Bitmap优化
- 采用ViewHolder模式来提高效率
- ListView/RecycleView的滑动时停止加载和分页加载
- Bitmap优化 对加载图片进行压缩,避免加载图片多大导致OOM出现。
-
线程优化
-
其他性能优化建议
问:说一下
Retrofit
答:Retrofit
是okhttp
的加强版,底层是使用okhttp
封装的。网络请求本质还是okhttp
,而Retrofit
仅负责网络请求接口的封装。
使用:
- 定义请求接口:
public interface ServiceAPI {
public String API_URL = "";
@GET("/test/news")
Call<News> getNews(
@Path("time") String time,
@Path("name") String name
);
}
- 通过
Retrofit
生成接口实现类,使用的是动态代理
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ServiceAPI.API_URL)
.addConverterFactory(...)
.client(httpClient) // 注释 1
.build();
注释1:如果不设置.client(httpClient)
,则会默认new一个OkHttpClient
,请看源码.
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
...
}
如果设置的话,需要初始化一个httpClient。
OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(...)
.connectTimeout(...)
.build();
继续以上,通过接口实现类,进行网络请求:
// 通过retrofit 生成一个接口实现类,使用的是动态代理
ServiceAPI serviceAPI = retrofit.create(ServiceAPI.class);// 注释2
Call<News> contributors = serviceAPI.getNews("time", "name");
Retrofit原理浅析
注释2:生成动态代理实例
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
// ServiceMethod 中的adapt方法
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
可以看到,通过反射拿到了method
,并为每个method
创建了ServiceMethod
,然后通过serviceMethod
对象创建了OkHttpCall
实例,最后通过serviceMethod
的实例调用callAdapter
来调用okhttpCall并返回结果。
网友评论