大家好,我是白露,全栈开发。

OpenAI 发布GPT-4o的消息又双叒刷屏了。

大家都在说它多好用、多先进的时候……我反问了一句:谁造就了它?


细数整个GPT爆火的背后,都离不开OpenAI 的CEO——Sam Altman,网友亲切的称之为“奥特曼”。

我们直接来看看这位大佬的简历吧:

5.16 8岁编程,20岁创业:GPT创始人的Sam Altman的简历。。。 - 图1

20岁辍学创业

据说,奥特曼从8岁就自学编程,20岁从斯坦福辍学创业,可以说是硅谷传奇人物的模板了。

许多人都将其和比尔盖茨、马斯克等大佬并列。

Altman的故事始于他对互联网时代的渴望:“我无法忍受互联网时代到来,自己却置身事外。

这股冲劲促使他离开校园,投身创业的浪潮。

26岁时,他卖掉了自己的公司,实现了财务自由。

29岁时,他成为美国最大创业孵化器Y Combinator(简称YC)的掌门人,并在短短五年内将YC的规模扩大了十倍。

而后,2024年3月,他作为CEO推出的ChatGPT-3.5,震动全世界。

“董事风波”

然而,真正让人记住Altman的,却是他个人经历中那段几近疯狂的日子。

2023年秋末,OpenAI 的一场”宫斗”,Altman在一周之内经历了被解雇与被恢复CEO职位的跌宕起伏。

最后他凭借卓越的领导力在48小时内再次回归OpenAI,这比乔布斯重返苹果的历程更显戏剧性。

有人戏称:“乔布斯重返苹果花了12年,而Altman重返OpenAI只用了48小时。”

YC创始人保罗·格雷厄姆对他说:“你可以把他扔到一个满是食人者的岛上,五年后回来,他就会成为那里的国王。


作为国内 AI 的领头羊,百度在GPT爆火之后马上推出来了自己的大模型文心一言,从而拉起了国产大模型自研的大旗。

接下来,我们就回归正题,来看一次百度的面试吧。

面试开始

面试官: 你好,欢迎来到百度大模型平台后端实习生的面试。首先,请你进行一下自我介绍。

求职者: 您好,我是XXX,目前就读于XXX大学,专业是XXX。我对后端开发和大数据处理非常感兴趣。

在校期间,我积极参与ACM竞赛,并且有过相关的实习经验,比如在腾讯实习期间,我参与了一个大模型平台的后端开发工作。我热衷于解决技术难题,并且乐于在团队中合作。

面试官: 很好,能具体介绍一下你的ACM竞赛经历吗?

求职者: 当然可以。我在大二时加入了我们学校的ACM团队,(* 省略500字)。

面试官: 你有优化Prompt的经验吗?如果有,请分享一下。

求职者: 是的,我在实习项目中遇到了一个挑战,即如何优化自然语言处理模型的Prompt以获得更好的性能,主要可以按照下面的步骤进行:

明确目标:在设计Prompt之前,明确你想要模型完成的任务或回答的问题类型。

简洁明了:尽量使Prompt简洁,避免冗长和复杂,这样模型更容易理解。

上下文信息:提供足够的上下文信息,帮助模型更好地理解问题背景。

使用示例:如果可能,提供一个或多个示例来说明你想要的答案格式或内容。

避免歧义:确保Prompt中的语言清晰,避免可能导致误解的模糊表述。

反馈迭代:根据模型的响应调整Prompt,不断迭代以提高效果。 测试验证:在不同的数据集上测试Prompt,确保其有效性和鲁棒性。

面试官: 好的,那大模型微调SFT的优化方法你了解吗?

求职者: 对于大模型的微调,Sparse Fine-Tuning (SFT) 是一个有效的策略。

我的优化方法主要是通过识别和优化模型中对最终性能影响最大的参数。 我尝试了几种不同的稀疏化策略,例如基于梯度和权重的稀疏化,以及利用知识蒸馏来进一步提升微调后模型的性能。

面试官: 我们来换个话题,你能介绍一下Raft协议吗?

求职者: 当然。Raft协议是一种一致性算法,它和Paxos算法一样,用于管理一个分布式系统中的一致性。

Raft通过一个更加直观和易于理解的方式来实现这一目的。 Raft将一致性问题分解为几个子问题:领导者选举、日志复制和安全性。 它通过选举出一个领导者,然后由领导者来管理日志条目的复制过程,并确保所有的副本最终都是一致的。

面试官: 在Raft协议中,如果出现网络故障导致分区,如何解决任期号一直增加的问题?

求职者: 在Raft协议中,如果网络分区导致了节点的隔离,各个分区内可能会独立进行领导者选举,导致任期号增加。Raft通过要求多数节点的投票来解决这个问题。

一个节点如果想成为领导者,它需要获得集群中大多数节点的投票。 如果网络分区导致没有单个节点能够获得大多数投票,那么选举将会失败,任期号不会继续增加。 一旦网络恢复,节点会重新同步日志,并且最终整个集群会达成一致。

面试官: 非常详细。接下来,你能介绍一下计算机网络的5层模型吗?

求职者: 计算机网络的5层模型包括应用层、传输层、网络层、数据链路层和物理层

应用层负责处理特定的应用程序细节。 传输层负责为两台计算机上的应用程序提供端到端的通信。 网络层处理数据包在网络中的活动,包括路由选择。 数据链路层在相邻的网络节点之间传送数据帧,负责错误检测和纠正。物理层涉及通过物理媒介传输原始的比特流。

面试官: 那么,TCP/IP属于哪一层?

求职者: TCP/IP协议主要工作在传输层。

TCP(传输控制协议)负责提供可靠的、面向连接的通信服务。 IP(网际协议)则工作在网络层,负责数据包的路由选择。

面试官: 能介绍一下WebSocket协议吗?

求职者: WebSocket是一种在单个TCP连接上进行全双工通信的协议。

它使得客户端和服务器之间的数据交换变得更简单,支持从客户端到服务器的持续性连接。 WebSocket在应用层初始化,但是在建立连接后,它通过一个特定的升级握手转换为WebSocket协议。 这使得它非常适合需要实时数据传输的应用场景,如在线游戏、聊天应用等。

面试官: 了解了WebSocket协议后,我们来聊聊编程语言方面的知识。请你介绍一下C++中的智能指针。

求职者: 在C++中,智能指针是用来管理动态分配(即使用<font style="color:rgb(46, 50, 56);">new</font>操作符分配)的内存的对象。

主要有三种智能指针:<font style="color:rgb(46, 50, 56);">std::unique_ptr</font><font style="color:rgb(46, 50, 56);">std::shared_ptr</font><font style="color:rgb(46, 50, 56);">std::weak_ptr</font>

<font style="color:rgb(46, 50, 56);">std::unique_ptr</font>是一个独占所有权的智能指针,它保证同一时间内只有一个智能指针指向一个特定的资源。

<font style="color:rgb(46, 50, 56);">std::shared_ptr</font>是引用计数类型的智能指针,允许多个<font style="color:rgb(46, 50, 56);">std::shared_ptr</font>实例共同拥有同一个资源,资源在最后一个引用被销毁时才会被释放。

<font style="color:rgb(46, 50, 56);">std::weak_ptr</font>是为了解决<font style="color:rgb(46, 50, 56);">std::shared_ptr</font>可能导致的循环引用问题而设计的,它指向一个由<font style="color:rgb(46, 50, 56);">std::shared_ptr</font>管理的对象,但不会增加引用计数。

面试官: 很好,那么智能指针内部的实现思路是什么?

求职者: 智能指针内部通常通过一个指向动态分配内存的原始指针来实现。

对于<font style="color:rgb(46, 50, 56);">std::shared_ptr</font>,内部还会有一个引用计数器,每当有新的<font style="color:rgb(46, 50, 56);">std::shared_ptr</font>指向相同的资源时,引用计数会增加;当<font style="color:rgb(46, 50, 56);">std::shared_ptr</font>被销毁或者重新指向另一个资源时,引用计数会减少。 当引用计数减到0时,资源会被自动释放。<font style="color:rgb(46, 50, 56);">std::unique_ptr</font>相对简单,它直接拥有资源,不需要引用计数,但提供了移动语义来转移资源的所有权。<font style="color:rgb(46, 50, 56);">std::weak_ptr</font>则通过一个观察指针来观察资源,但不增加引用计数,防止循环引用。

面试官: 那么,在C++中多态是如何实现的?

求职者: 在C++中,多态主要通过虚函数来实现。当一个类中有虚函数时,编译器会为这个类生成一个虚函数表(vtable),其中包含了虚函数的地址。

每个对象都会有一个指向其类的虚函数表的指针。当通过基类指针或引用调用虚函数时,运行时会根据对象的实际类型来从虚函数表中查找并调用对应的函数,实现了运行时多态。

面试官: C++中优先队列的底层数据结构是什么?

求职者: C++中的优先队列是基于堆(heap)数据结构实现的,通常是一个二叉堆。在标准库中,<font style="color:rgb(46, 50, 56);">std::priority_queue</font>默认使用<font style="color:rgb(46, 50, 56);">std::vector</font>作为容器,并利用<font style="color:rgb(46, 50, 56);">std::make_heap</font><font style="color:rgb(46, 50, 56);">std::push_heap</font><font style="color:rgb(46, 50, 56);">std::pop_heap</font>这些算法来维护堆性质,从而实现优先队列的功能。

面试官: 接下来,请手写一个单链表的反转函数,要求反转从l到r区间的节点。

求职者:

  1. class ListNode {
  2. int val;
  3. ListNode next;
  4. ListNode(int x) { val = x; }
  5. }
  6. public ListNode reverseBetween(ListNode head, int left, int right) {
  7. if (head == null || left == right) return head;
  8. ListNode dummy = new ListNode(0);
  9. dummy.next = head;
  10. ListNode pre = dummy;
  11. for (int i = 1; i < left; i++) {
  12. pre = pre.next;
  13. }
  14. ListNode start = pre.next;
  15. ListNode then = start.next;
  16. for (int i = 0; i < right - left; i++) {
  17. start.next = then.next;
  18. then.next = pre.next;
  19. pre.next = then;
  20. then = start.next;
  21. }
  22. return dummy.next;
  23. }

面试官:很好,你的链表反转实现考虑到了边界条件,耐心等待通知!