精华内容
下载资源
问答
  • 发现问题上周,我的测试同事告诉我,你的用户名怎么还允许中文啊?当时我心里就想,你们测试肯定又搞错接口了,我用的是正则\w过滤了参数,怎么可能出错,除非...唯一的区别是现在用的是Python3。上网搜了一圈,发现...

    发现问题

    上周,我的测试同事告诉我,你的用户名怎么还允许中文啊?当时我心里就想,你们测试肯定又搞错接口了,我用的是正则\w过滤了参数,怎么可能出错,除非Python正则系统出错了,那是不可能的。本着严谨的作风,我自己先测试一下,没问题看我怎么怼回去。可是当我测试,我就懵逼了,中文真TM都验证通过,不对啊,我以前也是这么过滤参数的,测试没问题啊?唯一的区别是现在用的是Python3。

    上网搜了一圈,发现没有一篇文章讲述Python2和Python3的正则在处理字符串是的区别,都是一视同仁,知道我去翻了一遍官方文档,才明白怎么回事。

    问题复现

    我们都知道,Python有个正则规则\w,几乎所有的网上博客文章都告诉你,这个规则匹配字母数字及下划线,但实际并不是这样:

    有Python2代码如下:

    ~|⇒ python

    Python 2.7.10 (default, Aug 17 2018, 19:45:58)

    [GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.0.42)] on darwin

    Type "help", "copyright", "credits" or "license" for more information.

    >>> import re

    >>> aa = '捕蛇者说'

    >>> re.match('\w{1,20}', aa)

    >>> bb = 'abc123ADB'

    >>> re.match('\w{1,20}', bb)

    我们可以看到,在python2中,\w是无法匹配中文的。那么,同样的代码在Python3中运行结果是什么样子的了?

    ~|⇒ python3

    Python 3.7.1 (default, Nov 28 2018, 11:55:14)

    [Clang 9.0.0 (clang-900.0.39.2)] on darwin

    Type "help", "copyright", "credits" or "license" for more information.

    >>> import re

    >>> aa = '捕蛇者说'

    >>> re.match('\w{1,20}', aa)

    >>> bb = 'abc123ADB'

    >>> re.match('\w{1,20}', bb)

    但在Python3中\w是可以匹配中文的,这是怎么回事了?要回答这个问题,我们要回到Python官方文档中来寻找答案。

    解决问题

    当我们仔细阅读Python的官方文档时,就会发现,对于同样的正则规则\w,Python2和Python3区别好大,我们先来看看Python2:

    When the LOCALE and UNICODE flags are not specified, matches any alphanumeric character and the underscore; this is equivalent to the set [a-zA-Z0-9_]. With LOCALE, it will match the set [0-9_] plus whatever characters are defined as alphanumeric for the current locale. If UNICODE is set, this will match the characters [0-9_] plus whatever is classified as alphanumeric in the Unicode character properties database.

    翻译一下:当没有设置LOCALE(re.L)和UNICODE(re.U)标志,匹配数字字母和下划线,如果设置了LOCALE(re.L)则匹配数字下划线和LOCALE文字。如果设置了UNICODE(re.U)标志,匹配数字下划线和Unicode字符集里的字符。

    那么Python3了:

    对于 Unicode (str) 样式:

    匹配Unicode词语的字符,包含了可以构成词语的绝大部分字符,也包括数字和下划线。如果设置了 ASCII 标志,就只匹配 [a-zA-Z0-9_] 。

    对于8位(bytes)样式:

    匹配ASCII字符中的数字和字母和下划线,就是 [a-zA-Z0-9_] 。如果设置了 LOCALE 标记,就匹配当前语言区域的数字和字母和下划线。

    到此,我明白了,默认情况下,不设置任何标志,Python2 \w匹配ASCII字符集里的字符,包括数字字符和下划线,Python3 \w匹配数字下划线和Unicode字符集。所以,为了迁移方便,如果你想匹配ASCII字符集里的字符,指定标志为re.A,如果你想匹配Unicode字符集里的字符,指定标志为re.U。

    总结

    到此,我的问题是彻底解决了,但也有两个教训:

    看网上的教程要多注意,特别是教程里的环境和自己环境的区别

    多看官方文档

    关于Python2和Python3,还有很多区别,这里就不一一列举了,欢迎大家留言讨论。

    展开全文
  • IO优化是怎么,使用 SharedPreferences为什么这么卡,mmkv原理是什么 心理分析:IO优化一直是每个企业必选项,每次闻到都很头疼,面试官想问有没有相关经验,如果有话,只有两种答案sqlitedatabse, ...

    IO优化是怎么做的,使用 SharedPreferences为什么这么卡,mmkv原理是什么

    心理分析:IO优化一直是每个企业必选项,每次闻到都很头疼,面试官想问有没有相关经验,如果有的话,只有两种答案sqlitedatabse, SharedPreferences。 这两个很常见,肯定不是面试官想问的。 那只有一种答案了,对,就是最新的mmkv框架

    接下来,会问你他的原理 你是怎么看。 它的优缺点。为什么比其他的好。从原理层来解析。这才是最难的。

    这篇文章 从原理层说明他们的区别

    1.1 MMKV的概念

    mkkv是基于 mmap 的高性能通用 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。

    1. MMKV 是基于 mmap 内存映射的移动端通用 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。
    2. 从 2015 年中至今,在Android 微信上使用已有近 3 年,其性能和稳定性经过了时间的验证。在腾讯内部开源半年之后,得到公司内部团队的广泛应用和一致好评。
    3. 通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,
      由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。
    4. XML、JSON 更注重数据结构化,关注人类可读性和语义表达能力。 ProtoBuf 更注重数据序列化,关注效率、空间、速度,人类可读性差,语义表达能力不足(为保证极致的效率,会舍弃一部分元信息)

    1.2 特点

    • 高性能 实时写入
    • 稳定 防crash
    • 多进程访问
      通过与 Android 开发同学的沟通,了解到系统自带的 SharedPreferences 对多进程的支持不好。
      现有基于 ContentProvider 封装的实现,虽然多进程是支持了,但是性能低下,经常导致 ANR。
      考虑到 mmap 共享内存本质上的多进程共享的,我们在这个基础上,深入挖掘了 Android 系统的能力,提供了可能是业界最高效的多进程数据共享组件。
    • 匿名内存
      在多进程共享的基础上,考虑到某些敏感数据(例如密码)需要进程间共享,但是不方便落地存储到文件上,直接用 mmap 不合适。
      我们了解到 Android 系统提供了 Ashmem 匿名共享内存的能力,发现它在进程退出后就会消失,不会落地到文件上,非常适合这个场景。
      我们很愉快地提供了 Ashmem MMKV 的功能。
    • 数据加密
      不像 iOS 提供了硬件层级的加密机制,在 Android 环境里,数据加密是非常必须的。
      MMKV 使用了 AES CFB-128 算法来加密/解密。我们选择 CFB 而不是常见的 CBC 算法,
      主要是因为 MMKV 使用 append-only 实现插入/更新操作,流式加密算法更加合适。
    • 数据有效性

    1.3性能对比

    我们将 MMKV 和 SharedPreferences、SQLite 进行对比, 重复读写操作 1k 次。相关测试代码在 Android/MMKV/mmkvdemo/。结果如下图表。

    单进程性能

    可见,MMKV 在写入性能上远远超越 SharedPreferences & SQLite,在读取性能上也有相近或超越的表现。

    可见,MMKV 无论是在写入性能还是在读取性能,都远远超越 MultiProcessSharedPreferences & SQLite & SQLite, MMKV 在 Android 多进程 key-value 存储组件上是不二之选。

    1.3 MMKV 原理

    • 内存准备 通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。

    • 数据组织 数据序列化方面我们选用 protobuf 协议,pb 在性能和空间占用上都有不错的表现。

    • 写入优化 考虑到主要使用场景是频繁地进行写入更新,我们需要有增量更新的能力。我们考虑将增量 kv 对象序列化后,append 到内存末尾。 这样同一个 key 会有新旧若干份数据,最新的数据在最后;那么只需在程序启动第一次打开 mmkv 时,不断用后读入的 value 替换之前的值,就可以保证数据是最新有效的。

    • 空间增长 使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增长得不可控。我们需要在性能和空间上做个折中。 以内存 pagesize 为单位申请空间,在空间用尽之前都是 append 模式;当 append 到文件末尾时,进行文件重整、key 排重,尝试序列化保存排重结果; 排重后空间还是不够用的话,将文件扩大一倍,直到空间足够。

    • 数据有效性 考虑到文件系统、操作系统都有一定的不稳定性,我们另外增加了 crc 校验,对无效数据进行甄别。

    更详细的设计原理参考 MMKV 原理

    1.4 快速上手

      dependencies {
          implementation 'com.tencent:mmkv:1.0.23'
          // replace "1.0.23" with any available version
      }
    

    MMKV的使用非常简单, 所有变更立马生效,无需调用 sync、apply。 在 App 启动时初始化 MMKV,设定 MMKV 的根目录 (默认/data/data/xxx.xxx/files/mmkv/) (sp存储在/data/data/xxx.xxx/shared_prefs/)

    支持从SP迁移数据importFromSharedPreferences

    MMKV 还额外实现了一遍 SharedPreferences、SharedPreferences.Editor 这两个 interface

      // 可以跟SP用法一样
      SharedPreferences.Editor editor = mmkv.edit();
      // 无需调用 commit()
      //editor.commit();
    

    MMKV 的使用非常简单,所有变更立马生效,无需调用 sync、apply。 在 App 启动时初始化 MMKV,设定 MMKV 的根目录(files/mmkv/),例如在 MainActivity 里:

      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
    
          String rootDir = MMKV.initialize(this);
          System.out.println("mmkv root: " + rootDir);
          //……
      }
    

    MMKV 提供一个全局的实例,可以直接使用:

      import com.tencent.mmkv.MMKV;
      //……
    
      MMKV kv = MMKV.defaultMMKV();
    
      kv.encode("bool", true);
      boolean bValue = kv.decodeBool("bool");
    
      kv.encode("int", Integer.MIN_VALUE);
      int iValue = kv.decodeInt("int");
    
      kv.encode("string", "Hello from mmkv");
      String str = kv.decodeString("string");
    

    使用完毕的几个方法

          public native void clearAll();
    
          // MMKV's size won't reduce after deleting key-values
          // call this method after lots of deleting f you care about disk usage
          // note that `clearAll` has the similar effect of `trim`
          public native void trim();
    
          // call this method if the instance is no longer needed in the near future
          // any subsequent call to the instance is undefined behavior
          public native void close();
    
          // call on memory warning
          // any subsequent call to the instance will load all key-values from file again
          public native void clearMemoryCache();
    
          // you don't need to call this, really, I mean it
          // unless you care about out of battery
          public void sync() {
              sync(true);
          }
    

    1.5 补充适用建议

    如果使用请务必做code19版本的适配,这个在github官网有说明

    依赖下面这个库,然后对19区分处理
    implementation ‘com.getkeepsafe.relinker:relinker:1.3.1’

      if (android.os.Build.VERSION.SDK_INT == 19) {
          MMKV.initialize(relativePath, new MMKV.LibLoader() {
              @Override
              public void loadLibrary(String libName) {
                  ReLinker.loadLibrary(context, libName);
              }
          });
      } else {
          MMKV.initialize(context);
      }
    
    

    1.6 限制

    可看到,一个键会存入多分实例,最后存入的就是最新的。
    MMKV 在大部分情况下都性能强劲,key/value 的数量和长度都没有限制。
    然而 MMKV 在内存里缓存了所有的 key-value,在总大小比较大的情况下(例如 100M+),App 可能会爆内存,触发重整回写时,写入速度也会变慢。
    支持大文件的 MMKV 正在开发中,有望在下一个大版本发布。

    1.7 多进程使用

    1.7.1锁 lock unlock tryLock

    注意如果一个进程lock住,另一个进程mmkvWithID获取MMKV时就阻塞住,直到持有进程释放。

              // get the lock immediately
            MMKV mmkv2 = MMKV.mmkvWithID(LOCK_PHASE_2, MMKV.MULTI_PROCESS_MODE);
            mmkv2.lock();
            Log.d("locked in child", LOCK_PHASE_2);
    
            Runnable waiter = new Runnable() {
                @Override
                public void run() {
                    //阻塞住 直到其他进程释放
                    MMKV mmkv1 = MMKV.mmkvWithID(LOCK_PHASE_1, MMKV.MULTI_PROCESS_MODE);
                    mmkv1.lock();
                    Log.d("locked in child", LOCK_PHASE_1);
                }
            };
    
    

    ​ 注意:如果其他进程有进行修改,不会立即触发onContentChangedByOuterProcess,
    checkLoadData如果变化,会clearMemoryState,重新loadFromFile。//数据量大时不要太频繁
    读取decodeXXX会阻塞住,先回调onContentChangedByOuterProcess,再返回值,保证值是最新的。

    1.7.2 mmkvWithAshmemID 匿名共享内存

    可以进行进程间通信,可设置pageSize
    // a memory only MMKV, cleared on program exit
    // size cannot change afterward (because ashmem won't allow it)

    1.7.3 测试结果

    write速度: mmkv > cryptKV >> sp
    read速度: sp > cryptKV > mmkv

    1.8 Binder MMAP(一次拷贝)

    ​ Linux的内存分用户空间跟内核空间,同时页表有也分两类,用户空间页表跟内核空间页表,每个进程有一个用户空间页表,但是系统只有一个内核空间页表。
    而Binder mmap的关键是:更新用户空间对应的页表的同时也同步映射内核页表,让两个页表都指向同一块地址,
    ​ 这样一来,数据只需要从A进程的用户空间,直接拷贝到B所对应的内核空间,而B多对应的内核空间在B进程的用户空间也有相应的映射,这样就无需从内核拷贝到用户空间了。

    copy_from_user() //将数据从用户空间拷贝到内核空间
    copy_to_user() //将数据从内核空间拷贝到用户空间

    1.8.1 Liunx进程隔离

    1.8.2 传统IPC

    1.8.3 Binder通信

    1.9 普通文件mmap原理

    普通文件的访问方式有两种

    1. ​ 第一种是通过read/write系统调访问,先在用户空间分配一段buffer,然后,进入内核,将内容从磁盘读 取到内核缓冲,最后,拷贝到用户进程空间,至少牵扯到两次数据拷贝;
      同时,多个进程同时访问一个文件,每个进程都有一个副本,存在资源浪费的问题。
    2. ​ 另一种是通过mmap来访问文件,mmap()将文件直接映射到用户空间,文件在mmap的时候,内存并未 真正分配,

    ​ 只有在第一次读取/写入的时候才会触发,这个时候,会引发缺页中断,在处理缺页中断的时候,完成内存也分配,同时也完成文件数据的拷贝。
    并且,修改用户空间对应的页表,完成到物理内存到用户空间的映射,这种方式只存在一次数据拷贝,效率更高。

    同时多进程间通过mmap共享文件数据的时候,仅需要一块物理内存就够了。

    ​ Android中使用mmap,可以通过RandomAccessFile与MappedByteBuffer来配合。
    通过randomAccessFile.getChannel().map获取到MappedByteBuffer。然后调用ByteBuffer的put方法添加数据。

      RandomAccessFile randomAccessFile = new RandomAccessFile("path","rw");
      MappedByteBuffer mappedByteBuffer= 
      randomAccessFile.getChannel().map(FileChannel.MapMode.READ_WRITE,0, 
      mappedByteBuffer.putChar('c');
      mappedByteBuffer.getC



    作者:字节走动_Android
    链接:https://www.jianshu.com/p/088cd1d90a20
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • 很多地方就是这么说的 它们的用途不一样。简单工厂模式创建型模式,...但是如果对于一个实际的应用场景来说,怎么才能分得清什么创造与行为的区别啊……看网上的例子也经常模糊不清,总感觉两者可以替代一样%……
  • 面试官: IO优化是怎么,使用 SharedPreferences为什么这么卡,mmkv原理是什么 心理分析:IO优化一直是每个企业必选项,每次闻到都很头疼,面试官想问有没有相关经验,如果有话,只有两种答案sqlitedatabse, ...

    在这里插入图片描述

    面试官: IO优化是怎么做的,使用 SharedPreferences为什么这么卡,mmkv原理是什么

    心理分析:IO优化一直是每个企业必选项,每次闻到都很头疼,面试官想问有没有相关经验,如果有的话,只有两种答案sqlitedatabse, SharedPreferences。 这两个很常见,肯定不是面试官想问的。 那只有一种答案了,对,就是最新的mmkv框架

    接下来,会问你他的原理 你是怎么看。 它的优缺点。为什么比其他的好。从原理层来解析。这才是最难的。

    这篇文章 从原理层说明他们的区别

    1.1 MMKV的概念

    mkkv是基于 mmap 的高性能通用 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。

    1. MMKV 是基于 mmap 内存映射的移动端通用 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。
    2. 从 2015 年中至今,在Android 微信上使用已有近 3 年,其性能和稳定性经过了时间的验证。在腾讯内部开源半年之后,得到公司内部团队的广泛应用和一致好评。
    3. 通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,
      由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。
    4. XML、JSON 更注重数据结构化,关注人类可读性和语义表达能力。 ProtoBuf 更注重数据序列化,关注效率、空间、速度,人类可读性差,语义表达能力不足(为保证极致的效率,会舍弃一部分元信息)

    1.2 特点

    • 高性能 实时写入
    • 稳定 防crash
    • 多进程访问
      通过与 Android 开发同学的沟通,了解到系统自带的 SharedPreferences 对多进程的支持不好。
      现有基于 ContentProvider 封装的实现,虽然多进程是支持了,但是性能低下,经常导致 ANR。
      考虑到 mmap 共享内存本质上的多进程共享的,我们在这个基础上,深入挖掘了 Android 系统的能力,提供了可能是业界最高效的多进程数据共享组件。
    • 匿名内存
      在多进程共享的基础上,考虑到某些敏感数据(例如密码)需要进程间共享,但是不方便落地存储到文件上,直接用 mmap 不合适。
      我们了解到 Android 系统提供了 Ashmem 匿名共享内存的能力,发现它在进程退出后就会消失,不会落地到文件上,非常适合这个场景。
      我们很愉快地提供了 Ashmem MMKV 的功能。
    • 数据加密
      不像 iOS 提供了硬件层级的加密机制,在 Android 环境里,数据加密是非常必须的。
      MMKV 使用了 AES CFB-128 算法来加密/解密。我们选择 CFB 而不是常见的 CBC 算法,
      主要是因为 MMKV 使用 append-only 实现插入/更新操作,流式加密算法更加合适。
    • 数据有效性

    1.3性能对比

    我们将 MMKV 和 SharedPreferences、SQLite 进行对比, 重复读写操作 1k 次。相关测试代码在 Android/MMKV/mmkvdemo/。结果如下图表。

    单进程性能

    在这里插入图片描述

    可见,MMKV 在写入性能上远远超越 SharedPreferences & SQLite,在读取性能上也有相近或超越的表现。
    在这里插入图片描述

    可见,MMKV 无论是在写入性能还是在读取性能,都远远超越 MultiProcessSharedPreferences & SQLite & SQLite, MMKV 在 Android 多进程 key-value 存储组件上是不二之选。

    1.3 MMKV 原理

    • 内存准备 通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。

    • 数据组织 数据序列化方面我们选用 protobuf 协议,pb 在性能和空间占用上都有不错的表现。

    • 写入优化 考虑到主要使用场景是频繁地进行写入更新,我们需要有增量更新的能力。我们考虑将增量 kv 对象序列化后,append 到内存末尾。 这样同一个 key 会有新旧若干份数据,最新的数据在最后;那么只需在程序启动第一次打开 mmkv 时,不断用后读入的 value 替换之前的值,就可以保证数据是最新有效的。

    • 空间增长 使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增长得不可控。我们需要在性能和空间上做个折中。 以内存 pagesize 为单位申请空间,在空间用尽之前都是 append 模式;当 append 到文件末尾时,进行文件重整、key 排重,尝试序列化保存排重结果; 排重后空间还是不够用的话,将文件扩大一倍,直到空间足够。

    • 数据有效性 考虑到文件系统、操作系统都有一定的不稳定性,我们另外增加了 crc 校验,对无效数据进行甄别。

    更详细的设计原理参考 MMKV 原理

    1.4 快速上手

      dependencies {
          implementation 'com.tencent:mmkv:1.0.23'
          // replace "1.0.23" with any available version
      }
    

    MMKV的使用非常简单, 所有变更立马生效,无需调用 sync、apply。 在 App 启动时初始化 MMKV,设定 MMKV 的根目录 (默认/data/data/xxx.xxx/files/mmkv/) (sp存储在/data/data/xxx.xxx/shared_prefs/)

    支持从SP迁移数据importFromSharedPreferences

    MMKV 还额外实现了一遍 SharedPreferences、SharedPreferences.Editor 这两个 interface

      // 可以跟SP用法一样
      SharedPreferences.Editor editor = mmkv.edit();
      // 无需调用 commit()
      //editor.commit();
    

    MMKV 的使用非常简单,所有变更立马生效,无需调用 sync、apply。 在 App 启动时初始化 MMKV,设定 MMKV 的根目录(files/mmkv/),例如在 MainActivity 里:

      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
    
          String rootDir = MMKV.initialize(this);
          System.out.println("mmkv root: " + rootDir);
          //……
      }
    

    MMKV 提供一个全局的实例,可以直接使用:

      import com.tencent.mmkv.MMKV;
      //……
    
      MMKV kv = MMKV.defaultMMKV();
    
      kv.encode("bool", true);
      boolean bValue = kv.decodeBool("bool");
    
      kv.encode("int", Integer.MIN_VALUE);
      int iValue = kv.decodeInt("int");
    
      kv.encode("string", "Hello from mmkv");
      String str = kv.decodeString("string");
    

    使用完毕的几个方法

          public native void clearAll();
    
          // MMKV's size won't reduce after deleting key-values
          // call this method after lots of deleting f you care about disk usage
          // note that `clearAll` has the similar effect of `trim`
          public native void trim();
    
          // call this method if the instance is no longer needed in the near future
          // any subsequent call to the instance is undefined behavior
          public native void close();
    
          // call on memory warning
          // any subsequent call to the instance will load all key-values from file again
          public native void clearMemoryCache();
    
          // you don't need to call this, really, I mean it
          // unless you care about out of battery
          public void sync() {
              sync(true);
          }
    

    1.5 补充适用建议

    如果使用请务必做code19版本的适配,这个在github官网有说明

    依赖下面这个库,然后对19区分处理
    implementation ‘com.getkeepsafe.relinker:relinker:1.3.1’

      if (android.os.Build.VERSION.SDK_INT == 19) {
          MMKV.initialize(relativePath, new MMKV.LibLoader() {
              @Override
              public void loadLibrary(String libName) {
                  ReLinker.loadLibrary(context, libName);
              }
          });
      } else {
          MMKV.initialize(context);
      }
    
    

    1.6 限制

    可看到,一个键会存入多分实例,最后存入的就是最新的。
    MMKV 在大部分情况下都性能强劲,key/value 的数量和长度都没有限制。
    然而 MMKV 在内存里缓存了所有的 key-value,在总大小比较大的情况下(例如 100M+),App 可能会爆内存,触发重整回写时,写入速度也会变慢。
    支持大文件的 MMKV 正在开发中,有望在下一个大版本发布。

    1.7 多进程使用

    1.7.1锁 lock unlock tryLock

    注意如果一个进程lock住,另一个进程mmkvWithID获取MMKV时就阻塞住,直到持有进程释放。

              // get the lock immediately
            MMKV mmkv2 = MMKV.mmkvWithID(LOCK_PHASE_2, MMKV.MULTI_PROCESS_MODE);
            mmkv2.lock();
            Log.d("locked in child", LOCK_PHASE_2);
    
            Runnable waiter = new Runnable() {
                @Override
                public void run() {
                    //阻塞住 直到其他进程释放
                    MMKV mmkv1 = MMKV.mmkvWithID(LOCK_PHASE_1, MMKV.MULTI_PROCESS_MODE);
                    mmkv1.lock();
                    Log.d("locked in child", LOCK_PHASE_1);
                }
            };
    
    

    ​ 注意:如果其他进程有进行修改,不会立即触发onContentChangedByOuterProcess,
    checkLoadData如果变化,会clearMemoryState,重新loadFromFile。//数据量大时不要太频繁
    读取decodeXXX会阻塞住,先回调onContentChangedByOuterProcess,再返回值,保证值是最新的。

    1.7.2 mmkvWithAshmemID 匿名共享内存

    可以进行进程间通信,可设置pageSize
    // a memory only MMKV, cleared on program exit
    // size cannot change afterward (because ashmem won’t allow it)

    1.7.3 测试结果

    write速度: mmkv > cryptKV >> sp
    read速度: sp > cryptKV > mmkv

    1.8 Binder MMAP(一次拷贝)

    ​ Linux的内存分用户空间跟内核空间,同时页表有也分两类,用户空间页表跟内核空间页表,每个进程有一个用户空间页表,但是系统只有一个内核空间页表。
    而Binder mmap的关键是:更新用户空间对应的页表的同时也同步映射内核页表,让两个页表都指向同一块地址,
    ​ 这样一来,数据只需要从A进程的用户空间,直接拷贝到B所对应的内核空间,而B多对应的内核空间在B进程的用户空间也有相应的映射,这样就无需从内核拷贝到用户空间了。

    copy_from_user() //将数据从用户空间拷贝到内核空间
    copy_to_user() //将数据从内核空间拷贝到用户空间

    1.8.1 Liunx进程隔离

    在这里插入图片描述

    1.8.2 传统IPC
    在这里插入图片描述

    1.8.3 Binder通信

    在这里插入图片描述

    1.9 普通文件mmap原理

    普通文件的访问方式有两种

    1. ​ 第一种是通过read/write系统调访问,先在用户空间分配一段buffer,然后,进入内核,将内容从磁盘读 取到内核缓冲,最后,拷贝到用户进程空间,至少牵扯到两次数据拷贝;
      同时,多个进程同时访问一个文件,每个进程都有一个副本,存在资源浪费的问题。
    2. ​ 另一种是通过mmap来访问文件,mmap()将文件直接映射到用户空间,文件在mmap的时候,内存并未 真正分配,

    ​ 只有在第一次读取/写入的时候才会触发,这个时候,会引发缺页中断,在处理缺页中断的时候,完成内存也分配,同时也完成文件数据的拷贝。
    并且,修改用户空间对应的页表,完成到物理内存到用户空间的映射,这种方式只存在一次数据拷贝,效率更高。

    同时多进程间通过mmap共享文件数据的时候,仅需要一块物理内存就够了。

    ​ Android中使用mmap,可以通过RandomAccessFile与MappedByteBuffer来配合。
    通过randomAccessFile.getChannel().map获取到MappedByteBuffer。然后调用ByteBuffer的put方法添加数据。

      RandomAccessFile randomAccessFile = new RandomAccessFile("path","rw");
      MappedByteBuffer mappedByteBuffer= 
      randomAccessFile.getChannel().map(FileChannel.MapMode.READ_WRITE,0, 
      mappedByteBuffer.putChar('c');
      mappedByteBuffer.getChar();
    

    每日分享大厂Android面经真题,喜欢的话点个关注吧~

    文末

    听说点赞关注的小伙伴都面试成功了?如果本篇博客对你有帮助,请支持下小编哦~

    Android高级面试精选题、架构师进阶实战文档传送门:我的GitHub

    整写作易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

    你的支持,我的动力;祝各位前程似锦,offer不断!!!

    在这里插入图片描述

    展开全文
  • 提问之前在网上搜集了一些资料了,先说下我自己理解。 FDM(频分多路复用)和OFDM(正交频分多路...我问题,OFDMA是怎么区分不同用户呢?跟FDMA有什么区别?是否OFDMA没有保护频带,而FDMA有保护频带?
  • CPU是什么?干什么? 听则就听得多,但是他是干嘛? CPU就是芯片吗?芯片就是CPU吗? 手机CPU、电脑CPU都是一回事吗?是不同种类吗? CPU种类这么多,有什么区别? 我知道这是很重要东西,可是他是怎么,...

    相关内容的科普放在最前面:
    笔记本CPU和台式机CPU区别:
    https://blog.csdn.net/azj2019/article/details/105981673
    CPU怎么选:(待更新)


    不知道,你是否曾今存在过以下疑问:
    CPU是什么?干什么的?
    听则就听得多,但是他是干嘛的?
    CPU就是芯片吗?芯片就是CPU吗?
    手机CPU、电脑CPU都是一回事吗?是不同种类吗?
    CPU种类这么多,有什么区别?
    我知道这是很重要的东西,可是他是怎么做的,为什么中国造不出?
    我们如何选择CPU?

    当你阅读完本文,你这些疑惑都能解决了。我将会以通俗易懂的语言给你回答这些问题。(受篇幅长度限制,本文只解答CPU的基本知识,专业知识只给出超链接)


    首先,什么是CPU呢?

    名词解释:中央处理器(CPU,Central Processing Unit)是一块超大规模的集成电路,是一台计算机的运算核心(Core)和控制核心(Control Unit)。它的功能主要是解释计算机指令以及处理计算机软件中的数据。
    CPU包括运算逻辑部件、寄存器部件和控制部件等,英文Logic components;运算逻辑部件,可以执行定点或浮点算术运算操作、移位操作以及逻辑操作,也可执行地址运算和转换。

    其实简单的说,他就是大脑,一颗电子大脑。

    通俗来讲,计算机的cpu就相当于人类的大脑,虽然不是主动指挥,但是通过遵循放置在计算机内存中的指令来实现指挥,其中包含指示它执行这些操作的代码。它也做算术运算,如加法,减法,乘法等,可以作出决定和选择。

    我们常说cpu是手机,电脑等电子设备最重要的元件之一,在现实中我们很多用户都喜欢以CPU为标准来判断性能。我们使用电脑/手机之所以有声音,有图像,能运行微信让你愉快聊天,能运行游戏让你一展身手,我们使用的扫地机器人能走遍你家为你服务,这都是通过一个叫做CPU的芯片来完成的。如果你想更深入更准确的去了解,可以通过百度百科超链接继续深入了解。

    目前我们使用的CPU是由运算器、控制器、寄存器、高速缓存及实现它们之间联系的数据、控制及状态的总线构成。作为整个系统的核心,CPU也是整个系统最高的执行单元,因此CPU已成为决定性能的核心部件。(听不懂?没关系,知道什么都归他管,他很重要就行)

    那么CPU就是我们平时说的芯片吗?

    不是,CPU是芯片的一种,但芯片不一定就是CPU。用数学的包含关系来说,芯片包含CPU,但不等于。

    CPU是超大规模的集成电路的一种,而集成电路都可以叫做芯片。如果说CPU是大脑,那么电子产品里面其他芯片就相当于小脑、脑干之类的,这个比喻不是很准确,反正就是负责内容不一样吧,有些芯片负责记忆,有些芯片负责升压降压(改变电源电压),而CPU只是相当于大脑思考的那部分,CPU不会记东西哦。(所以说电子产品里面有很多零配件,是很复杂的,一时半会儿我没办法全部讲清楚,等我慢慢更新完善吧。)

    概念上不是一回事,但是口语中我们常说的芯片通常在指代CPU(因为他太重要了),很多电子设备中,主要的芯片,被叫做主控芯片=主芯抄片,往往都是CPU,或者是和CPU概念很类似的SoC,MCU。

    也是因为这样,我们说华为能造芯片了指的也是麒麟芯片(CPU的一个“系列”,归属华为百分百控股的海思半导体公司)【注:华为能造其实与自产自销自足还远着,具体的我有时间会另外补充相关文章】
    我们常说的AMD,英特尔,其实是造芯片的厂家(和海思一样)i5/i7/r7什么的都是产CPU的这些公司的一个系列罢了。

    CPU种类那么多,怎么区分?

    首先遇见最多的问题是,电脑CPU的问题了,因为很多小伙伴都是买电脑,手机的时候才会遇见CPU这个词。

    笔记本CPU和台式机CPU区别(篇幅有限,请跳链接)https://blog.csdn.net/azj2019/article/details/105981673

    想知道CPU种类,首先要知道CPU有一种核心的东西,叫做架构,看完你就知道手机CPU和电脑CPU是不是一样,能不能通用了。

    【未完待续…】

    附上一些知识超链接(我认为都是讲的很好的)

    关于光刻机的视频链接:https://www.ixigua.com/i6840602212909974019/
    在此视频里你可以知道DUV、EUV、光刻机、为什么中国光刻机落后、光刻机技术难点在哪、为啥光刻机这么难搞? 为什么说光刻机是人类智慧的结晶? 中国又应该怎么办?

    【未完待续…】
    【未完待续…】
    【未完待续…】

    展开全文
  • ▼嘀嘀嘀——今天你们美妆·饭团。饭团每次看小红书上试色都疯狂心动,但很...所以今天这篇我们就来讲讲不同质地口红怎么涂更好看!你们要认真学习了哦!水光、漆光、镜面唇釉上嘴都会有一种水嘟嘟感觉...
  • 我都不知道自己这是怎么了?! 她和车模没法比,她不漂亮,但我觉得我真被感动了,我觉得她很真实,我感受到了一种劳动人民美。前几年北京车展火过一个什么最美清洁工,但我认为那炒作。我第一次被自己拍到...
  • 校招面试看重基础,全方位无死角考察各位基础知识点,并且一般考察XXX是什么?XXX怎么实现? 社招面试对于项目考察至少占到了一半,2面或者3面会针对项目做一个详细沟通与了解,包括整个项目业务架构,...
  • 这么多服务,怎么找? 服务挂了怎么办? 客户端如何访问这些服务? 客户端UI如何访问他?后台有N个服务,前台就需要记住管理N个服务,一个服务下线/更新/升级,前台就要重新部署,这明显不服务我们拆分理念,...
  • 你看,什么双座硬顶、双座敞篷、四座敞篷、三门、五门、六门、越野SUV等,每个种类名称对应一个独立MINI车型。如果仅以各个型号最新年款下所包含配置型号计算,加起来就有51个之多。真是够吓人。还有...
  • 前几天在帮同事小何笔记本电脑安装64位Windows 7时候,遇到一个从来没有碰到过问题,使用光盘安装时,提示:Windows...一下子蒙了,怎么跳出来这么多新词?看来我已经落伍了,于是引发了对UEFI学习和探究。...
  • 什么是UI设计?UI设计师和网页美工有什么区别? 有时候我们经常会把美工和UI设计师会混淆,觉得UI设计就是搞美工,用ps或者ai随便做做就可以了。...而明白区别的你该怎么提升自己技术呢? UI设计师:U...
  • String,Stringbuilder,Stringbuffer的区别? – 如果你答string维护的字符串常量,Stringbuilder,Stringbuffer适合频繁修改字符串的情况,且Stringbuffer线程安全。 这么回答也OK,但是再问你一句为什么?? 怕...
  • 前几天在帮同事小何笔记本电脑安装64位Windows 7时候,遇到一个从来没有碰到过问题,使用光盘安装时,提示:Windows无法...一下子蒙了,怎么跳出来这么多新词?看来我已经落伍了,于是引发了对UEFI学习和探究...
  • 有一个想法,就是将自己每天对技术感悟写下来,有时候我们弄通一个小技术,感觉太丢人了,这么东西怎么写。但是我就要写,因为我以后会用到,大家以后也会用到。 前言 每个java小白都会遇到阵痛,我写...
  • 你觉得两者的区别是,开源和闭源的区别吗?我觉得不是!在我看来,苹果的系统,某种意义上是开源。你可能不能理解?苹果明明是内核是闭源呢,怎么成了开源呢?我的理解是: 苹果给开发者一定的开发应用需要的部分...
  • 作者:祖大帅链接:juejin.im/post/5b679fbc5188251aad213110SpringBoot 故事从一个面试题开始Spring Boot、Spring MVC 和 Spring 有什么区别?先来个 SpringBoot 启动结构图分开描述各自特征Spring 框架就像...
  • 大家知道现在抖音短视频跟直播其实不分家,那么在讲这个视频怎么拍之前,我想先给各位讲一下,我们在做直播时候,到底应该如何去看待平时短视频拍摄,也就是说这个直播我每天投入这么多时间,那短视频我投多少...
  • 可能不少新手商家一听到这就头痛了,这么怎么选,也不知道到底有什么区别。为了帮助大家解决这些疑问,今天就着重来说说通用推广、专属推广、招商推广等三种的区别。一、多多进宝三种推广解析1、多多进宝通用计划...
  • ​ 在头条投放应用下载时候,有两种方式:一种直接投放下载链接,另一种用一个包含下载链接落地页来投放(以下简称落地页)。我用比较多的是直接投放下载链接。但后来认识一些优化师,他们坚定地认为“用...
  • 作者:祖大帅链接:juejin.im/post/5b679fbc5188251aad213110SpringBoot 故事从一个面试题开始Spring Boot、Spring MVC 和 Spring 有什么区别?先来个 SpringBoot 启动结构图分开描述各自特征Spring 框架就像...
  • 除了名字外,没什么区别啊??呵呵,这么想,你就错了!!1、压缩算法不同,rar格式能够提供更好压缩率,zip一种开放性压缩文件,算法不局限于一种,zip优势压缩速度快。2、rar格式私有并且已经申请了...
  • //C++中实例化Student类 Student student1; Student *student2=new Student();...显然在C++中new出来的是一个指向对象指针,而C#中new出来的是一个对象,为什么会出现这么不同,求大师们给出自己想法。
  • 中心化项目,你看重项目方利润,操盘手看重你本金,你怎么玩得过操盘手去中心化金融才市场方向,佛萨奇就是在革操盘手命!#forsage佛萨奇#万以社区成长哥目标:协助100个核心赚到1万个以太坊,1亿个波场!...
  • 首先,想问大家一个问题:你觉得家中最重要家具是什么?我认为是柜子,不说所有,但家里大部分杂物都得靠它。因此很多人在装修时就会陷入纠结:买成品柜还是做定制柜。​不要纠结,今天我们一起来看一看,他们之间...
  • “我真的什么都不想回答。首先,宇宙中很可能存在四个以上的空间维度,但宇宙中的动态制约因素使...”“结的答案有点令人信服,但却没有认识到几何中的数学变式和实际空间中物理运动之间的区别。例如,《平面国》...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 506
精华内容 202
关键字:

怎么这么的区别是什么