常见的Unicode编码
基础概念编码
编码是计算机最为常见的一部分,他所解决的是计算机”不认识”人所使用的自然语言的问题。
解决的思路也很简单,我们利用了计算机只认01 2进制的特点,既然计算机认识数字,那么我们就给所有的字符排一个号,类似于:
a : 97
A : 65
……
这样计算机就知道每个字符是什么了
Unicode编码
Unicode一般指统一码。 统一码(Unicode),也叫万国码、单一码,由统一码联盟开发,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。
其实在Unicode之前经历过很多的编码,这里就默认大噶都有所了解啦~
ASCII、GB2312、BIG5、GBK
啥没听说?看看再来学呗~
Unicode是一种编码集,也就是前面所说的字符到数值的映射。
Map<Integer,Charactor>
Map<Charactor,Integer>
Unicode码点
即Unicode编码所对应的数值
关于Unicode编码范围
目前Unicode最大的码点为0x10FFFF
编码实现
Unicode只是一套规范,这套规范里面给出了, ...
从CPU的视角看函数调用
从CPU的视角看函数调用
函数调用这我熟啊——不就是将栈帧压入栈内吗
我还知道递归层次过多会导致StackOverflow呢,看吧举一反三多聪明!
那你知道最底层是如何实现函数调用的吗?整个函数调用的过程?
前言
如果想了解操作系统函数调用过程,我们从编程语言的角度上是很难看出什么端倪的,因为这一过程已经被封装地太死了
唯一的突破口既是汇编代码
接下来将使用一些调试工具对一段C语言函数调用对底层函数调用过程进行分析。
环境
WSL:
WSL 版本: 1.2.5.0内核版本: 5.15.90.1WSLg 版本: 1.0.51MSRDC 版本: 1.2.3770Direct3D 版本: 1.608.2-61064218DXCore 版本: 10.0.25131.1002-220531-1700.rs-onecore-base2-hypWindows 版本: 10.0.22621.1702
OS Release
PRETTY_NAME=”Debian GNU/Linux 11 (bullseye)”NAME=”Debian GNU ...
Windows常见的编码问题
编码什么是编码”编码的诞生是带有一定场景和目的性的“
所谓场景既是需要用数字来表达信息的时候,很容易想到计算机,计算机只认01,恰好与之吻合。
目的就更好理解了,编码的出现就是为了解决01环境下无法表达信息的情况。
什么是编码问题直观的例子就是“鸡同鸭讲”
“鸡叫”是一种编码,“🦆叫”又是一种编码,他们属于不同的物种,语言不同即编码不兼容,就会出现双非都听不懂对方在说什么的情况。
(我不是什么小黑子,我只是单纯觉得这张图片好看)
放在实际情况来看,编码异常也就是,编码方和解码方采用不同的方式进行操作,导致双方得到的结果错误的情况,典型的如:
比如我编码采用GBK,解码采用UTF-8,就会出现如下问题:
Windows平台的编码问题就主流操作系统来看,Mac和Linux采用了UTF-8的编码,而Window却默认采用了GBK的编码。
而GBK对于UTF-8的中文解码是存在不兼容的。所以很容易出现乱码的情况。
如何解决Windows的编码问题一般发生编码异常的高发段(对于程序员)有如下:
源文件编码
编译器编码
终端编码
源文件编码容易理解,也就是代码的编码方式(代码本质就是纯文 ...
Java反射真的很耗时吗?
Reflection
自我学习Java起,带领我学习Java的学长都是会提醒我们——Java反射很耗时。
所以是真的很耗时吗?
不妨来测试一下
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172package com.example.reflect;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class Test { public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, Inter ...
记一次Java类型强转
背景
在刷一道Leetcode题
剑指 Offer 19. 正则表达式匹配
对照了答案,使用了DP对此题进行求解,由于没有完全抄题解的,所以有部分内容不完全一致。
但是就逻辑上和题解完全一致。可就是无法通过OJ
源代码
官方题解
1234567891011121314151617181920212223242526272829303132333435class Solution { public boolean isMatch(String s, String p) { int m = s.length(); int n = p.length(); boolean[][] dp = new boolean[m + 1][n + 1]; dp[0][0] = true; for(int i = 0;i <= m; i++) { for(int j = 1;j <= n; j++) { if(p.c ...
Glide Request构建
Glide Request
Glide在加载图片的第一步既是初始化Glide实例
接着就会获取RequestManager,然后初始化一个RequestBuilder构建一个Request,
本文会对于Glide的RequestBuilder实例化过程做解析
begin
Glide的创建是在Glide.with内部进行的,通过with以后就能得到一个RequestManager的实例化对象
1Glide.with(this)
RequestManager
关于RequestManager公开的api如下
request hook
addDefaultRequestListener
为所有由该RequestManager构建的Request添加监听。
applyDefaultRequestOptions
对Request进行默认配置
加载任务
as
进行RequestBuilder的实例化
1234public <ResourceType> RequestBuilder<ResourceType> as( @Non ...
Glide初始化分析
Glide Initial
Glide的初始化方法比较单一
无法无法使用
init
直接调用初始化,会初始化Glide内的static成员
get
初始化并获取Glide的实例
with
初始化Glide并依据传入的组件获取绑定响应生命周期的Manager对象,以便后续构建Request。
其中最为常用的既是with方法。with基本上包含了init和get方法的所有内容。
123public static RequestManager with(@NonNull Context context) { return getRetriever(context).get(context);}
123public static RequestManager with(@NonNull FragmentActivity activity) { return getRetriever(activity).get(activity);}
123public static RequestManager with(@Non ...
Glide核心原理概览
Glide主线流程
Glide是一个图片加载库
Glide通过压缩和缓存,解决了图片内存占用大的问题
Glide的过程大致分为5步
Glide初始化
生命周期绑定(Glide -> RequestManager)
请求构建(RequestManager -> RequestBuilder)
请求配置(RequestBuilder -> RequestBuilder)
发起请求资源获取,解码,转化,呈现(RequestBuilder -> Target)
Note:
前4步通常是在Main线程,主要是做好Request的配置
最后一步最为复杂也最为重要,完成资源获取和界面呈现。其中资源获取在后台线程,然后界面的呈现为main线程。
尺寸优化
Glide会自定依据ImageView的大小对图片进行缩放,以免图像的像素过高导致Bitmap无法分配或者OOM的问题
Bitmap缓存
Glide在加载过程中有使用缓存来加速图片的加载,其中Bitmap会被缓存到BitmapPool中
其中BitmapPool采用了LRU的淘汰策略,即淘汰最近最少使 ...
Glide基础使用
Glidestart up安装12345678910111213plugins { //...... id 'org.jetbrains.kotlin.kapt'}dependencies { // https://mvnrepository.com/artifact/com.github.bumptech.glide/glide implementation("com.github.bumptech.glide:glide:4.15.1") kapt("com.github.bumptech.glide:compiler:4.15.1") // ......}
基础使用
加载图片
123Glide.with(fragment) .load(myUrl) .into(imageView);
取消加载
1Glide.with(fragment).clear(imageView);
自定义request
Glide提供独立 ...
Okio原理解析
Okio原理
基于okio:3.3.0,JVM
Okio有如下优点
简单
指的是它的类关系满足迪米特原则,牵扯少,只有Sink/Source仅凭其可完成所有的IO
高效
发生io时的缓存做了池化处理避免了频繁的内存分配,Sink/Source是由Segment构成的,而Segment的获取会从SegmentPool获取
跨平台
使用了Kotlin Multiplatform插件实现类JVM/Js/Native多平台的兼容
Segment
通常的Segment是一个循环链表
对象创建123456789101112131415constructor() { // const val SIZE = 8192 this.data = ByteArray(SIZE) this.owner = true this.shared = false}constructor(data: ByteArray, pos: Int, limit: Int, shared: Boolean, owner: Boolean) ...