1.redmine是装在windows还是linux好

2.真正拯救安卓的,到底是安卓5.0还是安卓6.0

3.谷歌浏览器免安装教程

4.一文教你快速了解GoogleV8引擎

5.谷歌Android 13即将发布:可运行Win11,大部分功能可用

6.YUNOS与Android,两个系统究竟有什么区别

redmine是装在windows还是linux好

谷歌虚拟主机-谷歌电脑系统虚拟机

在我看来各有好处也各有弊端。双系统,好处在于,一台电脑有2个系统。而且互相不干扰。且对于电脑的配置要求要比虚拟机低。无论是widows还是linux,要想装到电脑上并能够正常的启动。到要有一些配置要求。它们的要求虽然不同,但是由于是不会同时启动。windows工作了,linux必然歇息。linux起来了,windows肯定关闭。所以,只要满足两套系统中要求较高的那个系统就好了。虚拟机就不是了。电脑启动后为了维持运作要占用一部分资源。再来个虚拟机软件,它也要占用资源。虚拟机里面还要有系统。那些系统还要占用资源。一块蛋糕就那么大,开机后,为了维持运作,分掉一块。虚拟机软件启动,再占用一块。虚拟机里面的系统启动还要分走一块。三分两分到最后所剩无几了。我就有这种经历。以前一台3G内存的Linux电脑装VirtualBox。VirtualBox里面装win7。我给win7多少内存?给多了,影响物理主机上linux系统的运行。给少了,win7启动慢的不是一星半点。win7从开机到它完全启动五六分钟。有时更长。有一次,虚拟机里面上网找个资源,用迅雷下载。点下IE的图标。鼠标变成沙漏在屏幕中间转来转去几分钟就是打不开。内存占用飙到80%以上。这不耽误事嘛。所以,虽然可以说要根据情况酌情考虑,但是问题是如何酌情?有时这个分寸确实不那么容易把握。再说安装。装系统有一个步骤是免不掉的,就是分区。在这个问题上,我的看法是虚拟机要比双系统容易。我用linux的时候,还没有GPT和UEFI。那时还是传统的MBR和BIOS。y有经验的人就知道了,BIOS基本输入输出系统和MBR主引导记录的时代,硬盘分区有所谓扩展分区和逻辑分区的概念。要装双系统,网上和书上往往会说"把电脑上最后一个逻辑分区缩小,或清除其中的数据"。这话对于电脑硬盘有些概念的人一看就懂。但是对于那些平时只会按鼠标的人来说,一看就蒙。我用linux这么些年,来知道也有10年,看到的,听到的因为分区错误把电脑搞糟的事情在不是一件两件。即使现在,用GPT了,硬盘不在用所谓扩展分区,逻辑分区了。但是,还是要把硬盘中最后一个区给缩小。怎么操作?这是个会者不难,难者不会的问题。网上说用某个软件操作,鼠标点这里,按哪里。这里改一改,那里调一调,然后确定,一切OK。实际呢?网上说的软件是英文版,用户下载的是中文版。这用户万一英文单词词汇量少。鼠标都不知道往哪按。或者,网上说的分区工具和用户下载安装的的确的同一种,但是版本不同。网上写的,可能是用以前的低版本的工具来操作。用户手里是新版。可能新版老版之间操作界面上有点不同。结果又晕了。再或者,网上说用工具A,可是用户却是怎么找也找不到工具A,只下载安装了工具B。虽然说,工具A,工具B都可以分区,但是,对于缺少经验的人来说,往往就不知道该怎么了。网上写的,书上教的和自己的不一样,或不完全一样。思路怎么转换?不会不懂。所以,我说,双系统的分区对于某些人是个问题。虚拟机就好一些。因为,对于大多数人来说,提到虚拟机往往是物理主机是windows,虚拟机里面装linux。windows装起来很简单,甚至于去商店买电脑的时候就已经预装了。就算没装,电脑城的人往往也会为顾客装上。分区的事情,不用用户动手。只是虚拟机里面的系统,怎么分区。即使分区不对了,也不会把电脑本身的重要分区例如C盘搞掉。导致不能开机。最后再说联网。这个问题上,我倾向虚拟机。在网络上经常有人问:我的虚拟机不能上网,怎么?虚拟机连不上网络,那真实的物理主机能不能上网?如果能,就先用真机联网,打开百度,要是谷歌也能用,那更好。有问题,百度一下。要是谷歌也能用,就听完度娘的再听听谷哥这么说。要是双系统,麻烦了。linux不能上网,重启系统,换到windows下,上网找百度找谷哥。费了半天劲,找到点答案。再重启,进到linux。问题解决的好说,万一没解决,又遇到新状况,网上说的和自己的情况不太一致。又不会了,没辙,再重启换windows,上百度谷歌吧。万一碰上个网络知识几乎是零,有问题全靠百度卫士,腾讯管家。360助手的人,那有得折腾的。所以,我觉得,双系统和虚拟机各有千秋。具体怎么选要看用户自己的想法了。但是别指望这哪种法能绝对百分百的简单好用。

真正拯救安卓的,到底是安卓5.0还是安卓6.0

进入安卓5.0时代,谷歌开始试图改善安卓系统跑虚拟机、执行效率低下的底层设计,于是开始有了Art模式,安卓的流畅度从此起飞…就连优化比较到位的千元机都能够流畅运行。在一定程度上来说,安卓5.0拯救了安卓。

进入安卓6.0时代,越来越多,铺天盖地关于安卓6.0用户体验完胜ios9.2的新闻曝出…安卓6.0似乎比安卓5.0更优秀、更强大了…

谷歌浏览器免安装教程

谷歌浏览器是一款备受欢迎的网络浏览器,但并非每个人都方便或需要安装。如果您想使用谷歌浏览器,但又不想进行安装,可以尝试以下方法:

1.谷歌浏览器在线版:直接在浏览器中访问谷歌浏览器的在线版官方网页即可开始使用。

2.绿色便携版:可直接在USB驱动器上运行,无需安装。在谷歌浏览器的官方网站上下载绿色便携版,并将其解压到USB驱动器中,然后直接运行可执行文件即可。

3.使用虚拟机:在虚拟机中安装谷歌浏览器,并在需要时运行该虚拟机,这样可以在不影响主机系统的情况下使用谷歌浏览器。

4.使用云服务:一些云服务提供商(如AWS、Azure等)提供了预先安装好谷歌浏览器的虚拟机镜像。创建一个虚拟机实例,并通过远程桌面连接到该实例,在其中使用谷歌浏览器。

这些方法可以帮助您在不进行安装的情况下使用谷歌浏览器。需要注意的是,这些方法可能不如直接安装谷歌浏览器来得方便和稳定。

一文教你快速了解GoogleV8引擎

探析它之前,我们先抛出以下几个疑问:

为什么需要V8引擎呢?

V8引擎到底是个啥?

它可以做些什么呢?

了解它能有什么收获呢?

接下来就针对以上几个问题进行详细描述。

由来

我们都知道,JS是一种解释型语言,支持动态类型(明显不同于Java等这类静态语言就是在命名一个变量时不需要声明变量的类型)、弱类型、基于原型的语言,内置支持类型。而一般JS都是在前端执行(直接影响界面),需要能够快速响应用户,那么就要求语言本身可以被快速地解析和执行,JS引擎就为此而问世。

这里提到了解释型语言和静态语言(编译型语言),先简单介绍一下二者:

解释型语言(JS)

每次运行时需要解释器按句依次解释源代码执行,将它们翻译成机器认识的机器代码再执行

编译型语言(Java)

运行时可经过编译器翻译成可执行文件,再由机器运行该可执行文件即可

从上面的描述中可以看到JS运行时每次都要根据源文件进行解释然后执行,而编译型的只需要编译一次,下次可直接运行其可执行文件,但是这样就会导致跨平台的兼容性很差,因此各有优劣。

而众多JS引擎(V8、JavaScriptCore、SpiderMonkey、Chakra等)中V8是最为出色的,加上它也是应用于当前最流行的谷歌浏览器,所以我们非常有必要去认识和了解一下,这样对于开发者也就更清楚JS在浏览器中到底是如何运行的了。

认识定义

使用C++开发

谷歌开源

编译成原生机器码(支持IA-32,x86-64,ARM,orMIPSCPUs)

使用了如内联缓存(inlinecaching)等方法来提高性能

运行速度快,可媲美二进制程序

支持众多操作系统,如windows、linux、android等

支持其他硬件架构,如IA32,X64,ARM等

具有很好的可移植和跨平台特性

运行

先来一张官方流程图:

准备

JS文件加载(不归V8管):可能来自于网络请求、本地的cache或者是也可以是来自serviceworker,这是V8运行的前提(有源文件才有要解释执行的)。3种加载方式&V8的优化:

Coldload:首次加载脚本文件时,没有任何数据缓存

Warmload:V8分析到如果使用了相同的脚本文件,会将编译后的代码与脚本文件一起缓存到磁盘缓存中

Hotload:当第三次加载相同的脚本文件时,V8可以从磁盘缓存中载入脚本,并且还能拿到上次加载时编译后的代码,这样可以避免完全从头开始解析和编译脚本

而在V86.6版本的时候进一步改进代码缓存策略,简单讲就是从缓存代码依赖编译过程的模式,改变成两个过程解耦,并增加了可缓存的代码量,从而提升了解析和编译的时间,大大提升了性能,具体细节见V86.6进一步改进缓存性能。

分析

此过程是将上面环节得到的JS代码转换为AST(抽象语法树)。

词法分析

从左往右逐个字符地扫描源代码,通过分析,产生一个不同的标记,这里的标记称为token,代表着源代码的最小单位,通俗讲就是将一段代码拆分成最小的不可再拆分的单元,这个过程称为词法标记,该过程的产物供下面的语法分析环节使用。

这里罗列一下词法分析器常用的token标记种类:

常数(整数、小数、字符、字符串等)

操作符(算术操作符、比较操作符、逻辑操作符)

分隔符(逗号、分号、括号等)

保留字

标识符(变量名、函数名、类名等)

TOKEN-TYPETOKEN-VALUE\-----------------------------------------------\T_IFif\T_WHILEwhile\T_ASSIGN=\T_GREATTHAN>\T_GREATEQUAL>=\T_IDENTIFIERname/numTickets/...\T_INTEGERCONSTANT100/1/12/....\T_STRINGCONSTANT"Thisisastring"/"hello"/...复制代码

上面提到会逐个从左至右扫描代码然后分析,那么很明显就会想到两种方案,扫描完再分析(非流式处理)和边扫描边分析(流式处理),简单画一下他们的时序图就能发现流式处理效率要高得多,同时分析完也会释放分析过程中占用的内存,也能大大提高内存使用效率,可见该优化的细节处理。

语法分析

语法分析是指根据某种给定的形式文法对由单词序列构成的输入文本(例如上个阶段的词法分析产物-tokensstream),进行分析并确定其语法结构的过程,最后产出其AST(抽象语法树)。

V8会将语法分析的过程分为两个阶段来执行:

Pre-parser

跳过还未使用的代码

不会生成对应的AST,会产生不带有变量的引用和声明的scopes信息

解析速度会是Full-parser的2倍

根据JS的语法规则仅抛出一些特定的错误信息

Full-parser

解析那些使用的代码

生成对应的AST

产生具体的scopes信息,带有变量引用和声明等信息

抛出所有的JS语法错误

为什么要做两次解析?

如果仅有一次,那只能是Full-parser,但这样的话,大量未使用的代码会消耗非常多的解析时间,结合实例来看下:通过Coverage录制的方式可以分析页面哪些代码没有用到,如下图可以看到最高有75%的没有被执行。

但是预解析并不是万能的,得失是并存的,很明显的一个场景:该文件中的代码全都执行了,那其实就是没必要的,当然这种情况其实还是占比远不如上面的例子,所以这里其实也是一种权衡,需要照顾大多数来达到综合性能的提升。

下面给出一个示例:

functionadd(x,y){if(typeofx==="number"){returnx+y;}else{returnx+'tadm';}}复制代码

复制上面的代码到web1和web2可以很直观的看到他们的tokens和AST结构(也可自行写一些代码体验)。

tokens

[{"type":"Keyword","value":"function"},{"type":"Identifier","value":"add"},{"type":"Punctuator","value":"("},{"type":"Identifier","value":"x"},{"type":"Punctuator","value":","},{"type":"Identifier","value":"y"},{"type":"Punctuator","value":")"},{"type":"Punctuator","value":"{"},{"type":"Keyword","value":"if"},{"type":"Punctuator","value":"("},{"type":"Keyword","value":"typeof"},{"type":"Identifier","value":"x"},{"type":"Punctuator","value":"==="},{"type":"String","value":""number""},{"type":"Punctuator","value":")"},{"type":"Punctuator","value":"{"},{"type":"Keyword","value":"return"},{"type":"Identifier","value":"x"},{"type":"Punctuator","value":"+"},{"type":"Identifier","value":"y"},{"type":"Punctuator","value":";"},{"type":"Punctuator","value":"}"},{"type":"Keyword","value":"else"},{"type":"Punctuator","value":"{"},{"type":"Keyword","value":"return"},{"type":"Identifier","value":"x"},{"type":"Punctuator","value":"+"},{"type":"String","value":"'tadm'"},{"type":"Punctuator","value":";"},{"type":"Punctuator","value":"}"},{"type":"Punctuator","value":"}"}]复制代码

AST

{"type":"Program","body":[{"type":"FunctionDeclaration","id":{"type":"Identifier","name":"add"},"params":[{"type":"Identifier","name":"x"},{"type":"Identifier","name":"y"}],"body":{"type":"BlockStatement","body":[{"type":"IfStatement","test":{"type":"BinaryExpression","operator":"===","left":{"type":"UnaryExpression","operator":"typeof","argument":{"type":"Identifier","name":"x"},"prefix":true},"right":{"type":"Literal","value":"number","raw":""number""}},"consequent":{"type":"BlockStatement","body":[{"type":"ReturnStatement","argument":{"type":"BinaryExpression","operator":"+","left":{"type":"Identifier","name":"x"},"right":{"type":"Identifier","name":"y"}}}]},"alternate":{"type":"BlockStatement","body":[{"type":"ReturnStatement","argument":{"type":"BinaryExpression","operator":"+","left":{"type":"Identifier","name":"x"},"right":{"type":"Literal","value":"tadm","raw":"'tadm'"}}}]}}]},"generator":false,"expression":false,"async":false}],"sourceType":"script"}复制代码解释

该阶段就是将上面产生的AST转换成字节码。

这里增加字节码(中间产物)的好处是,并不是将AST直接翻译成机器码,因为对应的cpu系统会不一致,翻译成机器码时要结合每种cpu底层的指令集,这样实现起来代码复杂度会非常高;还有个就是内存占用的问题,因为机器码会存储在内存中,而退出进程后又会存储在磁盘上,加上转换后的机器码多出来很多信息,会比源文件大很多,导致了严重的内存占用问题。

V8在执行字节码的过程中,使用到了通用寄存器和累加寄存器,函数参数和局部变量保存在通用寄存器里面,累加器中保存中间计算结果,在执行指令的过程中,如果直接由cpu从内存中读取数据的话,比较影响程序执行的性能,使用寄存器存储中间数据的设计,可以大大提升cpu执行的速度。

编译

这个过程主要是V8的TurboFan编译器将字节码翻译成机器码的过程。

字节码配合解释器和编译器这一技术设计,可以称为JIT(即时编译技术),Java虚拟机也是类似的技术,解释器在解释执行字节码时,会收集代码信息,标记一些热点代码(就是一段代码被重复执行多次),TurboFan会将热点代码直接编译成机器码,缓存起来,下次调用直接运行对应的二进制的机器码,加快执行速度。

在TurboFan将字节码编译成机器码的过程中,还进行了简化处理:常量合并、强制折减、代数重新组合。

比如:3+4-->7,x+1+2-->x+3......

执行

到这里我们就开始执行上一阶段产出的机器码。

而在JS的执行过程中,经常遇到的就是对象属性的访问。作为一种动态的语言,一个简单的属性访问可能包含着复杂的语义,比如Object.xxx的形式,可能是属性的直接访问,也可能去调用的对象的Getter方法,还有可能是要通过原型链往上层对象中查找。这种不确定性而且动态判断的情况,会浪费很多查找时间,所以V8会把第一次分析的结果放在缓存中,当再次访问相同的属性时,会优先从缓存中去取,调用GetProperty(Object,"xxx",feedback_cache)的方法获取缓存,如果有缓存结果,就会跳过查找过程,又大大提升了运行性能。

除了上面针对读取对象属性的结果缓存的优化,V8还引入了ObjectShapes(隐藏类)的概念,这里面会记录一些对象的基本信息(比如对象拥有的所有属性、每个属性对于这个对象的偏移量等),这样我们去访问属性时就可以直接通过属性名和偏移量直接定位到他的内存地址,读取即可,大大提升访问效率。

既然V8提出了隐藏类(两个形状相同的对象会去复用同一个隐藏类,何为形状相同的对象?两个对象满足有相同个数的相同属性名称和相同的属性顺序),那么我们开发者也可以很好的去利用它:

尽量创建形状相同的对象

创建完对象后尽量不要再去操作属性,即不增加或者删除属性,也就不会破环对象的形状

完成

到此V8已经完成了一份JS代码的读取、分析、解释、编译、执行。

总结

以上就是从JS代码下载到最终在V8引擎执行的过程分析,可以发现V8其实有很多实现的技术点,有着很巧妙的设计思想,比如流式处理、缓存中间产物、垃圾回收等,这里面又会涉及到很多细节,很值得继续深入研究。

作者:Tadm

谷歌Android 13即将发布:可运行Win11,大部分功能可用

Android 12已经发布了将近一年,但是周围用上它的人,寥寥无几。

而谷歌已经开始准备发布Android 13了,正式版将在5月11日- 5月12日谷歌 I/O 大会公开。

现阶段已经发布的是测试版Android 13,如果你也想抢先体验,这里有2个方法。

本次谷歌Android 13界面上改动并不大,更大的亮点在于:可运行Windows 11系统。

这里面的涉及到的技术,大家可以反向理解win11系统运行Android应用。

而Android开发者在Pixel 6手机上,已经在安卓13系统中,通过虚拟机成功运行Win11 on ARM系统。

虽然不支持硬件GPU加速,但是win11系统大部分功能均能正常使用。

之所以能够取得这么好的效果,主要就是因为谷歌优化了Android 13虚拟化支持。

目前谷歌也在不断改善虚拟化框架,确保它可以在其他设备上运行良好。

而且,相对于上一代,Android 13的安全性也更加强,比如说应用获取照片等数据的时候,会保持每次询问,确保使用者可以更加自由安全地控制应用。

同时,Android 13还可以进一步设置不允许将自己的位置信息被WIFI透露出去,更好地保护信息安全。

另外,Android 13依旧支持用户定制化主题,还允许用户就特定APP设置对应的语言使用,比如说系统语言是中文,但是你去可以单独设置某APP为英文语言。

不过,关于上面的功能,非常多网友谷歌吐槽抄iOS,还抄国产手机。

当然,不可否认的是,Android 13配合Pixel 6运行Win 11真的非常令人印象深刻,只是对于普通用户来说,这个意义就见仁见智了。

那你又是怎么看待Android 13可运行Win11的呢?

YUNOS与Android,两个系统究竟有什么区别

区别是:早期的时候,YunOS系统是对安卓的硬件和软件之间的中间层进行了替换和修改,就是YunOS采用了自家的虚拟机,新版的YunOS 3.0开始更完完全全的是一个独立的操作系统了,为什么说YunOS 3.0是一个独立的操作系统而不是安卓系统?可以来对比下YunOS 3.0和Andorid系统的架构图,看看两者本质上的区别。

上图是YUNos的系统架构图,下图是Android的系统架构图。

YunOS 3.0的移动终端部分基于Linux内核以及WebKit、OpenGL和SQLite等开源库,在应用层和API都大量调用了基于Web端的云计算,采用的是最新的HTML5技术。

YunOS是阿里巴巴集团旗下智能操作系统,融合了阿里巴巴在云数据存储、云计算服务以及智能设备操作系统等多领域的技术成果,可搭载于智能手机、智能穿戴、互联网汽车、智能家居等多种智能终端设备。

YunOS基于Linux研发,搭载自主研发的核心操作系统功能和组件,支持HTML5生态和独创的CloudCard应用环境,增强了云端服务能力。

Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用“安卓”或“安致”。Android操作系统最初由Andy Rubin开发,主要支持手机。

参考资料:

百度百科-YunOS?Android