JasonWang's Blog

JasonWang's Blog

Android系统时间自动更新机制

Android系统是如何更新时间的了?Android提供了两种时间更新方式,NITZ和NTP,其中NITZ是基于移动基站通信更新的,与语音通话时相同的一个通道,而NTP则是通过数据通道(此时手机必须能上网)来更新的。这里,就来了解下这两种时间更新方式具体是如何工作的吧?

Java程序编译过程

Java编译过程

一般,C/C++程序的编译过程可以分为5个步骤(见下图):Preprocessing(预处理),Parsing(解析), Translation(翻译),Assembling(汇编),Linking(链接)。

Java程序具有平台无关性,其在Java Virtual Machine(JVM)上执行,因此编译过程与C/C++大不相同:Java程序首先由编译器翻译成包含了Bytecode(字节码)的.class文件,程序执行时,由类加载器(class loader)将该类的字节码加载到JVM中,JVM会解释执行相应的Bytecode。

由人定胜天说起

我同意叔本华说的,引导人们通向艺术和科学的最强烈动机之一是摆脱日常生活及其中令人痛苦的粗糙状态和无望的枯燥乏味,摆脱一个人自身总是在变化着的欲望的羁绊。。。就像画家、诗人或者哲学家一样,科学家努力要创造一个属于他自己的世界。他们中的每个个人都是这个宇宙及它的结构成为它的感情生活的支点,这是为了以这种方法寻找到他在狭窄的个人经历的漩涡中无法找到的宁静与安全

    爱因斯坦

nature

停机问题

停机问题(The halting problem) 是可计算理论(Computability theory)中至关重要的一个问题。简单的来说,它要解决:给定一个输入,需要确定一个计算机程序是否能停机(产生问题的解)或者陷入死循环。究竟是否存在一个机器,能够检查给定任何输入的任何程序,确定程序是否在有限时间里停机了?

通常,使用Turning Machines(图灵机)来证明该理论:停机意味着图灵机接受或者拒绝一个输入,而如果一个程序在图灵机上陷入了死循环,则说明该图灵机不能在给定的输入上产生解。早在1936年,Alan Turing就证明了,停机问题是不可判定的,因而不可解。如果停机问题存在解,则其他许多计算机科学的难题也会得到解答,如 Kolmogorov compexity, the Busy Beaver function等。

Linux Shell快速入门

前言

开始使用Ubuntu操作系统,使用起来感觉挺顺,但是对于Shell脚本了解不多,以下是一个简单的shell入门总结。

不同的类Unix系统可能使用不同的Shell程序, 这里所有的例子都是基于Bash(Bourne Again Shell)

脚本语言,既然冠之以“语言”,就说明它跟其他C/C++等编译语言在形式上是完全一样的,有变量,有函数,有if,else,while等条件分支,只是脚本语言是解释性的执行:碰到一句,解释一句,执行。

Dependency Inversion Principle(依赖反转原则)

原文链接
by Robert C. Martin(Uncle Bob)

前言

这篇文章写于1996年,里边清晰而简明的介绍了“依赖反转原则”,对了解Dependency Injection很有帮助。今天看来,仍然具有很好的释疑作用。

介绍

我上一篇96年的文章谈到了 Liskov Substitution Principle(LSP)。 这个原则应用到了C++时,为使用公开(public)继承(inheritance)提供了指导。 该原则说,每一个操作一个基类的引用或者指针的函数,都应能够同样操作该基类的派生类,即使其对该派生类一无所知。这就意味着,派生类的虚成员函数必须与基类的虚成员函数保持一致,并且不应该做更多的事情。也就是说,基类中的虚成员函数必须要在派生类中,并且保证只做有用的工作。如果违背LSP原则,操作基类的引用或指针的函数将不得不检查具体对象的类型,以确保操作正确。而检查对象类型则违反了上周讲到的Open-Closed Principle(OCP)。

在此次专栏里,我们将讨论OCP与LSP结构化带来的启示。 严格使用这些原则所产生的结构,可以被一般化成一个更为基本的原则,我称之为“Dependency Inversion Principle”(DIP)。

Android Binder入门

背景

如今的操作系统都支持多进程并发执行, 系统一般都存在多种不同的服务运行在多个进程当中。那么,进程与进程之间如何通信,即跨进程通信(IPC, Inter-Process Communication)是如何进行的呢? Linux已有好几种IPC机制:

  • Signals: 最早的IPC方式,一个进程通过发送信号给另一个有相同UID/GID的进程或者在同一进程组的进程
  • Pipes(包括 named pipes): Pipes是一个单向的用于连接一个进程的标准输出与另一个进程的标准输入的字节流通道
  • Sockets: 双向的通道,两个进程通过打开同一个socket进行通信
  • Message queues: 一个进程将消息写入消息队列,另一个进程从改队列中读取消息
  • Semaphores: 信号量是一个可以被多个进程读写的共有变量
  • Shared Memeory: 一个系统的内存区域,通过将其映射到两个不同进程的虚拟地址空间,因此每个进程都可以访问该地址空间
  • D-Bus(Desktop Bus): 用于桌面组件与服务通讯的协议
Android Fota升级

Android设备的系统升级有两种方式:(1)下载更新包到手机后,手动安装,即所谓“卡刷包”的形式更新;(2) 通过 Over-the-air(OTA)的方式更新系统,简称为FOTA(Firmware Over The Air),FOTA升级有两种方式,一种是Full update,即将整个IMG置于升级包中,然后将升级包直接拷贝到系统;一种是Increamental update,即通过增量式的差分包,只是将系统更新的部分打包,然后以打补丁的形式应用到系统。

在介绍FOTA升级流程之前,先来看看Android系统的分区。一般,Android系统有如下几个分区(不同厂商、设备可能有差异):

  • /boot: 用于系统启动的分区,主要包括Kernel和ramdisk。主要用于挂载system和其他分区,并加载system分区的代码。没有该分区,手机是无法正常启动的;

ramdisk.img is a small partition image that is mounted read-only by the kernel at boot time. It only contains /init and a few config files. It is used to start init which will mount the rest of the system images properly and run the init procedure. A Ramdisk is a standard Linux feature.

  • /system:该分区包含了出了 kernel/ramdisk之外的系统应用程序和库文件;正常操作情况下,该分区是只读状态;
  • /recovery:用于系统升级打补丁,包含了一个完整的Linux操作系统和一个特殊的recovery包。FOTA升级时,下载完更新包后,进入recovery模式,recovery程序会读更新包,然后将各个patch应用到各个分区;
  • /misc:升级时,recovery用于存储相关信息的小分区
  • /data:主要包含了用户的数据,如联系人、短信、设置以及安装的应用。清除该分区等同于将手机重置,OTA不会影响该分区;
  • /cache:用于存放需要经常访问使用的数据和应用组件,访问该分区需要特殊的应用程序权限;OTA升级时下载的升级包就位于该分区;
Git常用命令

Git是目前使用最普遍的开源分布式版本控制系统,由Linus Torvalds在2005年开发, 与传统的集中式代码管理工具SVN/CVS不同, git是一个分布式的版本控制工具, 如代码托管网站Github就是基于Git作版本管理; Android Studio也支持使用Git来进行版本控制。

这里就来看一看基本的Git命令操作。

更新Git版本

1
2
3

$ git clone git://git.kernel.org/pub/scm/git/git.git

avatar
JasonWang
生命短暂,莫空手而归