学习笔记
引言:本文章只是个人记录日常学习的笔记,将不定期更新。
2017.3.11
-
2017.3.14
- Android 线程与进程
- Android app 启动过程
- Service 与耗时工作线程的区别
- 何时使用 Service,何时使用 Working Thread 即 UI 线程(主线程)开启耗时操作线程
- Local Service 与 Remote Service
- Service 的使用(实时温度显示客户端)
2017.3.16
- Service 与 Activity交互
- Service 开启线程后与 Activity 交互,注意线程之间的数据传递要么用 Handler 或者 AsyncTask 类
- 只能在 UI 主线程更新界面的真正含义(慕课网笔记)
2017.3.20
- ArrayBlockingQueue 是阻塞队列且线程安全
- 线程池的使用
2017.3.21
- HandlerThread 与 Handler 的关系
- Handler , Looper , MessageQueue 与线程的关系
2017.3.22
知乎 live 总结
- 要有兴趣学安卓
- 边学边实践项目,加深印象
- 需要用什么就学什么
- 巩固计算机基础知识,如操作系统、计算机网络、熟练掌握两三门编程语言
- 关注新兴技术,比如人工智能
2017.3.25
- 一次只有一个进程可以在一个处理器核心上运行
- 单线程模型:一个进程是一个只能进行单个执行线程的程序
- “超线程”(Hyperthreading Technology)技术就是通过采用特殊的硬件指令,可以把一个物理内核模拟成两个逻辑内核,在单处理器中实现线程级的并行计算,同时在相应的软硬件的支持下大幅度提高运行效能,从而实现在单处理器上模拟双处理器的效能。其实,从实质上说,超线程是一种可以将 CPU 内部暂时闲置处理资源充分“调动”起来的技术。虽然采用超线程技术能同时执行两个线程,但它并不象两个真正的 CPU 那样,每个 CPU 都具有独立的资源。当两个线程都同时需要某一个资源时,其中一个要暂时停止,并让出资源,直到这些资源闲置后才能继续。因此超线程的性能并不等于两颗 CPU 的性能
- 一个应用程序通常是作为一个具有多个控制线程的独立进程实现的
- 多进程的优点之一就是能够充分使用多处理器体系结构,以便每个进程能并行运行在不同的处理器上。而使用多线程加强了并发功能(在不谈论 Intel 的超线程技术)
- 数据结构是一堆数据元素和这些数据元素之间关系的总和,数据元素是数据的基本单位
- 按关系或结构分。数据结构可归结为以下4类:集合结构、线性结构、树形结构和图状结构
2017.4.8
- 内存可以看作是所有小房间连续线性排列而组成的大房子
- 为了标识大房子中的某一个小房子,我们给所有小房子编号,这就是内存地址,或者叫指针。指针就是特别指向了某一个小房子以方便找出房子里存储的货物(数据)。指针本质就是内存空间地址
- 而新建一个以链表为存储结构的线性表,如 List a;“a”所代表的含义其实就是这个链表的头指针,指向链表的第一个数据单元结点
2017.4.10
-
根据模块化程序设计思想,采用分解法把问题分解为多个相对独立的子问题,每个子问题对应程序的一个功能模块
-
一个源程序文件一般定义多个函数解决复杂问题。一个C程序由一个或多个源程序文件组成。
-
int x=10,y=100; swap(x,y);
按照C语言的参数传递规则,实参变量x和y的值分别被“单向传递”给形参变量a和b
-
数组元素作为函数参数,这种情况下与简单变量作为函数的参数完全一样,数组元素的值被单向传递给形参变量。另一种情况是数组名作为函数的参数,此时作为实参的数组名讲其存储的数组的首地址单向传递给作为形参的数组名。所以第二种情况下实参数组名和形参数组名中存放相同的地址,实际上实参数组名和形参数组名代表的是同一个数组。这样,如果在被调函数中通过形参数组名去改变数组元素,则程序流程返回主调函数后,实参数组名对应的数组内容也随之变化
-
递归调用过程必须在进行有限次后终止,这就必须在编写递归调用函数时进行条件控制
-
由于C语言是以源程序文件为单位进行编译的,所以在一个源程序文件中定义的全局变量,默认情况下不能在其他源程序文件中使用
-
C 语言中,供用户程序运行使用的内存空间分为3个部分:程序区、静态存储区、动态存储区
程序区:存放可执行的程序指令
静态存储区:存放程序运行期间占用固定内存单元的变量,比如全局变量、静态局部变量等
动态存储区:存放程序运行期间根据需要动态分配存储单元的变量,比如非static的局部变量、函数的形参等
-
局部变量的存储类别有自动、静态、寄存器。全局变量的存储类别有外部和静态。外部全局变量(外部函数)允许其他源程序文件直接使用。而静态全局变量(内部函数)只允许在本源程序文件中使用
-
数据在程序的运行过程中存储在计算机内存中,而内存是以字节为基本存储单元的连续存储空间。为了能够标识内存中不同的存储单元,每个存储单元都有一个编号,这个编号就是内存单元的“地址”。每个变量的值存储在内存空间中,通过变量名访问变量的值,这就是“按名访问”。“直接访问”是通过存储单元的地址读取其中的值。变量名在编译器中会与实际内存地址关联
-
一个变量的内存地址称为改变量的“指针”。如果把一个变量的指针(地址)存放到另一个变量中,则存放指针的变量称为“指针变量”
-
指向结构体类型数据的指针变量称为结构体指针变量,他存放结构体变量的起始地址。
2017.4.23
- 带参数的宏的定义:一切都要括号,指整个值要括号,参数出现的每个地方都要括号
2017.4.24
子网划分- 子网划分是某个网络内部的事情。在某个网络之外的视角下他是不具有子网的特点。只有当IP数据报传入到与该网络相连的路由器上时。该网络内部的子网划分就会将整个网络划分为若干个子网网络,每个子网络的标识就是由网络号和主机号重新组合形成的广义上的网络号。
- 由于子网划分是一个网络在内部的特性,所以某个网络的子网掩码是一定的。而为了节省地址资源,后来使用了变长子网掩码来根据实际情况在子网下再划分子网,所以一个网络下就存在多个子网掩码,这样可进一步提高IP地址资源的利用率。
2017.4.26
-
内存中的堆栈:操作系统对于正在运行的进程会分配一个独立的内存空间,这个内存空间在逻辑上分为3个部分:代码区、静态数据区和动态数据区。其中动态数据区一般又分为“堆”与”栈”。“栈stack”和“堆heap”是两种不同的动态数据区。
栈空间是由栈操作系统自动分配和释放,该部分主要用于存放函数的参数值、局部变量等。栈区的操作方式类似于数据结构中栈。
堆区空间一般由程序员分配和释放,如 C 语言中的
malloc
函数申请的空间就是堆空间。静态数据区:全局变量和静态变量都存放于该区。初始化的全局变量和初始化的静态变量放在一块区域,未初始化的全局变量和未初始化的静态变量放在相邻的另一区域。程序结束后由系统自动释放。
代码区:该区用于存放函数体的二进制代码。
-
数据结构的堆栈:数据结构意义上的”栈“是逻辑概念,具有后进先出的特点。而数据结构意义上的“堆”是一种树形结构,其满足树中任一非叶结点的关键字均不大于或不小于其左右子树的结点的关键字。
2017.4.27
- Android 作为一个移动设备平台,其软件层次结构包括操作系统、各种库和 Android 运行环境、应用程序框架和应用程序。
- Android 运行环境主要指虚拟机技术—— Dalvik 虚拟机。Dalvik 虚拟机和一般 Java 虚拟机不同,他执行的不是 Java 标准的字节码而是 Dalvik 可执行格式(.dex)中执行文件。他们两者最大不同就是 Java 虚拟机是基于栈的虚拟机,而 Dalvik 是基于寄存器的虚拟机。
- Android 的应用程序框架这一层级为应用程序的开发者提供 APIs。就是我们常说的 Android 四大组件 Activity、Broadcast Receiver、Service、Content Provider。
- XML 只是一种简单的数据存储语言,只用来存储数据,而 HTML 是用来表现数据的。
- 多种编程语言都支持获取 XML 文档。
- CSS 技术是 Web 网页技术的重要组成,页面通过 CSS 的修饰可以实现用户需要的显示效果。
- JavaScript 是一种脚本技术,页面通过脚本程序可以实现用户数据的传输和动态交互。
2017.4.28
- Socket 是支持 TCP/IP 协议的网络通信基本操作单元,是操作系统为应用程序提供的一套针对 TCP 或 UDP 的编程接口。
- 而类似 HttpURLConnection 、ftpClient 之类的类是基于 Socket 对应用层专属协议的封装。
- 递归函数是一层一层调用函数的。而在计算机中函数调用是通过栈(stack)这种数据结构实现,每当调用一层函数,栈就会加一层栈帧,每当函数返回,栈就会减少一层栈帧。所以递归用的不好可能会导致栈溢出。或者运行时间特别长。
- 尾递归:在函数返回时只调用自身。尾递归在执行过程中不需要回溯。因为尾递归把结果包含在一部分参数中。故每次调用实际上都是对参数的一个更新过程。
2017.5.3
- 运输层的“端口”概念可以类比于一个机构的收发室,这个机构收发公文都由这个收发室负责。而运输层中具体的某一个端口号可以认为是收发室中负责机构中某一个部门(可以理解为进程)收发公文的工作人员。而且这个端口号(工作人员)不是一直固定负责具体某个部门收发公文的工作(工作时由某个进程占有,通信结束后解除占有),可以在空闲时也为其他部门工作。
- 每一个 TCP 连接只能连接两个端点,就是点对点通信。而这个“点”就是我们通常所说的套接字 socket 。但是“套接字”这个翻译非常不准确,我们可以讲 socket 理解为插座,而 TCP 逻辑连接实体化为普通电线。而 socket 本身的翻译就是“插座,接头”
2017.5.4
-
注意回调机制和监听器的设计模式
-
注意 Android 项目目录下的 drawable 和 mipmap 文件夹的不同
-
关于回调机制的理解:Java 是面向对象语言,一切万物皆对象。父类暴露一个接口,接口内有一个抽象方法。该抽象方法不在父类中实现,而是在其他继承这个接口的类中实现。为了就是父类的实例能够根据实际情况各自做出反应。比如Button、ImageButton等都具有可被点击的共性,但是被点击之后相关事件的处理是不同的,比如说我想点击的这个Button弹出一个消息提示,然而我希望我的ImageButton点击之后可以弹出一个Notifaction通知,这个时候回调方法的好处就体现出来了。通过暴露接口方法可以减少很多重复,代码更加优雅。Android 当中的各种监听器采取的设计模式也是回调机制,设计模式如下:
public class A{ private CallBack mCallBack; public interface CallBack{ public abstract void work(); } public void setCallBack(CallBack callBack){ this.mCallBack=CallBack; } //调用回调接口对象中的方法 public void doWork(){ mCallBack.work(); } }
public class B{ private A a; a.setCallBack(new A.CallBack(){ @Override public void work(){ ...... } }) }
-
使用对话框最好采用 DialogFragment ,因为 DialogFragment 具有完整的生命周期,方便管理。代码如下:
public class MapLayerDialog extends DialogFragment { private ImageButton btn_normal, btn_satellite; //把它理解成监听者 public interface ChoiceListener { void onMapLayerListener(int view); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE); View view = inflater.inflate(R.layout.maplayer_choice_dialog, container); btn_normal = (ImageButton) view.findViewById(R.id.NORMAL_layer); btn_satellite = (ImageButton) view.findViewById(R.id.SATELLITE_layer); btn_normal.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ChoiceListener listener= (ChoiceListener) getActivity(); listener.onMapLayerListener(R.id.NORMAL_layer); } }); btn_satellite.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ChoiceListener listener= (ChoiceListener) getActivity(); listener.onMapLayerListener(R.id.SATELLITE_layer); } }); return view; } }
public class MainActivity extends AppCompatActivity implements LocationSource, AMapLocationListener,MapLayerDialog.ChoiceListener { //把监听者的功能赋予 Activity private MapView mMapView; private AMap mAMap; private MyLocationStyle mMyLocationStyle; OnLocationChangedListener mListener; AMapLocationClient mLocationClient; AMapLocationClientOption mLocationOption; private ImageButton mImageButton; private Context mContext; @Override protected void onCreate(Bundle savedInstanceState) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext=this; mMapView = (MapView) findViewById(mapView); mMapView.onCreate(savedInstanceState); mImageButton=(ImageButton)findViewById(R.id.choiceDialog); mImageButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MapLayerDialog mapLayerDialog=new MapLayerDialog(); mapLayerDialog.show(getFragmentManager(),"ChoiceMapLayer"); } }); init(); } ...... ...... @Override public void onMapLayerListener(int view) { switch (view){ case R.id.NORMAL_layer:mAMap.setMapType(AMap.MAP_TYPE_NORMAL); break; case R.id.SATELLITE_layer:mAMap.setMapType(AMap.MAP_TYPE_SATELLITE); break; } } }
2017.5.11
- Intent 是 Android 程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。 Intent 一般可被用于启动活动、启动服务、以及发送广播等场景
2017.5.14
- 抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。
- 如何保证Service不被杀死或被kill之后自动重启:利用系统广播
Intent.ACTION_TIME_TICK
每隔一分钟检测一次Service的运行状态
2017.6.10
- 当应用继承 ContentProvider 类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用 SharedPreferences 共享数据,需要使用 SharedPreferences API 读写数据。而使用 ContentProvider 共享数据的好处是统一了数据访问方式。
- 服务不能自己运行,需要通过调用---
Context.startService()
或Context.bindService()
方法启动服务。这两个方法都可以启动 Service,但是它们的使用场合有所不同。使用startService()
方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()
方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
2017.6.11
- Android 的官方建议应用程序的开发采用MVC 模式。MVC 是 Model,View,Controller 的缩写,MVC 包含三个部分:
- 模型层(model):对数据库的操作、对网络等的操作都应该在model里面处理,当然对业务计算等操作也是必须放在的该层的。
- 视图层(view):是应用程序中负责生成用户界面的部分。也是在整个mvc架构中用户唯一可以看到的一层,接收用户的输入,显示处理结果。
- 控制层(controller):是根据用户的输入,控制用户界面数据显示及更新model对象状态的部分,控制器更重要的一种导航功能,响应用户出发的相关事件,交给模型层处理。
- Service 和 Thread 的区别?
答:Service 是系统的组件,它由系统进程托管(ServiceManager);它们之间的通信类似于 Client 和 Server,是一种轻量级的IPC 通信,这种通信的载体是 Binder ,它是在 Linux 层交换信息的一种 IPC 机制。而 Thread 是由本应用程序托管。
- Thread:Thread 是程序执行的最小单元,它是分配 CPU 的基本单位。可以用 Thread 来执行一些异步的操作。
- Service:Service 是 Android 的一种机制,当它运行的时候如果是 Local Service,那么对应的 Service 是运行在主进程的 main 线程上的。如:
onCreate
,onStart
这些函数在被系统调用的时候都是在主进程的 main 线程上运行的。如果是 Remote Service,那么对应的 Service 则是运行在独立进程的 main 线程上。
既然这样,那么我们为什么要用 Service 呢?其实这跟 Android 的系统机制有关,我们先拿 Thread 来说。Thread 的运行是独立于 Activity 的,也就是说当一个 Activity 被杀掉之后,如果你没有主动停止 Thread 或者 Thread 里的run
方法没有执行完毕的话,Thread 也会一直执行。因此这里会出现一个问题:当 Activity 被杀掉之后,你不再持有该 Thread 的引用。另一方面,你没有办法在不同的 Activity 中对同一 Thread 进行控制。
举个例子:如果你的 Thread 需要不停地隔一段时间就要连接服务器做某种同步的话,该 Thread 需要在 Activity 没有创建并运行的时候也在运行。这个时候当你创建一个 Activity 就没有办法在该 Activity 里面控制之前创建的 Thread。因此你便需要创建并启动一个 Service ,在 Service 里面创建、运行并控制该 Thread,这样便解决了该问题(因为任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例)。
2017.6.12
-
如果后台的Activity由于某原因被系统回收了,如何在被系统回收之前保存当前状态?
答:重写onSaveInstanceState()
方法,在此方法中保存需要保存的数据,该方法将会在 Activity 被回收之前调用。通过重写onRestoreInstanceState()
方法可以从中提取保存好的数据 -
如何退出Activity?如何安全退出已调用多个Activity的Application?
- 单个 Activity:
finish()
System.exit()
- 多个 Activity:
- 抛异常强制退出:该方法通过抛异常,使程序 Force Close。方法可行。但是需要解决的问题是,如何使程序结束掉,而不弹出 Force Close 的窗口
- 记录打开的 Activity:每打开一个 Activity,就记录下来。在需要退出时,关闭每一个 Activity 即可。
- 发送特定广播:在需要结束应用时,发送一个特定的广播,每个 Activity 收到广播后,关闭即可
- 递归退出:在打开新的 Activity 时使用
startActivityForResult()
,然后自己加标志,在onActivityResult()
中处理,递归关闭 - Activity 基类:让所有 Activity 继承这个基类,基类中定义一个方法解决这个关闭各个 Activity 的共同问题
- 请解释下Android程序运行时权限与文件系统权限的区别。
- 运行时权限 Dalvik ( Android 授权)
- 文件系统 Linux 内核授权
- Android dvm 的进程和 Linux 的进程, 应用程序的进程是否为同一个概念
答:DVM 指 dalivk 的虚拟机。每一个 Android 应用程序都在它自己的进程中运行,都拥有一个独立的 Dalvik 虚拟机实例。而每一个 DVM 都是在 Linux 中的一个进程,所以说可以认为是同一个概念。
2017.6.17
-
浏览器之所以能够工作,它的核心是一个叫做「内核」的东西,这个内核就类似于汽车的引擎,没有它浏览器是没法工作的,而市面上的内核有很多种,比如:KHTML、Presto、Trident、WebKit 等,大家熟知的浏览器如 Firefox、IE、Opera、Chrome、Safari 等所用的内核都不一样,而 Chrome 和 Safari 浏览器所用的内核是一样的,叫做「WebKit」,WebKit 其实是苹果基于开源的内核 KHTML 来改造的,也是开源的。而内核其实又分为两部分:渲染引擎和 js 引擎。渲染引擎主要就是负责获取网页的 html、xml、图片、css 等内容进行渲染显示,js 引擎则负责解析 javascript 语言,实现网页的动态效果。Chrome 虽然也是基于 WebKit 内核的,但是 Google 一开始觉得 WebKit 自带的 js 引擎性能上有问题,所以 Google 专门为 Chrome 搞了个 js 引擎叫做「V8」,所以在内核方面,Chrome 和 Safari 的主要区别就在于 js 引擎不一样。
-
TCP 是面向连接的协议。那么采用 TCP 协议的运输层的连接得建议和释放是每一次面向连接得通信中不可少的过程。因此运输层连接包含了连接建立、数据传送、连接释放。
-
运输层的连接建立过程也可称作三次握手
用三次握手建立TCP连接-
第一次握手:A 主动向 B 发出建立连接的请求
-
第二次握手:B 向 A 发出确认建立连接的请求
-
第三次握手:A 向 B 发出确认
至于为什么连接建立后客户进程 A 还要发送一次确认报文。这主要是为了防止已失效(已失效:滞留在网络中而后才到达B)的连接请求报文段突然又传到了服务进程 B 中而产生错误。
-
-
运输层的连接释放过程也称作四次握手
连接释放的过程- 第一次握手:A 主动向 B 发出释放连接的请求
- 第二次握手:B 向 A 发出确认释放连接的请求
- 第三次握手:B 主动向 A 发出释放连接的请求
- 第四次握手:A 向 B 发出确认释放连接的请求
经过四次握手过程,TCP 连接还没有释放掉。必须经过时间等待计时器设置的时间 2MSL 后客户进程 A 才进入 CLOSED 状态。而 B 只要收到了 A 发过来的确认就立即进入 CLOSED 状态。因此 B 结束 TCP 连接的时间要比 A 早一些。当然服务进程也会有一个保活计时器来探测客户端是否有响应。至于为什么是两倍的 MSL 时间是保证 A 发送的最后一个报文段能够到达 B 。
2017.6.20
- RecyclerView 是 Android 5.0 系统官方推出的一个代替 ListView 的组件,ListView 和 RecycleView 的原理大致相同,如下图。
原理示意图
都是在内部维护一个缓存池,回收划出列表的 item,添加给将要进入列表的 item。只不过 ListView 内部是两级缓存,分别是mActiveViews
和mScrapViews
。而 RecycleView 内部有四级缓存。
2017.6.25
- 应用层协议与网络应用并不是同一个概念。应用层协议只是网络应用的一部分。例如,万维网应用是一种基于客户-服务器体系结构的网络应用。万维网应用包含很多部件,有万维网浏览器、万维网服务器、万维网文档的格式标准,以及一个应用层协议。万维网的应用层协议是 HTTP,它定义了在万维网浏览器和万维网服务器之间传送的报文类型、格式和序列等规则,而万维网浏览器如何显示一个万维网页面,万维网服务器是用多线程还是多进程来实现并不是 HTTP 定义的内容
- 许多应用层软件经常直接使用域名系统 DNS。虽然计算机的用户只是间接而不是直接使用域名系统,但 DNS 却为因特网的各种网络应用提高了核心服务
- 因特网的域名系统 DNS 被设计成为一个联机分布式数据库系统,并采用客户-服务器方式。
2017.6.30
- 设计模式原则:修改原有代码就说明解耦性太低。其次依赖倒转原则是让程序实体运行类都依赖抽象类,而不是实体运行类互相依赖。注意解耦!
- 设计模式——观察者模式:观察者模式又叫做发布-订阅(Publish/Subsrcibe)模式。它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 观察者模式结构图
2017.7.1
- 响应式编程:响应式编程是一种面向数据流和变化传播的编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。例如,在命令式编程环境中,
a=b+c
表示将表达式的结果赋给a
,而之后改变b
或c
的值不会影响a
。但在响应式编程中,a
的值会随着b
或c
的更新而更新。电子表格程序就是响应式编程的一个例子。单元格可以包含字面值或类似=B1+C1
的公式,而包含公式的单元格的值会依据其他单元格的值的变化而变化。响应式编程最初是为了简化交互式用户界面的创建和实时系统动画的绘制而提出来的一种方法,但它本质上是一种通用的编程范式。
2017.7.2
- 从理论上来讲,可以让每一级的域名都有一个相对应的域名服务器,使所有的域名服务器构成树状结构。但这样做会使域名服务器的数量太多,使域名系统的运行效率降低。因此 DNS 就采用划分区的办法来解决这个问题。一个服务器所负责管辖的范围叫做区。各单位根据具体情况来划分自己管辖范围的区。但在一个区中的所有节点必须是能够连通的。每一个区设置相应的权限域名服务器,用来保存该区中所有主机的域名到 IP 地址的映射。因此 DNS 服务器的管辖范围是以”区“为单位的。
- 因特网上的 DNS 域名服务器也是按照层次安排的。每一个域名服务器都只对域名体系中的一部分进行管辖
- 根名服务器:根域名服务器是最高层次的域名服务器。所有的根域名服务器都知道所有的顶级域名服务器的域名和 IP 地址。因特网上任何一个域名的解析,只要在本地服务器无法解析,就首先要求助于根域名服务器。因此根域名服务器的工作情况对整个 DNS 系统的工作至关重要。同时在许多情况下,根域名服务器并不直接把待查询的域名直接转换成 IP 地址,而是告诉本地域名服务器下一步应当找哪一个顶级域名服务器进行查询
- 顶级域名服务器:这些域名服务器负责在该顶级域名服务器注册的所有二级域名
- 本地域名服务器:本地域名服务器并不属于域名服务器层级结构中。当一个主机发出 DNS 查询请求时,这个查询请求报文就发送给本地域名服务器。每一个因特网服务提供者 ISP ,或一个大学,甚至一个大学里的系,都可以拥有一个本地域名服务器,这种域名服务器有时也称为默认域名服务器。本地域名服务器离用户较近,一般不超过几个路由器的距离。当所要查询的主机也属于同一个本地 ISP 时,该本地域名服务器立即就能将所查询的主机名转换为它的 IP 地址,而不需要再去询问其他的域名服务器
- 文件传送协议 FTP 只提供文件传送的一些基本服务,它使用了 TCP 可靠的运输服务。FTP 的主要功能是减少或消除在不同操作系统下处理文件的不兼容性。FTP 使用C/S 模式,即客户服务器模式。一个 FTP 服务器进程可同时为多个客户进程提供服务。FTP 的服务器进程有两大部分组成:一个主进程,负责接受新的请求;另外有若干个从属进程,负责处理单个请求。从属进程对客户进程的请求处理完毕后即终止,但从属进程在运行期间根据需要还可能创建其他一些子进程。FTP 的工作情况如图所示,图中的服务器端有两个从属进程:控制进程和数据传送进程。客户端除控制进程和数据传送进程还有一个用户界面进程。文件进行传输时 FTP 的客户和服务器之间要建立两个并行的 TCP 连接:控制连接和数据连接。 FTP两个并行连接
- 万维网 WWW 并非某种特殊的计算机网络。万维网是一个大规模的、联机式的信息储藏所,英文简称为 Web。万维网用链接的方法能非常方便地从因特网上一个站点访问另一个站点。
- 万维网是一个分布式的超媒体系统,它是超文本系统的扩充。所谓超文本是包含指向其他文档的链接的文本。超文本是万维网的基础。超媒体与超文本的区别是文档内容不同,超文本文档仅包含文本信息,而超媒体文档还包含其他表示方式的信息,如图形、图像、声音、动画,甚至活动视频图像。
2017.7.3
-
统一资源定位符 URL (Uniform Resource Locator)来标志万维网上的各种文档,并使每一个文档在整个因特网的范围内具有唯一的标识符 URL。URL 是与因特网相连的机器上的任何可访问对象的一个指针。URL 的一般形式由以下四个部分组成:
<协议>://<主机域名>:<端口>/<路径>
-
使用超文本传送协议 HTTP(HyperText Transfer Protocol)实现万维网上各种链接
-
万维网使用超文本标记语言 HTML(HyperText Markup Language)使得万维网网页的设计者可以很方便地用链接从本页面的某处链接到因特网上的任何一个万维网页面,并且能够在自己的主机屏幕上将这些页面显示出来。
2017.7.4
-
应用需要因特网的支持,但这些应用又不能直接使用已经标准化的因特网协议,那么我们应当了解一下系统调用和应用编程接口
-
大多数操作系统使用系统调用的机制在应用程序和操作系统之间传递控制权。
- 当某个应用进程启动系统调用时,控制权就从应用进程传递给了系统调用接口。此接口再把控制权传递给计算机的操作系统。操作系统把这个调用转给某个内部过程,并执行所请求的操作。内部过程一旦执行完毕,控制权就又通过系统调用接口返回给应用进程。总之,只要应用进程需要从操作系统获得服务,就要把控制权传递给操作系统,操作系统在执行必要的操作后把控制权返回给应用进程。因此,系统调用接口实际上就是应用进程的控制权和操作系统的控制权进行转换的一个接口。由于应用程序在使用系统调用之前要编写一些程序,特别是需要设置系统调用中的许多参数,因此这种系统调用接口又称为应用编程接口 API(Application Programming Interface) 套接字称为应用进程与运输层协议的接口
-
现在 TCP/IP 协议软件已驻留在操作系统中。因此 TCP/IP 标准没有规定应用程序与 TCP/IP 协议软件如何接口的细节。目前只有几种可供应用程序使用 TCP/IP 的应用编程接口 API——Socket
-
在讨论网络编程时常常把套接字作为应用进程与运输层协议之间的接口。在套接字以上的进程是受应用程序控制的,而在套接字一下的运输层协议软件则是受计算机操作系统的控制。因此,只要应用程序使用 TCP/IP 协议进行通信,他就必须通过套接字与操作系统交互并请求其服务。由此可见套接字是应用进程为了获得网络通信服务而与操作系统进行交互使用的一种机制。
-
TCP 系统调用过程:
-
连接建立阶段——应用进程创建套接字并绑定来指明本地端口号和本地 IP 地址。服务器进程同样过程,但之后需要调用 listen 把套接字设置为被动方式。紧接着调用 accept 以便把远地客户进程发来的连接请求提取出来。该服务进程也称为主服务器进程就为每一个新的连接请求创建一个新的套接字,并把这个新创建的套接字的识别符返回给发起连接的客户进程。与此同时,主服务器进程还要新创建一个从属服务器进程来处理新建立的连接。这样,从属服务器进程用这个新创建的套接字和客户进程建立连接,而主服务器进程用原来的套接字重新调用 accept ,继续接受下一个连接请求。客户进程调用 connect ,以便和远地服务器建立连接,此过程必须指明远地服务器的 IP 地址和端口号
-
数据传送阶段——客户和服务器都在 TCP 连接上使用 send 系统调用传送数据,使用 recv 系统调用接受数据。调用 send 需要三个变量:数据要发往的套接字的描述符、要发送数据的地址(操作系统的内核的缓存中)以及数据的长度。调用 recv 也需要三个变量:套接字的描述符、缓存地址以及缓存空间的长度
-
连接释放阶段——一旦任何一方结束使用套接字,就把套接字撤消。这时就调用 close 释放连接和撤消套接字
TCP连接系统调用顺序UDP 服务器只提供无连接服务,因此不使用 listen 和 accept 系统调用
-
2017.7.8
- HTTP 是面向事务的应用层协议
- 当我们点击了网页当中的某个链接,如“清华大学院系设置”的页面,其 URL 是
http://www.tsinghua.edu.cn/chn/yxsz/index.html
。下面我们将列举用户点击鼠标后所发生的几个事件- 浏览器分析链接指向页面的 URL
- 浏览器向 DNS 请求解析 www.tsinghua.edu.cn 的 IP 地址
- 域名系统 DNS 解析出清华大学服务器的 IP 地址为 116.111.4.100
- 浏览器与服务器建立 TCP 连接(第一次握手,服务器需要发出确认连接报文)
- TCP 建立连接的第三次握手中浏览器发出取文件命令(具体查看 HTTP 协议的请求报文)
- 服务器给出相应,发出响应报文
- 释放 TCP 连接
- 浏览器解析渲染得到的 html 文件显示网页
2017.7.11
- XHTML 是更严格更纯净的 HTML 版本
- 在数据交换, 配置文件, 任务和流程的描述, Web服务的描述, 还有界面描述领域都取得了成功
- XML 是独立于软件和硬件的信息传输工具
- XHTML 是更严格更纯净的 HTML 版本
- XHTML 是作为一种 XML 应用被重新定义的 HTML
最后是广告时间,我的博文将同步更新在三大平台上,欢迎大家点击阅读!谢谢