百度java一面总结学习

1. get与post的区别
GET把请求的数据放在url上,即HTTP协议头上,其格式为: 以?分割URL和传输数据,参数之间以&相连。 数据如果是英文字母/数字,原样发送, 如果是空格,转换为+, 如果是中文/其他字符,则直接把字符串用BASE64加密,及“%”加上“字符串的16进制ASCII码”。
POST把数据放在HTTP的包体内(requrest body)。

GET提交的数据最大是2k(原则上url长度无限制,那么GET提交的数据也没有限制咯?限制实际上取决于浏览器,(大多数)浏览器通常都会限制url长度在2K个字节,即使(大多数)服务器最多处理64K大小的url。也没有卵用。)。
POST理论上没有限制。实际上IIS4中最大量为80KB,IIS5中为100KB。

GET产生一个TCP数据包,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
POST产生两个TCP数据包,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

GET在浏览器回退时是无害的,POST会再次提交请求。

GET产生的URL地址可以被Bookmark(建立书签),而POST不可以。

GET请求会被浏览器主动cache,而POST不会,除非手动设置。

GET请求只能进行url编码,而POST支持多种编码方式。

GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

GET只接受ASCII字符的参数的数据类型,而POST没有限制

2. http与https的区别
HTTPS和HTTP的区别主要如下:

  1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。

  2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。

  3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

  4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

3.Https握手过程
一、客户端发出加密通信请求ClientHello

提供:
1,协议版本(如TSL1.0)
2,随机数1(用于生成对话密钥)
3,支持的加密方法(如RSA公钥加密)
4,支持的压缩方法

二、服务器回应SeverHello

回应内容:
1,确认使用的加密通信协议版本(TSL1.0)
2,随机数2(用于生成对话密钥)
3,确认加密方法(RSA)
4,服务器证书(包含非对称加密的公钥)
5,(可选)要求客户端提供证书的请求

三、客户端验证证书

如果证书不是可信机构颁布,或证书域名与实际域名不符,或者证书已经过期,就会向访问者显示一个警告,是否继续通信

四、客户端回应

证书没有问题,就会取出证书中的服务器公钥
然后发送:
1,随机数3(pre-master key,此随机数用服务器公钥加密,防止被窃听)
2,编码改变通知(表示随后的信息都将用双方商定的方法和密钥发送)
3,客户端握手结束通知

五、双方生成会话密钥

双方同时有了三个随机数,接着就用事先商定的加密方法,各自生成同一把“会话密钥”
服务器端用自己的私钥(非对称加密的)获取第三个随机数,会计算生成本次所用的会话密钥(对称加密的密钥),如果前一步要求客户端证书,会在这一步验证

六、服务器最后响应

服务器生成会话密钥后,向客户端发送:
1,编码改变通知(后面的信息都用双方的加密方法和密钥来发送)
2,服务器握手结束通知

至此,握手阶段全部结束,接下来客户端与服务器进入加密通信,用会话密钥加密内容

4. tcp三次握手与四次挥手
三次握手

四次挥手

这里写图片描述

5. osi七层协议模型与TCP/IP四层模型

这里写图片描述

6. hashCode()与equals()的区别
7. jvm内存分配
8. jvm GC ROOTS对象种类
9. 算法题:你和两一个人,一同取100根火柴,两个人每次可以取1-2根火柴,如何保证最后一个取火柴的人是你自己?
答:自己先拿一根,剩余99根火柴,另一个人先拿,自己再拿,保证自己与他拿的火柴总数为3,99=33*3,这样在最后剩余三根火柴的时候还是他先拿,不管他拿1根还是2根,自己都是最后一个拿火柴的人。
10.堆排序
堆是一种重要的数据结构,为一棵完全二叉树, 底层如果用数组存储数据的话,假设某个元素为序号为i(Java数组从0开始,i为0到n-1),如果它有左子树,那么左子树的位置是2i+1,如果有右子树,右子树的位置是2i+2,如果有父节点,父节点的位置是(n-1)/2取整。分为最大堆和最小堆,最大堆的任意子树根节点不小于任意子结点,最小堆的根节点不大于任意子结点。所谓堆排序就是利用堆这种数据结构来对数组排序,我们使用的是最大堆。处理的思想和冒泡排序,选择排序非常的类似,一层层封顶,只是最大元素的选取使用了最大堆。最大堆的最大元素一定在第0位置,构建好堆之后,交换0位置元素与顶即可。堆排序为原位排序(空间小), 且最坏运行时间是O(nlgn),是渐进最优的比较排序算法。

堆排序的大概步骤如下:
(1)构建最大堆。
(2)选择顶,并与第0位置元素交换
由于步骤2的的交换可能破环了最大堆的性质,第0不再是最大元素,需要调用maxHeap调整堆(沉降法),如果需要重复步骤2
堆排序中最重要的算法就是maxHeap,该函数假设一个元素的两个子节点都满足最大堆的性质(左右子树都是最大堆),只有跟元素可能违反最大堆性质,那么把该元素以及左右子节点的最大元素找出来,如果该元素已经最大,那么整棵树都是最大堆,程序退出,否则交换跟元素与最大元素的位置,继续调用maxHeap原最大元素所在的子树。该算法是分治法的典型应用。具体代码如下:

public void HeapAdjust(int[] array, int parent, int length) {  

    int temp = array[parent]; // temp保存当前父节点  
    int child = 2 * parent + 1; // 先获得左孩子  

    while (child < length) {  
        // 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点    
        if (child + 1 < length && array[child] < array[child + 1]) {  
              child++;    
        }  

        // 如果父结点的值已经大于孩子结点的值,则直接结束  
        if (temp >= array[child])  
            break;  

        // 把孩子结点的值赋给父结点  
        array[parent] = array[child];  

        // 选取孩子结点的左孩子结点,继续向下筛选  
        parent = child;  
        child = 2 * child + 1;  
    }  
    array[parent] = temp;  
}  

public void heapSort(int[] list) {  

    // 循环建立初始堆  
    for (int i = list.length / 2; i >= 0; i--) {  
        HeapAdjust(list, i, list.length - 1);  
    }  

    // 进行n-1次循环,完成排序  
    for (int i = list.length - 1; i > 0; i--) {  

        // 最后一个元素和第一元素进行交换  
        int temp = list[i];  
        list[i] = list[0];  
        list[0] = temp;  

        // 筛选 R[0] 结点,得到i-1个结点的堆  
        HeapAdjust(list, 0, i);  
        System.out.format("第 %d 趟: \t", list.length - i);  
        printPart(list, 0, list.length - 1);  
    }  
}  

11. 计算n个数组的笛卡尔积

private List<List<Object>> combineAlg(List<Object[]> nArray) {  
    List<List<Object>> values = new LinkedList<List<Object>>();  
    int[] x = new int[nArray.size()];  
    for (int i = 0; i < x.length; i++) {  
        x[i] = 0;  
    }  

    int flag = 0;  
    do {  
        /**一种组合形式**/  
        List<Object> objs = new LinkedList<Object>();  
        for (int looper = 0; looper < nArray.size(); looper++) {  
            objs.add(nArray.get(looper)[x[looper]]);  
        }  
        flag = NextPermutation(x, nArray);  
        values.add(objs);  
    } while (flag != 1);  
    /**所有组合形式**/  
    return values;  
}  

private int NextPermutation(int[] x, List<Object[]> nArray) {  
    int carry = 0;  
    for (int looper = nArray.size() - 1; looper >= 0; looper--) {  
        if (x[looper] + 1 == nArray.get(looper).length) {  
            carry = 1;  
            x[looper] = 0;  
        } else {  
            x[looper] = x[looper] + 1;  
            carry = 0;  
            return 0;  
        }  
    }  

    if (carry == 1)  
        return 1;  
    else  
        return 0;  
}  

12. 使用一个不规则的硬币(正面概率为P,反面概率为1-P),构造一个0.5概率的事件
答:每次连续扔硬币两次,如果两次的结果相同,则丢弃这个结果,重新扔,这样剩下的两个事件为:正反和反正,将这两个事件作为两个概率相等且为0.5的事件。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值