每日一题:网络编程概述

每日一题:网络编程概述

面试率: ★★★★★

面试提醒

网络编程是个十分重要知识点,在移动端和服务端,前端都扮演着十分重要的位置,Android中几乎只要是上线的项目基本都会涉及到网络,应聘者们应该熟悉掌握该技术.

面试技巧

网络编程概念会比较多,你可能要掌握Android平台下的常见网络API接口;一些相关网络协议;网络架构和数据传输;网络安全.

从上面看来我们要掌握的内容实在太多了,为了简化我们的准备工作,提供以下几个技巧:

  • 网络库掌握技巧
    面试中经常会被问到一些比较流行的网络框架,如okHttp,而okHttp源码中包含了协议,缓存,架构,加密,压缩,异步,并发等技术,没错你要掌握的就是把okHttp的源码熟悉掌握下来,而外面目前有很多这相关的资料博文.
    这种掌握技巧可以比较有条理的全局去掌握网络编程,并从中学习到一些大神代码书写规范.

  • 分类掌握技巧

  • 智能硬件
    如面试智能硬件的公司你主要要掌握的是相关的WIFI,蓝牙,Socket.
  • 视频直播
    Android这边要了解jni,ndk,媒体协议(hls、rtsp、rtmp等),另外还有流服务器.
  • 新闻电商
    服务端分页加载大数据,网络框架封装,js与java交互等

面试题

下面通过一些比较常见的面试题来,提高我们对Android网络编程的了解.

Android中常见的网络API接口了解多少?

首先,你应该先了解的下面几个概念:

  • Android平台网络相关API接口
  1. Java.NET.* (标准Java接口)
    java.Net.* 提供与联网有关的类,包括流、数据包套接字(socket) 、Internet 协议、常见Http处理等。比如:创建URL,以及URLConnection /HttpURLConnection 对象、设置链接参数、链接到服务器、向服务器写数据、从服务器读取数据等通信。这些在Java网络编程中均有涉及。
  2. Org.apache 接口
    对于大部分应用程序而言JDK本身提供的网络功能已远远不够,这时就需要Android提供的Apache HttpClient 了。它是一个开源项目,功能更加完善,为客户端的Http编程提供高效、最新、功能丰富的工具包支持。
  3. Android.net.* (Android网络接口)
    常常使用此包下的类进行Android特有的网络编程,如:访问WiFi,访问Android联网信息,邮件等功能。

常见的网络架构有几种?

网络架构主要有两种模式B/S,C/S

  1. B/S----> 就是浏览器/服务器端模式了,通过应用层的HTTP协议通信,不需要特定客户端软件,而是需要统一规范的客户端,简而言之就是Android网络浏览器(如chrome,UcWeb,QQ浏览器等等)访问web服务器端的方式了。
  2. C/S----> 就客户端/服务器端模式,通过任意的网络协议通信,需要特定的客户端软件。

服务器一般会返回什么类型数据给客户端?

服务器端返回客户端的内容有三种方式:

  1. 以HTML代码的形式返回。
  2. 以XML字符串的形式返回,做Android开发时这种方式比较多。返回的数据需要通过XML解析(SAX、DOM,Pull,等)器进行解析(必备知识)。
  3. 以json对象的方式返回(开发常用)。

从长连接和短连接的角度分析Android的网络编程分为2种:基于socket的 和 基于http协议的

说说你对socket的了解

socket基本概念

  • 三元组(ip地址,协议,端口)
    Socket 是对 TCP/IP 协议族的一种封装,是应用层与TCP/IP协议族通信的中间软件抽象层。从设计模式的角度看来,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

Socket 还可以认为是一种网络间不同计算机上的进程通信的一种方法,利用三元组(ip地址,协议,端口)就可以唯一标识网络中的进程,网络中的进程通信可以利用这个标志与其它进程进行交互。

socket下的外观模式

外观模式(face pattern)
外观模式也叫门面模式,虽然平时我们可能没什么听过这个模式,但是外面实际开发中很多时候也会使用到他,因为它完美地体现了依赖倒转原则迪米特法则的思想,所以是非常常用的模式之一.

外观设计模式在什么时候用好?
这个要分三个阶段:

  1. 在设计初期阶段,应该要有意思的讲不通的两个层分离,如经典的三层架构(mv*),就需要考虑数据层访问业务层,业务层和展示层的层与层之间建立外观Facade ,这样可以为负责的子系统提供一个简单的接口,使得耦合大大降低.
  2. 在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,大多数的模式使用时也都会产生很多小的类,这本来是好事,但是也给外部调用它们的用户程序带来了使用上的困难,给这些小类添加外观Facade 可以提供一个简单的接口,减少它们之间的依赖.
  3. 在维护一个遗留的大型系统时,可能这个系统以及非常难以维护和拓展了,但因为它包含非常重要的功能,新的需求必须要依赖于他.此时用外观模式Facade也是非常适合的.你可以为新的系统开发一个外观Facade 类,来提供设计粗糙或高度复杂的遗留代码的比较清晰的简单接口,让新的系统与Facade 对象交互, Facade与遗留代码交互所有复杂的工作.

实例:
农夫有很多家禽,如鸭,鸡,鹅,他们都需要喂养和照顾.
因为鸡鸭鹅吃的饲料都是一样的,所以如果农夫每种家禽都单独去做,这样的效率就会很低,而且整个过程也相当复杂,因此我们通过门面模式把要对鸡鸭鹅做的事情封装在 Poultry 家禽类中,里面过程不用理,只要提供 feed 和 care 的公共方法即可.

//class: Duck,Duck,Goose
//method: feed,care

class Poultry{
pig =  new Pig();
duck =  new Duck();
goose =  new Goose();

    void feedMethod(){
    pig.feed();
    duck.feed();
    goose.feed();
    }
    
    void careMethod(){
    pig.care();
    duck.care();
    goose.care();
    }
}

基于TCP/IP协议之上的协议

使用HttpURLConnection连接URL

  • GET请求
URL url = new URL(
                    "http://baidu.com");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(TIME);
            conn.setReadTimeout(TIME);
            int responseCode = conn.getResponseCode();
            if (responseCode == 200) {
                input = conn.getInputStream();
                if (input != null) {
                    //TODO 把流转成String
                    
                }
            }
  • 记得设置连接超时,如果网络不好,Android系统在超过默认时间会收回资源中断操作.
  • 返回的响应码200,是成功.
  • 在Android中对文件流的操作和Java SE上面是一样的.
  • 在对大文件的操作时,要将文件写到SDCard上面,不要直接写到手机内存上.
  • 操作大文件是,要一遍从网络上读,一遍要往SDCard上面写,减少手机内存的使用.这点很重要,面试经常会被问到.
  • 对文件流操作完,要记得及时关闭.
  • POST请求
    向服务器端发送请求参数,步骤:
String data = "username=justice&password=infiniteJustice";
            URL url = new URL(
                    "http://192.168.31.144:10010/MINATest/servlet/DataTestServlet");
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(TIME);
            conn.setReadTimeout(TIME);
            conn.setDoInput(true);// 允许输入
            conn.setDoOutput(true);// 允许输出
            conn.setUseCaches(false);// 不使用Cache
            conn.setRequestProperty("Charset", ENCODING);
            conn.setRequestProperty("Content-Length",
                    String.valueOf(data.length()));
            conn.setRequestProperty("Content-Type", "text");//设置文件类型
            conn.setRequestProperty("Charset", "UTF-8");//设置字符集
            conn.setRequestProperty("Connection", "Keep-Alive");//设置长连接             conn.setRequestProperty("Content-Length", String.valueOf(data.length));//设置文件长度
            conn.setRequestProperty("Accept“,” image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword");//设置HTTP请求头
            conn.setRequestProperty("Accept-Language“,"zh-CN");//设置语言
        
            conn.setRequestMethod("POST");
            DataOutputStream outStream = new DataOutputStream(
                    conn.getOutputStream());
            outStream.write(data.getBytes());
            outStream.flush();
            outStream.close();
            if (conn == null) {
                return;
            }
            int responseCode = conn.getResponseCode();
            if (responseCode == 200) {
                input = conn.getInputStream();
                if (input != null) {
                    
                }
            }
  • 发送POST请求必须设置允许输出.
  • 不要使用缓存,容易出现问题.
  • 在开始用HttpURLConnection对象的setRequestProperty()设置,就是生成HTML文件头.
  • 向服务器端发送xml数据(也称为实体Entity)
    XML格式是通信的标准语言,Android系统也可以通过发送XML文件传输数据.
  • 我们使用的是用HTML的方式传输文件,这个方式只能传输一般在5M一下的文件.
  • 传输大文件不适合用HTML的方式,传输大文件我们要面向Socket编程.确保程序的稳定性
  • 将地址和参数存到byte数组中:byte[] data = params.toString().getBytes();
  • 利用Apache的HttpClient实现Android客户端发送实体Entity.
  • 以上为直接利用HTTP协议来实现的,其实Android已经集成了,第三方开源项目:
    org.apache.http.client.HttpClient,可以直接参考它提供的API使用。
    HTTP clients encapsulate a smorgasbord of objects required to execute HTTP requests while handling cookies, authentication, connection management, and other features. Thread safety of HTTP clients depends on the implementation and configuration of the specific client.
    使用POST方法进行参数传递时,需要使用NameValuePair来保存要传递的参数。另外,还需要设置所使用的字符集。

其他网络相关

服务器实现心跳机制的两种策略?

网络中的接收和发送数据都是使用SOCKET进行实现。但是如果此套接字已经断开,那发送数据和接收数据的时候就一定会有问题。可是如何判断这个套接字是否还可以使用呢?这个就需要在系统中创建心跳机制。其实TCP中已经为我们实现了一个叫做心跳的机制。

大部分C/S的应用需要心跳机制。心跳机制一般在Server和Client都要实现,两者实现原理基本一样。Client不关心性能,怎么做都行。

如果应用是基于TCP的,可以简单地通过SO_KEEPALIVE实现心跳。TCP在设置的KeepAlive(java中的长连接) 定时器到达时向对端发一个检测TCP segment,如果没收到ACK或RST,尝试几次后,就认为对端已经不存在,最后通知应用程序。这里有个缺点是Server主动发出检测包,对性能有点影响

应用自己实现:

  1. Client启动一个定时器,不断发心跳;
  2. Server收到心跳后,给个回应;
  3. Server启动一个定时器,判断Client是否存在,判断方法这里列两种:时间差和简单标志。

时间差策略

  1. 收到一个心跳后,记录当前时间(记为recvedTime)。
  2. 判断定时器时间到达,计算多久没收到心跳的时间(T)=当前时间 - recvedTime(上面记录的时间)。如果T大于某个设定值,就可以认为Client超时了。

简单标志

  1. 收到一个心跳后,设置连接标志为true;
  2. 判断定时器时间到达,查看所有的标志,false的,认为对端超时了;true的将其设成false。
  3. 上面这种方法比上面简单一些,但检测某个Client是否离线的误差有点大。

native与js互调?

Android WebView控件
在android app 中嵌入网页的形式。
此外,通过webview可以实现HTML <-> Javascript <-> Android Java 交互,例如:

  • Javascript调用Java
    webview.addJavascriptInterface(Object obj, String interfaceName) 方法,让该方法可以在javascript中被调用;
    在Android中创建提供给webview中页面js调用的接口
    ,并在该接口中添加 @JavascriptInterface注入,表示该方法可以被js掉用,如js调用native关闭activity方法 closeThisPage:
@JavascriptInterfacepublic void closeThisPage(){
      //关闭本页面  context.finish();}
  • Java中调用Javascript脚本中的方法
    调用js的show方法.
    webview.loadUrl("javascript:show('"+json+"')");
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,424评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 梦里旧恨,梦外新愁,相思夕阳昏瘦。遥望嫦娥轻舒袖,不解人间常醉秋。 皎朗月下,谁与登楼?长亭幽意将休。寂寞长天陈北...
    大唐逸民阅读 131评论 0 4
  • 出于种种考虑,刘彻有着一种尊霍抑卫的心理,也就使得霍去病迅速崛起,成为比卫青更耀眼的一颗将星。 元狩二年(公元前1...
    懒虫小狮子阅读 272评论 0 0
  • HomeKit 网站介绍:https://developer.apple.com/homekit/ 开发指南:ht...
    七一小月阅读 1,594评论 0 1