由于负责系统稳定性和性能监控的同事离职了,所以领导希望我来与剩下的同事一起负责这个事,那没法了,学吧~
最近搞PKI,遇到问题经常不明所以,后来找同事帮忙抓包才定位到原因,瞬间感觉学习抓包的重要。
最近研究PKI,想实现私钥不出TEE这个需求,需要确认okhttp中SSL认证的实现,结果说看看源码吧,让我好一顿找阿,特此记录一下过程。
这是我跟随秋少的系列课程Android系统开发入门做的笔记,感谢原博主秋少!
课程连接
这是我跟随秋少的系列课程Android系统开发入门做的笔记,感谢原博主秋少!
课程连接
这是我跟随秋少的系列课程Android系统开发入门做的笔记,感谢原博主秋少!
课程连接
这是我跟随秋少的系列课程Android系统开发入门做的笔记,感谢原博主秋少!
课程连接
今天重新安装了ubuntu20.04LTS,安装了IDEA后发现不能用adb连接车机,报错: 1 no permissions (missing udev rules? user is in the plugdev group) 在这里找到了解决办法,感最近工作要求,涉及到了HAL层开发,让我这个刚刚从上层转底层的小白无所适从,根本不知道怎么入手,从网上搜集了大堆的文章,照着做没有一个能成,前前后后一个月了,今天终于成功了,特此记录一下,希望能帮到其他像我一样高转低的同行吧。
今天又弄了一下fcitx5,并且配置了go环境变量,然后重启了一下电脑,到了登录页面,输入密码,竟然又退到登录页面,无论如何也进不去桌面。
最近事多,整天瞎忙,都是沟通、开会、填表格和填坑,今天想休息休息,打算有空再写写后端服务,把自己的网盘和图床先弄好。思来想去,自己一个人的项目,时间少,所以尽量还是要方便维护,那么就不要用JAVA了,罗里吧嗦的,可惜Dart这边没什么好的框架,要不然一个语言全站了,最终还是选择了kotlin,但是又不想用idea,于是我瞄向了vscode…
今天是我过得非常不爽的一天,因为今天说了『我不会』『我不懂』『我看不明白』,从哥2017年自学安卓到现在,从一点不会到基本不百度,我还没说过这些话。今天真是太刺激了,从上层转底层真的这么费劲吗,还是说年纪大了学不动了?都不是,是我一开始学系统底层还没找到要领,同时又事物缠身,分身无术。仔细想想还是先从常用工具入手,别他妈让我抓个log都这么费劲。
前段时间面试滴滴的时候,跟面试官聊了一下属性动画,上来就问:你看过源码吗?我说没看过,然后他表示属性动画并不是真正的改变view的属性,原因是一个例子:在constraintlayout中,通过相互约束定义纵向的一列view,然后通过属性动画,让第一个view平移,你认为下面的view是否会跟着动?他的结论是从系统设计上,谷歌就不可能允许跟着动的情况,因为我们指定动画的目标就是第一个view,所以平移操作也应该局限在第一个view中,而不应该影响其他的view。我当时觉得他太牛逼了,能从源码想到设计思想,后面我还靠他这个结论去忽悠过其他人,而其他人也觉得我很牛逼,哈哈哈。今天心血来潮,自己写个demo测一下,通过属性动画去改view的x位置,结果下面的view真的没有跟着动,可是接下来的表现却让我瞠目结舌。
最近打算自己开发独立App,那么首先考虑的就是账号密码的网络传输安全,也就是所谓的登录安全。
同样基于交换的思想,选择排序法的效率要比冒泡排序高很多。
冒泡法可以用来找队列中的最大值,也可以通过多次冒泡对集合进行排序。
一个无限大的文件,里面包函大量的数据,需求是从中取出top50。
面试题:场景需要在子线程中依次执行多个子任务,要保证任务时序,所有子任务执行完毕该线程自动退出,怎么实现?
假设有个单向链,我们并不知道长度,要求找到倒数的第N个节点。
按下电源键,首先从加载并运行BootLoader; BootLoader拉起linux内核; linux内核启动后会加载init.rc文件,并启用了Hugo这一段时间,一直搞不明白图片怎么存放比较好,也一直弄不清楚Leaf Bundle和Branch Bundle有什么区别,今天有点时间,终于搞清楚了,并且图片也成功在Github-pages上显示出来了,特此记录一下吧!
过年这几天鼓捣一下树莓派,结果各种麻烦,尤其是安装docker-compose,明明docker安装很顺畅,为啥这货就这么麻烦呢?
过年这几天鼓捣一下树莓派,结果各种麻烦。。。尤其是在挂载exFat格式的移动硬盘的时候,明明临时挂载是没有问题的,但是一旦做了开机自动挂载的话,就连系统都启动不了了。经过不懈的百度,终于解决了问题,特此记录一下。
之前已经了解过,OkHttp默认添加CacheInterceptor来处理缓存,而后者是依靠DiskLruCache
来实现硬盘缓存读写,所以我先去看了一下Android内置的LruCache
原理,是依靠java的LinkedHashMap
的LRU排序算法实现的,最后我准备详细看看DiskLruCache
是怎么基于硬盘缓存实现LRU的。
LRU这个算法就是把最近一次使用时间离现在时间最远的数据删除掉,而实现LruCache将会频繁的执行插入、删除等操作,我们就会想到使用LinkedList,但是我们又要基于Key-Value来保存数据,这个时候我们就会想起HashMap,但是HashMap不能像linkedList那样保留数据的插入顺序,如果要使用HashMap的话可以使用它的一个子类LinkedHashMap。
RealCall中的传值 1 2 3 ... interceptors.add(new BridgeInterceptor(client.cookieJar())); ... RealCall在创建这个拦截器的时候只传递了一个cookieJar。 作用 这个类的注释如下: Bridges from application code to
RealCall中的传值 1 2 3 ... interceptors.add(new CacheInterceptor(client.internalCache())); ... RealCall在创建这个拦截器的时候只传递了一个cookieJar。 作用 这个类的注释如下: Serves requests from the cache
ConnectInterceptor 连接拦截器 作为第二个实际生效的拦截器,ConnectInterceptor 的代码非常简单。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24quarkus可以从.properties文件中读取配置。
RealCall中的传值 1 2 3 4 5 6 private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) { this.client = client; this.originalRequest = originalRequest; this.forWebSocket = forWebSocket; this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket); } RealCall初始化时,会创建这个RetryAndFol
初始化调用 1 2 3 4 5 6 7 8 9 10 public final class RetryAndFollowUpInterceptor implements Interceptor { ... @Override public Response intercept(Chain chain) throws IOException { ... // 初始化数据流分配器 StreamAllocation streamAllocation = new StreamAllocation(client.connectionPool(),createAddress(request.url()), call, eventListener, callStackTrace); StreamAllocation是在Re回顾并且深入一下OkHttp(v3.10.0)的原理。
Crash(应用崩溃)是由于代码异常而导致 App 非正常退出,导致应用程序无法继续使用,所有工作都停止的现象。发生 Crash 后需要重新启动应用(有些情况会自动重启),而且不管应用在开发阶段做得多么优秀,也无法避免 Crash 发生,特别是在 Android 系统中,系统碎片化严重、各 ROM 之间的差异,甚至系统Bug,都可能会导致Crash的发生。在 Android 应用中发生的 Crash 有两种类型,Java 层的 Crash 和 Native 层 Crash。这两种Crash 的监控和获取堆栈信息有所不同。
Window Activity、Window、DecorView三者一一对应。 Window的分类 普通window,z轴范围1~99; 子window,z轴事情的起因是,在工作项目中,一开始只有我一个人研发,为了方便,我封装了一个网络访问层。但是随着团队规模的拓展,陆续加入了其他人,时间紧项目重,所以后续的伙伴没有时间来问我这个框架怎么使用,所以他们直接上手改了我的封装!但是后期架构要求加入oauth2.0机制,所以需要全局处理token的有效认证,并且自动刷新token。为了满足这一需求,我需要重新编写网络层,同时为了避免伙伴修改我的抽象,我想到了本文的主题——搭建个pub.dev私服吧!
关于我
/bin: bin 是 Binaries (二进制文件) 的缩写, 这个目录存放着最经常使用的命令。 /boot: 这里存放的是启动 Linux 时使用的一些核心文件,包括一些连接文件以
自定义ViewGroup与自定义View不同,一般不需要重写onDraw,而是需要重写onLayout。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
用途 读取.class文件的字节码并加载成内存形式的类对象。 边解释边执行 JVM并不是一次性加载全部的类,而是需要用到才会去加载。比如加载了类,
字节流 标准用法: 1 2 3 4 5 6 7 8 9 10 11 12 DataOutputStream out = new DataOutputStream(//负责数据类型 new BufferedOutputStream
JDK、JVM、Jre之间的关系 JVM 只负责把.class文件翻译成操作系统可识别的语句。 Jre 提供Java程序的运行环境 JDK 提供工具 JVM的三大区域
创建类 1 2 3 4 5 class StudentEntity with JsonConvert<StudentEntity> { @JSONField(name: "name") late String name; } 使用 1 2 3 4 5 6 7 8 9 10 11 //序列化 Map<String, dynamic> json = StudentEntity(name: "走两步试试").toJson(); //
打开命令面板 ctrl+shift+P 跳转设置页面 ctrl+,
流程 点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求; sys
.apk文件的组成 apk文件其实就是个压缩包,里面包含: classes.dex编译后的代码文件,安卓的可执行文件 resource.arsc 编译后的资源文件(raw)
.apk文件的组成 apk文件其实就是个压缩包,里面包含: classes.dex文件 resource 打包流程 aapt编译打包资源文件,生成R.java。 编译
ReentrantLock的使用 1 2 3 4 5 6 ReentrantLock lock = new ReentrantLock(); try { lock.lock(); } finally { lock.unlock(); } AQS原理概述 1 private volatile int state; 维护了一个int state作为状态机,CLH队
RV是什么 1 2 3 public class RecyclerView extends ViewGroup implements ScrollingView{ ... } 就是个ViewGroup,并且遵循了ScrollingView接口,所以支持滑动。 那么,既然是VG,那么我
SharedPreferences解读 SharedPreferences是我们平时常用的简单储存工具。优点就是用起来方便,而且线程安全,甚至
原因 短生命周期对象持有长生命周期对象的强引用,造成短生命周期对象在不需要使用时不能被回收。 静态变量导致 1 2 3 4 5 6 7 8 9 10 11 12 13 public class MainActivity extends AppCompatActivity {
中共中央 国务院印发海南自由贸易港建设总体方案 中共中央 国务院印发《海南自由贸易港建设总体方案》 新华社北京6月1日电 中共中央、国务院印发了《海南
setContentView 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 @Override public void setContentView(View v) { ensureSubDecor(); ViewGroup contentParent = mSubDecor.findViewById(android.R.id.content); contentParent.removeAllViews(); contentParent.addView(v); mAppCompatWindowCallback.getWrapped().onContentChanged(); } @Override public void setContentView(int resId) { ensureSubDecor(); ViewGroup contentParent = mSubDecor.findViewById(android.R.id.content); contentParent.removeAllViews(); LayoutInflater.from(mContext).inflate(resId, contentParent); mAppCompatWindowCallback.getWrapped().onContentChanged(); } @Override public void setContentView(View v, ViewGroup.LayoutParams lp) { ensureSubDecor(); ViewGroup contentParent =
三大流程 measure 用来测量View的宽高; layout 用来确定View在父容器中的放置位置; draw 负责绘制。 在ActivityThread中,当Activity创
位置参数 主要位置参数 View的位置主要由它的四个顶点(相对父容器)来决定: getLeft() getTop() getRight() getBottom() 用于移动的参数 x/y View左上角相对父容器的坐标; translationX/translationY View
并发三大特性 原子性 操作要么成功,要么失败,中途不可被中断。 可见性 共享变量的变更立即可见。 有序性 程序执行依照代码的先后顺序来执行。 JMM模型 J
状态 new 新建 Runnable 可运行 Blocaked 阻塞 Waiting 等待 Timed waiting 计时等待 Terminated 终止 核心方法 void start()启动 void run()调用内部Runnable的run()。 public static void sleep(long mil
阻塞队列 BlockingQueue 生产者&消费者模型 队列的意义: 生产者与消费者解耦 平衡生产与消费速度 可应用于消息中心 默认实现: 队列 界限 特点 ArrayBlockingQueue 有 一个由数组结构
用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 // 步骤1:创建HandlerThread实例对象 // 传入参数 = 线程名字,作用 = 标记该
使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 public class MainActivity extends
从Set方法入手 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } ThreadLocalMap getMap(Thread t) { return t.threadLocals; } 从这里可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 class Data implements Parcelable
Binder是什么 进程间通讯机制 系统驱动 Binder.java跨进程能力 为何要多进程 申请更多内存 安全性隔离 Binder的优势 机制 性能 特点 安全
初始化 1 2 3 Looper.prepare(); Handler mHandler = new Handler(Looper.myLooper()); Looper.loop(); Looper.prepare()源码: 1 2 3 4 5 6 private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); } Looper的
回顾 handler发送消息: 1 2 3 4 5 6 7 8 9 10 private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg, long uptimeMillis) { msg.target = this; msg.workSourceUid = ThreadLocalWorkSource.getUid(); if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis);//最后调用的是
Handler的原理 内存共享方案,并且通过加锁避免线程之间的相互干扰。 为何不用wait/notify 答案: 通过阅读main()函数,会发现主
构造方法 1 2 3 4 5 6 public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; } 构造方法中可以看到,handler持有Looper的MessageQueu
创建 我们都知道创建Message的时候有两种方式: 构造方法创建(不推荐)。 Message.obtain();(推荐). 为了防止OOM,我们一
类图 prepare 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public static void prepare() { prepare(true); } private static void prepare(boolean quitAllowed) { // 如果线程已经有了Looper就会报错 if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); }
记忆方式 Fragment的onAttach,onCreate,onCreateView,onViewCreated在附加到Activity时
GraphQL如何获取数据 每个field都有一个graphql.schema.DataFetcher与之对应。 一些File会使用特定的dat
引入依赖 1 2 3 4 5 6 7 dependencies { implementation 'com.graphql-java:graphql-java:14.1' // NEW implementation 'com.graphql-java:graphql-java-spring-boot-starter-webmvc:1.0' // NEW implementation 'com.google.guava:guava:26.0-jre' // NEW implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' } 定义Schema 在src/main/resources中创建schema.gra
Queries 如果想要在schema里跑个查询,需要用对应的参数创建一个新的GraphQL object,然后执行execute()。该方法会返回一个Ex
引入依赖 版本列表 Gradle 1 2 3 4 5 6 7 repositories { mavenCentral() } dependencies { compile 'com.graphql-java:graphql-java:15.0' } Maven 1 2 3 4 5 <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-java</artifactId> <version>15.0</version> </dependency> Schema——大纲 创建一个Schema有两种方式: 推荐SDL(sp
版本差异 版本 特点 JDK1.7 数组+单向链 JDK1.8 数组+单向链+红黑树 jdk1.7中,数组是HashMap的主体,而链表是为了解决哈希冲突而存在的。当链表过长
由于我对GC的理解一直不好,总是记不住,所以本篇博客完全撸了一颗苹果的博客,十分感谢原作者! 什么是垃圾 Java进程运行后,如果某个类型(方法
java是引用传递还是值传递? 结论,Java就是值传递,只不过在传递引用类型的时候,会把对象的引用地址当作值来传递。 首先声明一个引用类型: 1
趁着下载Keycloak的时候,记录一下自己对SpringCloud中的用户鉴权系统的认识。 OAuth2.0 四种授权模式 模式 refresh_token 用途 authorization_code true 允许用户通过第三方应
死锁 死锁是指多个的线程在执行过程中,由于竞争资源或者由于批次通信而造成的一种阻塞现象。若无外力作用,他们都将无法推进下去。 悲观锁与乐观锁 悲观
反编译指令 1 javap -v XXX.class 监视器对象Monitor 原理 当synchronized加载代码块上,JVM会执行两条指令: 加锁:MonitorEnter 解
序列化:Object => String 反序列化:String => Object 核心原理 序列化是把对象转成字符串的过程,那么转换之后的字符串,就保存在文件中,所以Java