《关于我的那些面经》——百度后端(附答案)

示例 1:

输入:head = [3,2,0,-4], pos = 1

输出:true

解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1], pos = -1

输出:false

解释:链表中没有环。

进阶:

你能用 O(1)(即,常量)内存解决此问题吗?

思路:首先我们要明白,链表不可能出现这种情况:

因为一个结点只有一个指针,所以链表只可能向实例一那样,在末尾出现一个环。

慢指针一次一步,快指针一次两步。能相遇就是有环,反之没有环。就像操场跑步,跑的快的总有一天可以追慢的一圈,相遇。

/**

  • Definition for singly-linked list.

  • class ListNode {

  • int val;
    
  • ListNode next;
    
  • ListNode(int x) {
    
  •     val = x;
    
  •     next = null;
    
  • }
    
  • }

*/

public class Solution {

public boolean hasCycle(ListNode head) {

if (head == null || head.next == null) {

return false;

}

ListNode slow = head;

ListNode fast = head.next;

while (slow != fast) {

if (fast == null || fast.next == null) {

return false;

}

slow = slow.next;

fast = fast.next.next;

}

return true;

}

}

那么,这对于懂算法的人来说可能是烂大街的问题,有些人可能不屑于看了,那么,第二个问题来了:如果让那个快指针一次走三步,还能不能做正确的答案呢?一次四步呢?五步呢?

如果看的人多,我会在下一期公布答案哈哈,大家不要以为应试被题就可以过关。

2)介绍一下堆这种数据结构

大根堆要求

①根节点的关键字既大于或等于左子树的关键字值,又大于或等于右子树的关键字值。

②为完全二叉树

注意这是递归定义的。

对于大根小根堆,递归定义,实现,空间复杂度,各种操作的时间复杂度,真实写二叉树的情况和数组模拟的情况都要会。

有人要问了,会这些算法有啥用?其实Java的优先队列就是堆结构。八大排序之一的堆排序也是数组上堆结构,面试官让我手动实现一个,以下是实现。

/*

================================================

功能:堆排序

输入:数组名称(也就是数组首地址)、数组中元素个数

注:画画

================================================

*/

/*

功能:建堆

输入:数组名称(也就是数组首地址)、参与建堆元素的个数、从第几个元素开始

*/

void sift(int *x, int n, int s)

{

int t, k, j;

t = *(x+s); /暂存开始元素/

k = s; /开始元素下标/

j = 2*k + 1; /左子树元素下标/

while (j<n)

{

if (j<n-1 && *(x+j) < *(x+j+1))/判断是否存在右孩子,并且右孩子比左孩子大,成立,就把j换为右孩子/

{

j++;

}

if (t<*(x+j)) /调整/

{

*(x+k) = *(x+j);

k = j; /调整后,开始元素也随之调整/

j = 2*k + 1;

}

else /没有需要调整了,已经是个堆了,退出循环。/

{

break;

}

}

*(x+k) = t; /开始元素放到它正确位置/

}

/*

功能:堆排序

输入:数组名称(也就是数组首地址)、数组中元素个数

注:

  • *
    

建堆时,从从后往前第一个非叶子节点开始调整,也就是“-”符号的位置

*/

void heap_sort(int *x, int n)

{

int i, k, t;

//int *p;

for (i=n/2-1; i>=0; i–)

{

sift(x,n,i); /初始建堆/

}

for (k=n-1; k>=1; k–)

{

t = *(x+0); /堆顶放到最后/

*(x+0) = *(x+k);

*(x+k) = t;

sift(x,k,0); /剩下的数再建堆/

}

}

3)排序知道哪些?来介绍介绍?

答:全知道,全会写,然后只说了冒泡的所有思路和优化、和快排BFPRT就被叫停了。我就把所有排序介绍和实现分享给大家。

全排序

一面结束,面试小哥表示对我很满意,说马上让另外一个人二面。

二面:

二面小哥说,一面说你算法贼强,咱们这次就不聊算法了,说说项目。

4)看我项目里用了redis,就问redis都有哪些数据结构。

我说有string、list、hash、set、zset。

问:你说的这些Java以及其他语言基本也都有,你说了解redis,那这些数据结构到底是不是快?咋实现的呢?

我举例子说了一下:

  • 1) 字符串

redis并未使用传统的c语言字符串表示,它自己构建了一种简单的动态字符串抽象类型。

当需要一个可以被修改的字符串时,redis就会使用自己实现的SDS(simple dynamic string)。比如在redis数据库里,包含字符串的键值对底层都是SDS实现的,不止如此,SDS还被用作缓冲区(buffer):比如AOF模块中的AOF缓冲区以及客户端状态中的输入缓冲区。

下面来具体看一下sds的实现:

  1. struct sdshdr

  2. {

  3. int len;//buf已使用字节数量(保存的字符串长度)

  4. int free;//未使用的字节数量

  5. char buf[];//用来保存字符串的字节数组

  6. };

sds遵循c中字符串以’\0’结尾的惯例,这一字节的空间不算在len之内。

这样的好处是,我们可以直接重用c中的一部分函数。比如printf;

sds相对c的改进

获取长度:c字符串并不记录自身长度,所以获取长度只能遍历一遍字符串,redis直接读取len即可。

缓冲区安全:c字符串容易造成缓冲区溢出,比如:程序员没有分配足够的空间就执行拼接操作。而redis会先检查sds的空间是否满足所需要求,如果不满足会自动扩充。

内存分配:由于c不记录字符串长度,对于包含了n个字符的字符串,底层总是一个长度n+1的数组,每一次长度变化,总是要对这个数组进行一次内存重新分配的操作。因为内存分配涉及复杂算法并且可能需要执行系统调用,所以它通常是比较耗时的操作。   
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

如何快速更新自己的技术积累?

  • 在现有的项目里,深挖技术,比如用到netty可以把相关底层代码和要点都看起来。
  • 如果不知道目前的努力方向,就看自己的领导或公司里技术强的人在学什么。
  • 知道努力方向后不知道该怎么学,就到处去找相关资料然后练习。
  • 学习以后不知道有没有学成,则可以通过面试去检验。

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目

八年CRUD,疫情备战三个月,三面头条、四面阿里拿offer面经分享

八年CRUD,疫情备战三个月,三面头条、四面阿里拿offer面经分享

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
学什么。

  • 知道努力方向后不知道该怎么学,就到处去找相关资料然后练习。
  • 学习以后不知道有没有学成,则可以通过面试去检验。

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目

[外链图片转存中…(img-wxQV4dl3-1712698340086)]

[外链图片转存中…(img-YJyKo5yW-1712698340086)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 27
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《java面经-百度准入职老哥整理.pdf》是一份关于百度准入职面试的Java面经整理。这份面经是由百度准入职的老哥整理而成,其中记录了一些面试时可能会遇到的问题以及解答方法。 这份面经对于准备参加百度准入职面试的人来说非常有价值。首先,它列出了一些常见的面试问题,涵盖了Java语言的各个方面,包括基础知识、数据结构与算法、设计模式、多线程、网络编程等等。通过仔细研究和复习这些问题的答案,可以帮助面试者全面了解Java语言的特性和应用。 其次,这份面经还提供了问题的解答思路和方法,帮助面试者理清思路,正确回答问题。这对于很多面试者来说特别有帮助,因为在面试时有时会遇到一些棘手的问题,有了这份面经的指导,面试者可以更好地掌握应对策略。 不过需要注意的是,面经作为一份参考资料,不能完全依赖于它来准备面试。面试官可能会问一些不在面经中列出的问题,因此考生还是需要自己对Java语言有充分的了解,并能够熟练运用。同时,面试官还会关注考生的沟通能力、解决问题的能力以及对新技术的学习和掌握能力。 总体来说,《java面经-百度准入职老哥整理.pdf》是一份非常宝贵的资料,可以帮助面试者对Java面试中可能会遇到的问题有更深入的了解,提供了解答思路和方法。但记住,面试准备还需要多方面的知识积累和实践经验的积累,才能在面试中展现自己的优势。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值