您的位置:首页 > 职场人生

UC面试java游戏程序员经历

2014-06-17 01:59 302 查看
今天去了UC面试.面试的Java后台开发岗位.技术面的面试官问了我如下几个问题,记录一下吧.现在做一个记录吧.无论如何,这也是很宝贵的经验.!

问题1:关于HTTP协议的长连接

什么是HTTP长连接?
HTTP长连接,与一般每次发起http请求或响应都要建立一个tcp连接不同,http长连接利用同一个tcp连接处理多个http请求和响应,也叫HTTP keep-alive,或者http连接重用。使用http长连接可以提高http请求/响应的性能。

使用http长连接有很多好处,包括:
更少的建立和关闭tcp连接,可以减少网络流量。

因为已建立的tcp握手,减少后续请求的延时。
长时间的连接让tcp有充足的时间判断网络的拥塞情况,方便做出下步操作。

这些优点在使用https连接时更显著。可以减少多次建立高消耗的SSL/TLS握手。
在HTTP/1.1中,默认使用的是长连接方式。客户端默认服务端会保持长连接,即便返回错误响应;除非明确指示不使用长连接。同时,协议中也指定了客户端可以发送关闭信号到服务端来关闭TCP连接。

怎样是连接可以重用?
因为TCP是基于流的协议,所以HTTP协议需要有一种方式来指示前一个响应的结束和后一个响应的开始来重用已建立的连接。所以,它要求连接中传输的信息必须有自定义的消息长度。自定义消息长度可以通过设置 Content-Length 消息头,若传输编码的实体内容块,则每个数据块的标明数据块的大小,而且响应体也是以一个特殊的数据块结束。

当前的JDK如何处理Keep-Alive?
JDK同时支持HTTP/1.1 和 HTTP/1.0。
当应用程序读取完响应体内容后或者调用 close() 关闭了URLConnection.getInputStream()返回的流,JDK中的HTTP协议句柄将关闭连接,并将连接放到连接缓存中,以便后面的HTTP请求使用。
对HTTP keep-Alive 的支持是透明的。但是,你也可以通过系统属性http.keepAlive和http.maxConnections以及HTTP/1.1协议中的特定的请求响应头来控制。

控制Keep-Alive表现的系统属性有:

http.keepAlive=<布尔值>
默认: true
指定长连接是否支持

http.maxCon
4000
nections=<整数>
默认: 5
指定对同一个服务器保持的长连接的最大个数。

影响长连接的HTTP header是:
Connection: close
如果请求或响应中的Connection header被指定为close,表示在当前请求或响应完成后将关闭TCP连接。

JDK1.5中的新特性
当应用接收到400或500的HTTP响应时,它将忽略IOException 而另发一个HTTP 请求。这种情况下,底层的TCP连接将不会再保持,因为响应内容还在等待被读取,socket 连接未清理,不能被重用。应用可以在捕获IOException 以后调用HttpURLConnection.getErrorStream()
,读取响应内容然后关闭流。但是现存的应用没有这么做,不能体现出长连接的优势。

SUN实现中的特定属性来帮助接收到错误响应体后清理连接:

主要的一个是:

sun.net.http.errorstream.enableBuffering=<布尔值>

默认: false

当上面属性设置为true后,在接收到响应码大于或等于400是,HTTP 句柄将尝试缓存响应内容。释放底层的socket连接来重用。所以,即便应用不调用getErrorStream()来读取响应内容,或者调用close()关闭流,底层的socket连接也将保持连接状态。

下面的两个系统属性是为了更进一步控制错误流的缓存行为:

sun.net.http.errorstream.timeout=<int> in 毫秒

默认: 300 毫秒

sun.net.http.errorstream.bufferSize=<int> in bytes

默认: 4096 bytes
你如何做可以保持连接为连接状态呢?
不要忽略响应体而丢弃连接。这样会是TCP连接闲置,当不再被引用后将会被垃圾回收器回收。
如果getInputStream()返回成功,读取全部响应内容。如果抛出IOException ,捕获异常并调用getErrorStream() 读取响应内容(如果存在响应内容)。

即便你对响应内容不感兴趣,也要读取它,以便清理连接。但是,如果响应内容很长,你读取到开始部分后就不感兴趣了,可以调用close()来关闭流。值得注意的是,其他部分的数据已在读取中,所以连接将不能被清理进而被重用。

问题2:如果一个表里面有100亿条数据,你会打算怎么做改进处理.?怎么倒序查出前30条数据?

我的回答是可以进行分库操作.但是分了库之后存在里面存的数据不一定是按照顺序排列的.这样分出来的数据库得出来的数据就会有偏差.之前没有面对过这个问题,这种数据即使塞在缓存里也会塞爆.我最后给出的方案是把它变成全文搜索的方式.利用Hadoop来处理,能够用比较低的成本来解决这个问题.回来之后,上网找了一下资料,貌似没有很好的办法.大多数的建议还是分库分表,建立索引.分区和分页查询数据量小的表,在内存里查询.但是也没有办法保证它们的记录是有规律的.排序这个问题比较难搞.

问题3:当有一个功能需要频繁访问,你怎么处理.?

我的回答是可以进行读写分离.如果只是读,那么可以提高响应的速度.同时也可以引入缓存,进一步加快响应.追问,如果需要更改,同时需要实时数据.?我的回答是在修改后,先更改缓存里面的数据,将这些实时数据进行标记.利用空闲时间进行同步数据库的操作.这样保证了数据的一致性.

<
c038
span style="color:rgb(75,75,75);font-family:georgia, verdana, Arial, helvetica, 'sans-seriff';line-height:20px;">问题4:有一个1,000W数据记录的表,数据表的id是自增的,需要随机取10条记录,给出解决思路.?

我的回答是可以用Java来辅助实现.Java中有Random可以读取到随机数.通过这个随机数作为表的id.通过以下方式查找:

select
* from XXX where id in ('id1','id2',...'idn')追问,还有其他解决方案吗.?因为这里面的记录可能被修改过.里面的随机出来的id可能已经不存在了.应该用select max(id) from XXX得出最大的id.从1到这个最大的id之间查找.之后用limit查询出一段的数据.

问题5:为什么大数据量的时候delete
from XXX where id 会比delete from XXX where ...要好.?

我的回答无法自圆其说.只能说是习惯用法.其实后来认真想想,因为大数据量的时候,如果只是对属性删除,那么删除的就是整个进行全表搜索再删除.如果用id的话要删除的范围要小很多.可能是这个原因吧.中间select出来的是一个临时表,但是表里面的数据相对于整个表的数据是少很多的.

还有几个问题,围绕的都是大数据量或者海量请求怎么处理的问题.很多时候工作中都没有遭遇过这么多的极端条件.确实要应该好好思考了.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  面试