aapt命令获取apk详细信息(包名、版本号、版本名称、兼容api级别、启动Activity等)
第一步:找到aapt/AAPT2
找到sdk的根目录,然后找到build-tools文件夹,然后会看到一些build-tools的版本号,随便点开一个,就可以看到aapt了,如下图
aapt命令获取apk详细信息(包名、版本号、版本名称、兼容api级别、启动Activity等)
找到sdk的根目录,然后找到build-tools文件夹,然后会看到一些build-tools的版本号,随便点开一个,就可以看到aapt了,如下图
在线安装包下载地址:
独立安装包下载地址:
https://www.google.cn/chrome/?platform=win64&standalone=1
https://www.google.cn/chrome/?platform=win32&standalone=1
最新稳定版:
https://www.google.cn/intl/zh-CN/chrome/browser/?standalone=1&platform=win64
最新测试版:
https://www.google.cn/intl/zh-CN/chrome/browser/?standalone=1&extra=betachannel&platform=win64
最新开发版:
https://www.google.cn/intl/zh-CN/chrome/browser/?standalone=1&extra=devchannel&platform=win64
如果一个索引式文件的索引节点有10个直接块,1个一级间接块,1个二级间接块,1个三级间接块。假设每个数据块的大小是512个字节,一个索引指针占用4个字节。假设索引节点已经在内存中,那么访问该文件偏移地址在6000字节的数据需要再访问 ( ) 次磁盘。
A.1
B.2
C.3
D.4
B
[解析] 因为每个数据块的大小是512个字节,且前10块可以直接寻址,得出1~5120字节范围内可以直接寻址。对于间接索引块(索引块的大小也是512字节),一个索引指针占4字节,则一个索引块可以映射512/4=128个数据块,因为每个数据块的大小是512个字节,合计64KB。6000B-5120B=880B<64KB,所以只需一次映射就够了。因此,第1次,取索引指针,第2次读数据,一共需要两次访问。
在计算机科学里,我们会经常遇到一些关于计算多项式的问题,例如计算当 ${x}=2$ 时 $2x^4 - 3x^3 + 5x^2 + x - 7$ 的值。我们首先能够想到的方法就是求出每一项的值,然后把它们全部加起来。如果多项式的阶数不高,这种方法完全可行,而且更容易理解,可是如果把这个问题推广到 $n$ 阶,即计算 $a_nx^n + a_{n-1}x^{n-1} + ··· + a_2x^2 + a_1x + a_0 $ 的值,而且当 $n$ 很大时,这种算法就显得力不从心了。
这里以 $2x^4 - 3x^3 + 5x^2 + x - 7$ 为例计算当 $x = 4$ 时的值。下面是直接求解的代码:
|
1 2 3 4 5 6 7 8 9 |
def poly_bf(coeffi_list, x): degree = len(coeffi_list) - 1 # 最高次项 result = 0 for i in range(degree+1): coeffi = coeffi_list[i]; poly = 1 for j in range(degree-i-1, -1, -1): poly *= x # 计算 x^i result += coeffi * poly return result |
直接求解的方法的复杂度等于多少呢?我们知道,计算机在计算乘法的时候的时间开销要大于加减法的时间开销,所以这里的复杂度大致看做是执行乘法运算的次数。
$T(n)=\sum_{i=1}^{n}{i+1}=2+3+\cdots+n+1=\frac{n(n+3)}{2}\in\Theta(n^2) $
最后得到时间复杂度为 $Θ(n^2)$。
霍纳法则(Horner’s rule)可以将上面的多项式转化成下面的形式:
$p(x)=(\cdots(a_nx+a_{n-1})x+\cdots)x+a_0"$
假设还是计算当 $x = 4$ 时 $2x^4 - 3x^3 + 5x^2 + x - 7$ 的值,我们需要先将其转换为 $x(x(x(2x - 3) + 5) + 1) - 7$ 的形式,为了更好地呈现每一步的计算过程,我们可以构建出下面的表格:

实现霍纳法则的代码非常简单,只需要用一个循环即可。
|
1 2 3 4 5 6 |
def poly_horner(coeffi_list, x): degree = len(coeffi_list) - 1 # 最高次项 result = coeffi_list[0] for i in range(1, degree+1): result = result * x + coeffi_list[i] return result |
经过霍纳法则变换的多项式只需要执行 $n$ 次乘法运算便可以得到 $n$ 阶多项式的值,所以复杂度自然就为 $Θ(n)$ 。跟直接求解相比有了明显的提升,根本原因在于我们对问题做了一个变换,使其变得更容易求解。
自从 Google 的 Flutter 发布之后,Facebook 对 React-Native 的迭代开始快了起来,优化 React-Native 的性能表现,避免被 Flutter 比下去。最近一个比较大的动作是开源了一个 JavaScript 引擎,并将其包含到 React-Native 中。那么这款引擎它有什么不同,相比 V8、JSC 这些 JavaScript 引擎又有什么优势呢,现在本文来为你揭晓。
重要的事情提前说:Hermes 引擎是 Facebook 研发,在 React-Native Android 端用于替换 JavaScript Core 的 JavaScript 引擎。Hermes 引擎的优势是适合移动端的轻量级 JavaScript 引擎,使用 aot 编译,可以减少 Android 端内存使用,减小安装包大小,提升执行效率。
JavaScript 引擎是一个专门处理 JavaScript 脚本的虚拟机,一般会附带在网页浏览器之中。
V8(Google)、JavaScriptCore(Apple)、SpiderMonkey(Firefox)
Weex,Android:V8,iOS:JavaScriptCore
RN,Android:JavaScriptCore(Hermes、V8),iOS:JavaScriptCore(Apple 要求)
注:Hermes Engine在React-native 0.60.2 版本后支持
预编译字节码(引擎加载二进制代码效率高于运行JS脚本)
无 JIT 编译器(减小了引擎大小,优化内存占用,但直接运行 JS 脚本的性能差于 V8 和 JSC)
针对移动端的垃圾回收策略
第一阶段是混合开发的web容器时代
第二阶段是以RN和Weex为代表的泛web容器时代
第三阶段是以Flutter为代表的自绘引擎时代
MPM多进程处理模块
MPM分为三种模式:
1,prefork
进程模型,每个进程处理一个请求,模式:父进程——————>多个子进程——————>一个子进程处理一个请求
2,worker
线程模型,每个进程衍生出多个线程,每个线程处理一个请求,模式:父进程——————>多个子进程——————>每个子进程衍生多个线程------->一个线程处理一个请求任务
3,event
事件驱动模型,一个进程处理多个任务,模式:父进程————————>多个子进程-------->一个子进程处理多个请求
centos6 httpd-2.2 MPM设置
修改文件
/etc/sysconfig/httpd
|
1 2 3 |
HTTPD=/usr/sbin/httpd.worker HTTPD=/usr/sbin/httpd.event |
默认为prefork模式
配置后重启httpd server生效
centos7 httpd-2.4 MPM设置
修改文件 /etc/httpd/conf.modules.d/00-mpm.conf
|
1 2 3 4 5 |
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so LoadModule mpm_worker_module modules/mod_mpm_worker.so LoadModule mpm_event_module modules/mod_mpm_event.so |
模式参数配置详解
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<IfModule prefork.c> //如果加载了这个模块,就实现一下配置,一个条件化模块加载 StartServers 8 //服务在启动时默认启动几个子进程 MinSpareServers 5 //最小空闲进程数量 MaxSpareServers 20 //最大空闲进程数量 ServerLimit 256 //限制MaxClients MaxClients 256 //最大并发量,就是同时访问数量 MaxRequestsPerChild 4000 //每个子进程最多能处理的请求数量,处理够数量后就被kill然后重新启动 </IfModule> |
相比上一篇文章所讲的Instrumented Unit Tests,本文所讲的自动化测试Espresso最显著的特点就是,可以与UI相交互。
首先我们在Android Studio中新建一个项目,取名为EspressoTests。同时删除自动生成的一些文件,最终目录结构如下:
在使用 Espresso 进行单元测试的时候,我们需要等待被测试界面上某个元素显示出来,这个时候需要进行等待,等待的时间需要我们自行控制。
问题及原因:
我们在做UI相关的代码时有时候会碰到WindowLeak,也就是所谓的窗体泄露,泄露的原因是因为Android UI操作在主线程中操作,但是我们会需要在一些线程或者异步任务中操作UI界面元素的需求,那么这个时候可能会出现类似问题。我在做浮动窗口的时候碰到了这个问题,浮动窗口需要用到WindowManager, WindowManger又是一个Activity的一个变量,它依存于Activity,当横竖屏切换或者Activity销毁的时候这个变量会销毁。销毁的时候导致WindowManager通过AddView()方法添加的View没有依存,导致窗体泄露。那么问题来了,为什么这里会泄露了?
2.解决方法:我在onDestroy()里面调用了removeView方法,想要避免窗体泄露,但是这个方法并不管用,后来换成removeViewImmediate()就解决了这个问题,原因就是两个方法设计到线程同步问题,removeViewImmediate()是通知View立刻调用View.onDetachWindow(),这说明这个方法是通过一个监听或者观察者来实现的,因为线程的同步跟异步问题导致Activity销毁了,但View还没有被remove完,于是就产生了所谓的窗体泄露。说到这里,我想大家也能明白这两个方法的区别了。
android WindowManager中removeView(View v)与removeViewImmediate(View v)的区别