注:以下问题答案都是自己在网上找的一些答案,如若存在问题,请指正,感谢。
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并返回结果。








网友评论