实习投递记录

实习投递记录


4.18 腾讯笔试

五道题AC率:0,0.6,0,0.9,0

4.23查看官网显示笔试通过,等待初试(面试)

但是这之前我进行了一个操作,就是把简历上的“城市服从调剂”改为了“是”,然后又改回了“否”,再次刷新的时候发现进初试了。


3.6 腾讯提前批面试

1.讲一讲synchronized和可重入锁的区别,synchronized是可重入锁吗?可重入锁的概念?

不可重入锁:

自己这个方法占用了锁以后,在这个方法内部还有一些操作,需要用到这个锁,但是因为这个锁已经被自己拿了,所以自己内部的这些操作就无法获得这个锁。

可重入锁就是,当发生上面这种情况的时候,可以继续执行下去,并且让count++,每次上锁的时候,判断一下当前这个资源被谁拿着,如果是被自己拿着,那就不用wait,如果不是被自己拿着,才wait。当解锁的时候,判断count是不是为0,如果不是的话则count–,否则notify,告诉别的线程,可以来拿这个资源了。

**于是,可重入就意味着:线程可以进入任何一个它已经拥有的锁所同步着的代码块。**所以可重入锁也叫做递归锁。

synchronize是可重入锁。

区别:

  1. synchronize是依赖于JVM的,ReenTrantLock是JDK实现的。在Synchronized优化以前,synchronized的性能是比ReenTrantLock差很多的,但是自从Synchronized引入了偏向锁,轻量级锁(自旋锁)后,两者的性能就差不多了,在两种方法都可用的情况下,官方甚至建议使用synchronized,其实synchronized的优化我感觉就借鉴了ReenTrantLock中的CAS技术。都是试图在用户态就把加锁问题解决,避免进入内核态的线程阻塞。

  2. ReenTrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。

  3. ReenTrantLock提供了一个Condition(条件)类,用来实现分组唤醒需要唤醒的线程们,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程。

  4. ReenTrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly()来实现这个机制。

    synchronized是不可中断锁,Lock实现的都是可中断锁

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QIgn4CpF-1625065729000)(/Users/shenhangran/Desktop/学习笔记/我的/实习投递记录.assets/image-20210424161302900.png)]

锁的一种宏观分类方式是悲观锁乐观锁。悲观锁与乐观锁并不是特指某个锁(Java中没有哪个Lock实现类就叫PessimisticLock或OptimisticLock),而是在并发情况下的两种不同策略。

悲观锁(Pessimistic Lock), 就是很悲观,每次去拿数据的时候都认为别人会修改。所以每次在拿数据的时候都会上锁。这样别人想拿数据就被挡住,直到悲观锁被释放。

乐观锁(Optimistic Lock), 就是很乐观,每次去拿数据的时候都认为别人不会修改。所以不会上锁,不会上锁!但是如果想要更新数据,则会在更新前检查在读取至更新这段时间别人有没有修改过这个数据。如果修改过,则重新读取,再次尝试更新,循环上述步骤直到更新成功(当然也允许更新失败的线程放弃操作)。

悲观锁阻塞事务,乐观锁回滚重试,它们各有优缺点,不要认为一种一定好于另一种。像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行重试,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。

乐观锁的基础:CAS(compare and set 比较并替换)

  1. 比较:读取到了一个值A,在将其更新为B之前,检查原值是否仍为A(未被其他线程改动)。

  2. 设置:如果是,将A更新为B,结束。如果不是,则什么都不做。

上面的两步操作是原子性的,可以简单地理解为瞬间完成,在CPU看来就是一步操作。

整个过程中并没有“加锁”和“解锁”操作,因此乐观锁策略也被称为无锁编程。换句话说,乐观锁其实不是“锁”,它仅仅是一个循环重试CAS的算法而已!

有一种锁叫自旋锁。所谓自旋,说白了就是一个 while(true) 无限循环。

乐观锁不是自旋锁,尽管他们的操作是一样的。“自旋”这两个字,特指自旋锁的自旋。

synchronized锁升级:偏向锁 → 轻量级锁 → 重量级锁

详见:https://zhuanlan.zhihu.com/p/71156910

前面提到,synchronized关键字就像是汽车的自动档,现在详细讲这个过程。一脚油门踩下去,synchronized会从无锁升级为偏向锁,再升级为轻量级锁,最后升级为重量级锁,就像自动换挡一样。那么自旋锁在哪里呢?这里的轻量级锁就是一种自旋锁

初次执行到synchronized代码块的时候,锁对象变成偏向锁(通过CAS修改对象头里的锁标志位),字面意思是“偏向于第一个获得它的线程”的锁。执行完同步代码块后,线程并不会主动释放偏向锁。当第二次到达同步代码块时,线程会判断此时持有锁的线程是否就是自己(持有锁的线程ID也在对象头里),如果是则正常往下执行。**由于之前没有释放锁,这里也就不需要重新加锁。**如果自始至终使用锁的线程只有一个,很明显偏向锁几乎没有额外开销,性能极高。

一旦有第二个线程加入锁竞争,偏向锁就升级为轻量级锁(自旋锁)。这里要明确一下什么是锁竞争:如果多个线程轮流获取一个锁,但是每次获取锁的时候都很顺利,没有发生阻塞,那么就不存在锁竞争。只有当某线程尝试获取锁的时候,发现该锁已经被占用,只能等待其释放,这才发生了锁竞争。

在轻量级锁状态下继续锁竞争,没有抢到锁的线程将自旋,即不停地循环判断锁是否能够被成功获取。获取锁的操作,其实就是通过CAS修改对象头里的锁标志位。先比较当前锁标志位是否为“释放”,如果是则将其设置为“锁定”,比较并设置是原子性发生的。这就算抢到锁了,然后线程将当前锁的持有者信息修改为自己。

长时间的自旋操作是非常消耗资源的,一个线程持有锁,其他线程就只能在原地空耗CPU,执行不了任何有效的任务,这种现象叫做忙等(busy-waiting)。如果多个线程用一个锁,但是没有发生锁竞争,或者发生了很轻微的锁竞争,那么synchronized就用轻量级锁,允许短时间的忙等现象。这是一种折衷的想法,短时间的忙等,换取线程在用户态和内核态之间切换的开销。

显然,此忙等是有限度的(有个计数器记录自旋次数,默认允许循环10次,可以通过虚拟机参数更改)。如果锁竞争情况严重,某个达到最大自旋次数的线程,会将轻量级锁升级为重量级锁(依然是CAS修改锁标志位,但不修改持有锁的线程ID)。当后续线程尝试获取锁时,发现被占用的锁是重量级锁,则直接将自己挂起(而不是忙等),等待将来被唤醒。在JDK1.6之前,synchronized直接加重量级锁,很明显现在得到了很好的优化。

一个锁只能按照 偏向锁、轻量级锁、重量级锁的顺序逐渐升级(也有叫锁膨胀的),不允许降级。


2.进程和线程的关系?进程之间的通信?管道了解过吗?

  • 进程是资源分配的基本单位、线程是调度的基本单位
  • 一个进程可包含多个线程
  • 线程又称轻量级进程:进程间切换代价大,线程间切换代价小
  • 进程有独立的资源,如内存空间,IO资源等,进程中线程共享这些资源
进程间通信常用有4种方式
  1. 管道

管道是一种具有两个端点的通信通道,一个管道实际上就是一种特殊的独立的文件系统,是一个只存在于内存的文件。它有自己的数据结构,它的两端是两个已经打开的文件。

1) 无名管道

无名管道用于父进程和子进程之间,通常父进程创建管道,然后由通信的子进程继承父进程的读端点句柄和写端点句柄,或者父进程有读写句柄的子进程,这些子进程可以使用管道直接通信,不需要通过父进程。
当父进程通过fork创建子进程后,父子进程都拥有对管道操作的文件描述符,此时父子进程关闭对应的读写端,使父子进程间形成单向的管道。关闭哪个端要根据具体的数据流向决定。

2) 命名管道

命名管道是建立在实际的磁盘介质或文件系统(而不是只存在内存中),任何进程可以通过文件名或路径建立与该文件的联系

  1. 事件/信号

信号,用于向进程通知发生异步事件的机制。类似于中断。 内核、进程都可以发送信号, 一次只给进程一个信号,不排队。

我目前理解的这一点,就和线程的通信差不多,不知道对不对。

  1. 消息队列

消息队列是消息(有类型的一段文本)的链表,每个进程都有一个与之关联的消息队列,消息队列类似于邮箱,有权限的进程可以向消息队列中添加消息,有读权限的进程可以读走消息队列的消息。

消息队列克服了信号承载信息量少,管道只能承载无格式字节流及缓冲区大小受限等缺陷。

管道和消息队列的区别

消息队列和管道的区别主要有以下两点:

  1. 一个进程向消息队列写入消息之前,并不需要某个进程在该队列上等待该消息的到达,而管道和FIFO是相反的,进程向其中写消息时,管道和FIFO必需已经打开来读,否则写进程就会阻塞(默认情况下)。
  2. IPC的持续性不同。管道和FIFO是随进程的持续性,当管道和FIFO最后一次关闭发生时,仍在管道和FIFO中的数据会被丢弃。消息队列是随内核的持续性,即一个进程向消息队列写入消息后,然后终止,另外一个进程可以在以后某个时刻打开该队列读取消息。只要内核没有重新自举,消息队列没有被删除。
  1. 共享内存

管道,命名管道,消息队列。它们的共同点都是通过内核来进行通信。写入数据时,需要把数据从用户空间(用户进程)复制到内核,而从这些IPC读取数据时,又需要把数据从内核复制到用户空间。
共享内存使用方式是将同一个内存区映射到共享它的不同进程的地址空间中,这样这些进程间的通信就不再需要通过内核,只需对该共享的内存区域进程操作就可以了。
共享内存是最快的IPC形式,是针对其他通信方式运行效率低而设计的,往往与其他进程通信方式结合使用,如与信号量结合,来达到进程间的同步与互斥。传递文件最好用共享内存的方式。

临界区与互斥量的区别

互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量 。因为互斥量是跨进程的互斥量一旦被创建,就可以通过名字打开它。


3.讲一讲JVM,java内存什么样的,四种GC,青年区,Eden区 from区;to区一定是空的吗?

详见JVM笔记


4.池化技术有了解过吗?不要只局限于使用,池化技术的原理和本质是什么?

池化技术的核心思想就是:空间换时间,事先准备好一定的对象来减少频繁创建对象的性能开销。比如链接数据库,如果每次操作都先链接数据库,那太麻烦了,不如把这部分代码写到公共类里,并实现创建一个Connection对象,一直处于连接状态,随时可以用.


5.TCP为什么要三次握手,两次握手不行吗?为什么两次握手不能保证可靠性?

  • 第一次握手:服务器收到客户端发送的请求,证明了服务器可以接受。此时服务器不知道是哪个客户端发来的请求,必须解析报文才能知道。
  • 第二次握手:服务器给目标客户端返送一个请求,需要等待客户端回复,才能证明服务器具有发送功能并且成功发送
  • 第三次握手:客户端回复服务器,此时证明了第二次握手的时候,服务器成功给客户端发送了请求,并且客户端成功的收到了。

6.网络四层模型了解过吗?网络层在上还是传输层在上?IP在哪一层?接口在哪一层?

  • 数据链路层
  • 网络层
  • 传输层
  • 应用层

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EmMLfoDg-1625065729003)(/Users/shenhangran/Desktop/学习笔记/我的/实习投递记录.assets/image-20210424163607930.png)]

  1. 数据链路层实现了网卡接口的网络驱动程序,以处理数据在物理媒介(比如以太网、令牌环等)上的传输。

  2. 网络层实现数据包的选路和转发。

网络层最核心的协议是IP协议(Internet Protocol,因特网协议)。IP协议根据数据包的目的IP地址来决定如何投递它。如果数据包不能直接发送给目标主机,那么IP协议就为它寻找一个合适的下一跳(next hop)路由器,并将数据包交付给该路由器来转发。多次重复这一过程,数据包最终到达目标主机,或者由于发送失败而被丢弃。可见,IP协议使用逐跳(hop by hop)的方式确定通信路径。

网络层另外一个重要的协议是ICMP协议(Internet Control Message Protocol,因特网控制报文协议)。它是IP协议的重要补充,主要用于检测网络连接。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rRZLdcJs-1625065729004)(/Users/shenhangran/Desktop/学习笔记/我的/实习投递记录.assets/image-20210424163818327.png)]

  1. 传输层为两台主机上的应用程序提供端到端(end to end)的通信。与网络层使用的逐跳通信方式不同,传输层只关心通信的起始端和目的端,而不在乎数据包的中转过程。

TCP服务是基于流的。基于流的数据没有边界(长度)限制,它源源不断地从通信的一端流入另一端。发送端可以逐个字节地向数据流中写入数据,接收端也可以逐个字节地将它们读出。

UDP协议是无连接的,即通信双方不保持一个长久的联系,因此应用程序每次发送数据都要明确指定接收端的地址(IP地址等信息)。基于数据报的服务,是相对基于流的服务而言的。每个UDP数据报都有一个长度,接收端必须以该长度为最小单位将其所有内容一次性读出,否则数据将被截断。

  1. 应用层负责处理应用程序的逻辑。

ping是应用程序,而不是协议,前面说过它利用ICMP报文检测网络连接,是调试网络环境的必备工具。

telnet协议是一种远程登录协议,它使我们能在本地完成远程任务。

DNS(Domain Name Service,域名服务)协议提供机器域名到IP地址的转换。

OSPF(Open Shortest Path First,开放最短路径优先)协议是一种动态路由更新协议,用于路由器之间的通信,以告知对方各自的路由信息。

总结:

五层协议背后的思想:上层屏蔽下层细节,只使用其提供的服务。高内聚低耦合,每一层专注于其功能,各层之间的关系依赖不大。

数据包在每层有不同的格式,从上到下依次叫段,数据报,帧,数据从应用层通过协议栈向下传递,每经过一层加上对应层协议的报头,最后封装成帧发送到传输介质上,到达路由器或者目的主机剥掉头部,交付给上层需要者。这一过程称为封装,传输,分离,分用。


7.数据结构学过吗?B+树和二叉树的区别?B+树和B-树的区别?为什么B+树可以存放很多数据?

详见数据库笔记。

数据库用B+树,不用B树,是因为B树不管叶子节点还是非叶子节点,都会保存数据,这样导致在非叶子节点中能保存的指针数量变少(有些资料也称为扇出),指针少的情况下要保存大量数据,只能增加树的高度,导致IO操作变多,查询性能变低;

InnoDB一棵B+树可以存放多少行数据?这个问题的简单回答是:约2千万。这是可以算出来的。

在计算机中磁盘存储数据最小单元是扇区,一个扇区的大小是512字节,而文件系统(例如XFS/EXT4)他的最小单元是块,一个块的大小是4k,而对于我们的InnoDB存储引擎也有自己的最小储存单元——页(Page),一个页的大小是16K。

8.数组和链表讲一讲吧

9.HashMap用过吗?hash是怎么实现的?冲突如何解决?为什么要用红黑树?

HashMap非线程安全,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用 Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap。

Hashtable是遗留类,很多映射的常用功能与HashMap类似,不同的是它承自Dictionary类,并且是线程安全的,任一时间只有一个线程能写Hashtable,并发性不如ConcurrentHashMap,因为ConcurrentHashMap引入了分段锁。Hashtable不建议在新代码中使用,不需要线程安全的场合可以用HashMap替换,需要线程安全的场合可以用ConcurrentHashMap替换。

LinkedHashMap是HashMap的一个子类,保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的,也可以在构造时带参数,按照访问次序排序。

TreeMap实现SortedMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。如果使用排序的映射,建议使用TreeMap。在使用TreeMap时,key必须实现Comparable接口或者在构造TreeMap传入自定义的Comparator,否则会在运行时抛出java.lang.ClassCastException类型的异常。

https://blog.csdn.net/weixin_44547562/article/details/107130609


4.26 腾讯一面

30分钟

TIB平台

1、介绍一下项目

遇到反爬虫机制了吗?——没遇到,B站开个大会员就行了

你说你用的正则,那你怎么从html标签里获取字段——用的beautiful soup

2、操作系统了解过吗?讲一讲Linux里什么什么什么(三个问题,都没听懂)

3、数据库了解过吗?

为什么用B+树不能用B树?

都有什么索引?

聚簇索引和非聚簇索引

INNODB和MYASIM区别

4、算法

外部排序 —— 说了思路

力扣435 无重叠空间(DP)——没做出来

反问:

我这次的表现?

面试官:操作系统比较薄弱,数据库答的很好,算法题没做出来,有点可惜


4.23 字节电话

还没在官网投过简历,只是在boss上发了简历

接到电话,介绍部门:

描述:data 核心部门 基础架构 比较底层 对接其他部门

问了实习时间:我说6月到9月的暑期实习

我:需要到官网投简历吗?

hr:我们这边先会给您做一个评估,如果简历评估过关的,会打电话邀请您。

4.16 阿里笔试

两道题,一到简单的50分,一道困难的50分,简单的暴力A了,还没有面试消息。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值