编程导航抖音话题讨论

抖音

4 参与
分享

快来分享你的内容吧~

点击登录,快来和大家讨论吧~
表情
图片
话题
打卡
综合
交流
文章
问答

30-50K|抖音大模型|社招3轮面经

**抖音一面** 1、聊项目。 2、AUC的两种公式是?你能证明这两种等价的吗? 3、BERT-CRF中,为什么要加CRF?好处是? 4、self-attention为什么要用QKV三个矩阵,不用有什么问题?有没有哪个模型的Q和K矩阵是一样的? 5、reinforce属于on-policy还是off-policy?为什么? 6、reinforce带上baseline好处是?reinforce的loss写一下? 7、策略梯度会推导吗?简单写一下? 8、代码题(代码题一般别着急写,先跟面试官说下思路,确定了再写): lc 46,全排列(lc表示leetcode,下同)。 lc 73,矩阵置0。 **抖音二面** 1、介绍项目。 2、知识蒸馏有哪几种?你觉得哪种效果最好? 3、nlp的数据增强方法,主要有哪几种?每一种举个例子? 4、分类的损失函数为什么是交叉熵而不是mse? 5、BERT对输入文本的长度有什么限制,为什么要限制长度呢? 6、BigBird里面有哪几种注意力机制?相比原始transformer的self-attention的优势? 7、场景题:如何根据拼多多的商品数量,估计淘宝的商品数量? 8、给出emb_size, max_len, vocab_size, ff_inner_size,num_heads, 12层,求BERT参数量。 9、代码题:n皇后问题。 **抖音三面** 1、简单聊项目。 2、CRF和HMM区别?CRF为什么比HMM效果好? 3、如果BERT词表很大,比如vocab_size达到几百万,怎么办? 4、快速手写一些transformer的mha(多头注意力),伪代码意思一下就行。 5、为什么对比学习中,temperature很小,而知识蒸馏的temperature比较大? 6、你觉得在抖音买东西,和淘宝、拼多多他们的区别是?(我没在抖音买过,就只能现场编。) 7、你最近看到过哪些paper?简单介绍下? 8、你觉得自己有那些优缺点?平时喜欢怎么缓解压力?

字节抖音电商一面 25/2/17

## 字节抖音电商一面 25/2/17 1. 展开介绍一下模板方法,除了模板方法还有其他用到的设计方法吗,模板方法会有一些什么问题 2. 多级缓存是怎么理解的,guawa cache和caffeine的区别,为什么选择caffeine,它的缓存失效机制有哪些 3. 定时删除和惰性删除的优缺点,redis是怎么结合使用的 4. 多级缓存的缓存一致性问题怎么解决 5. redis热key问题怎么解决 6. redis支持事务吗,支持回滚吗 7. 对redis中的哪些数据结构比较了解,zset使用的场景,底层原理,除了跳表还有什么 8. 展开说一下跳表 9. redis持久化机制,什么场景使用哪一个 10. shardingspere底层实现原理,怎么进行分库分表 11. 数据库的连接池有了解吗 12. 数据库里面的会话是什么意思,就是session 13. 分库分表的场景(云图库团队空间),有涉及到分布式事务的场景吗 14. 打开网页输入一个url返回网页的过程 15. DNS寻找的逻辑 16. 什么是DDOS 17. ping的底层原理逻辑,它是哪一层的协议 18. 进程跟线程的差异 19. 管道 20. 缺页机制 21. concurrenthashmap的底层逻辑,怎么解决的线程安全的问题,跟hashmap有什么差异,segment分段锁,hashmap为什么线程不安全 22. java里面的锁有哪些,sychronized的底层机制,本身是一个什么级别的锁,锁方法怎么用,锁对象怎么用,锁方法有什么需要注意的,对象锁和方法锁的底层差异是什么,java在底层是怎么支持这种能力的,java字节码层面会涉及到一些什么改造 23. ThreadLocal线程安全吗,在什么场景下使用 24. volatile的作用,它在字节码层面是怎么禁止指令重排的 25. 算法(最长非重复子串)

抖音一面24/7/12

1. 介绍项目(oj) 2. 做这个项目时遇到的印象比较深刻的问题 > 在开发多种代码沙箱的实现方式(Java 原生和 Docker)发现有大量的重复代码,不利于修改和维护,想到使用模板方法来解决; > > > > 改造项目为微服务后发现无法在题目服务中获取到用户信息,想到把项目登录方式由本地 Session 改造为基于 Redis 的分布式 Session 等。(解决 cookie 跨路径问题) > > ```yml > server: > address: 0.0.0.0 > port: 8104 > servlet: > context-path: /api/judge > # cookie 30 天过期 > session: > cookie: > max-age: 2592000 > path: /api > ``` > > 3. session在redis中怎么存的 > (sessionId,用户信息) 引入依赖,修改session存储类型 4. redis有哪些数据结构 5. zset底层实现 6. 还有什么遇到的问题 > Java安全管理器 限制用户对文件、内存、CPU、网络等资源的操作和访问。 > > docker容器安全性 **超时控制 内存资源 网络资源 权限管理** 7. 操作系统中进程和线程的区别 > 1. 资源分配: > - 进程是资源分配的基本单位,拥有独立的地址空间,包括代码段、数据段、堆、栈等。 > - 线程是进程中的执行单元,共享所属进程的资源,如代码段、数据段等,但每个线程有自己的栈。 > 2. 系统开销: > - 创建和撤销进程时,系统需要分配和回收资源,开销较大。 > - 线程的创建和撤销开销相对较小。 > 3. 并发性: > - 进程之间的并发性较低,切换时需要切换上下文。 > - 线程之间的并发性较高,切换线程的开销较小。 > 4. 通信方式: > - 进程间通信方式较为复杂,如管道、消息队列、共享内存等。 > - 线程间通信相对简单,可以直接读写进程内的共享变量。 > 5. 调度: > - 进程是操作系统调度的基本单位。 > - 线程是 CPU 调度的基本单位。 8. 为什么不用进程做并发,而是设计出了线程这样一个概念 > 1. 资源开销:进程的创建、切换和销毁需要较大的系统资源开销。创建一个新进程需要为其分配独立的地址空间、内存资源、文件描述符等。而线程的创建和切换开销相对较小,因为线程共享所属进程的资源,不需要为每个线程单独分配完整的资源。 > 2. 通信效率:进程间通信的方式相对复杂且效率较低,如管道、消息队列、共享内存等方式都需要额外的系统调用和数据拷贝操作。而线程间由于共享进程的内存空间,通信可以通过直接访问共享变量来实现,通信效率更高。 > 3. 并发粒度:进程的并发粒度较粗,每个进程都是一个独立的执行单元,切换进程意味着较大的上下文切换成本。而线程可以提供更细粒度的并发控制,使得多个任务在同一个进程内并发执行,更灵活地分配系统资源和处理任务。 > 4. 系统性能:在需要大量并发执行任务的场景下,如果使用进程来实现,由于进程的资源开销和切换成本,会导致系统性能下降。而线程能够在较小的资源消耗下实现更高的并发度,提高系统的整体性能和响应能力。 9. 在项目中使用到多线程的场景 * 智能BI项目 ![image-20240712161335537](自我介绍.assets/image-20240712161335537.png) 自定义线程池 ```java @Configuration public class ThreadPoolExecutorConfig { @Bean public ThreadPoolExecutor threadPoolExecutor() { ThreadFactory threadFactory = new ThreadFactory() { private int count = 1; @Override public Thread newThread(@NotNull Runnable r) { Thread thread = new Thread(r); thread.setName("线程" + count); count++; return thread; } }; ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 4, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), threadFactory); return threadPoolExecutor; } } ``` 提交任务到线程池: ```java CompletableFuture.runAsync(() -> { System.out.println("任务执行中:" + name + ",执行人:" + Thread.currentThread().getName()); try { Thread.sleep(60000); } catch (InterruptedException e) { e.printStackTrace(); } }, threadPoolExecutor); ``` * 导入数据 ```java private ExecutorService executorService = new ThreadPoolExecutor(16, 1000, 10000, TimeUnit.MINUTES, new ArrayBlockingQueue<>(10000)); ``` 10. volatile关键字的作用 > 1. 保证可见性:当一个变量被声明为`volatile`时,线程对该变量的修改对于其他线程是立即可见的。也就是说,当一个线程修改了一个`volatile`变量的值,其他线程能够立即感知到这个变化,从而读取到最新的值。 > 2. 禁止指令重排序:编译器和处理器为了优化性能,可能会对代码的执行顺序进行重排序。但对于被`volatile`修饰的变量,在其读写操作前后,相关的指令不会被重排序,从而保证了程序执行的顺序和逻辑的正确性。 > > 需要注意的是,`volatile`不能保证原子性,即多个线程同时对`volatile`变量进行操作时,可能会出现数据不一致的问题。例如,当一个线程对`volatile`变量进行自增操作(`++`)时,这个操作不是原子性的,可能会出现并发问题。在这种情况下,如果需要保证原子性和线程安全,需要使用锁或者其他并发控制机制。 11. 为什么会出现一个线程把数据改了,其他线程读不到的这种情况 > 1. 缓存问题:现代计算机系统中,为了提高性能,CPU 都有自己的高速缓存(L1、L2、L3 缓存等)。当一个线程对共享变量进行修改时,这个修改可能首先被写入到该线程所在 CPU 的缓存中,还没有及时刷新到主内存(计算机的物理内存)。而其他线程可能从自己的 CPU 缓存或者尚未更新的主内存中读取数据,导致无法获取到最新的值。 > 2. 编译器优化:编译器在编译代码时,可能会对代码进行优化重排序。例如,在不影响单线程执行结果的前提下,编译器可能会对指令的执行顺序进行调整。这可能导致在多线程环境下,不同线程对变量的读写顺序与我们在代码中编写的顺序不一致,从而导致数据不一致的问题。 > 3. 处理器优化:处理器为了提高执行效率,也可能会对指令进行乱序执行,使得指令的实际执行顺序与程序代码中的顺序不一致。这在多线程场景下也可能导致数据可见性问题。 12. ThreadLocal的基本原理(map的key是什么) [ThreadLocal 详解 | JavaGuide](https://javaguide.cn/java/concurrent/threadlocal.html) > `Thread`类有一个类型为`ThreadLocal.ThreadLocalMap`的实例变量`threadLocals`,也就是说每个线程有一个自己的`ThreadLocalMap`。 > > `ThreadLocalMap`有自己的独立实现,可以简单地将它的`key`视作`ThreadLocal`,`value`为代码中放入的值(实际上`key`并不是`ThreadLocal`本身,而是它的一个**弱引用**)。 > > 每个线程在往`ThreadLocal`里放值的时候,都会往自己的`ThreadLocalMap`里存,读也是以`ThreadLocal`作为引用,在自己的`map`里找对应的`key`,从而实现了**线程隔离**。 > > `ThreadLocalMap`有点类似`HashMap`的结构,只是`HashMap`是由**数组+链表**实现的,而`ThreadLocalMap`中并没有**链表**结构 > > > > `ThreadLocal`内部维护了一个`ThreadLocalMap`,这个`ThreadLocalMap`以当前线程作为键,要存储的值作为值。 > > > > 当在一个线程中通过`ThreadLocal`对象进行数据存储时,`ThreadLocal`会获取当前线程,然后将数据存储在当前线程的`ThreadLocalMap`中。每个线程都有自己独立的`ThreadLocalMap`,所以不同线程通过同一个`ThreadLocal`对象存储的数据不会相互干扰和影响。 > > > > 当需要获取数据时,`ThreadLocal`同样根据当前线程从对应的`ThreadLocalMap`中获取数据。 > > > > 当线程结束时,如果没有对`ThreadLocal`中的数据进行正确的清理,可能会导致内存泄漏,因为线程结束后,对应的`ThreadLocalMap`以及其中存储的数据可能无法被正常回收。 `Java`的**四种引用类型**: - **强引用**:我们常常 new 出来的对象就是强引用类型,只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足的时候 - **软引用**:使用 SoftReference 修饰的对象被称为软引用,软引用指向的对象在内存要溢出的时候被回收 - **弱引用**:使用 WeakReference 修饰的对象被称为弱引用,只要发生垃圾回收,若这个对象只被弱引用指向,那么就会被回收 - **虚引用**:虚引用是最弱的引用,在 Java 中使用 PhantomReference 进行定义。虚引用中唯一的作用就是用队列接收对象即将死亡的通知 `ThreadLocal` 的`key`是弱引用,那么在`ThreadLocal.get()`的时候,发生`GC`之后,`key`是否是`null`? > 这个问题刚开始看,如果没有过多思考,**弱引用**,还有**垃圾回收**,那么肯定会觉得是`null`。 > > 其实是不对的,因为题目说的是在做 `ThreadLocal.get()` 操作,证明其实还是有**强引用**存在的,所以 `key` 并不为 `null`,如下图所示,`ThreadLocal`的**强引用**仍然是存在的。 > > 如果我们的**强引用**不存在的话,那么 `key` 就会被回收,也就是会出现我们 `value` 没被回收,`key` 被回收,导致 `value` 永远存在,出现内存泄漏。 13. 算法题 数组中滑动窗口的滑动过程中,每一个窗口的最大值(时间复杂度) > 窗口中的每一个值存入有序map,key为元素值,value为元素值的出现次数,最大值就是最后一个元素。滑动的过程中将左边移除窗口的元素减减,右边的元素加加,如果移除的元素移除后次数为0,就删除这个元素。 14. 一个系统中,记录处理用户提交的订单的耗时,得到实时流式输入的耗时数据的中位数, > 排序 > > 优先队列 > > 维护一个有序数组,插入到有序数组 > > **正解** > > **使用两个堆(大顶堆和小顶堆)** > > 维护一个大顶堆和一个小顶堆。 > > 大顶堆存储较小的一半数据,小顶堆存储较大的一半数据。 > > 当新数据到来时: > > 如果大顶堆为空或者新数据小于等于大顶堆的堆顶元素,将新数据插入大顶堆;否则,将新数据插入小顶堆。 > > 然后进行调整,使两个堆的元素数量差不超过 1。 > > 要获取中位数: > > 如果两个堆的元素数量相同,中位数为两个堆顶元素的平均值;如果大顶堆的元素数量比小顶堆多 1,大顶堆的堆顶元素为中位数;反之,小顶堆的堆顶元素为中位数。 > > > > 插入数据和获取中位数的时间复杂度都为 O(log n),效率较高。 > > ```java > import java.util.PriorityQueue; > > class MedianCalculator { > > private PriorityQueue<Integer> maxHeap; // 存储较小的一半数据 > private PriorityQueue<Integer> minHeap; // 存储较大的一半数据 > > public MedianCalculator() { > maxHeap = new PriorityQueue<>((a, b) -> b - a); > minHeap = new PriorityQueue<>(); > } > > public void insertData(int data) { > if (maxHeap.isEmpty() || data <= maxHeap.peek()) { > maxHeap.offer(data); > } else { > minHeap.offer(data); > } > > // 调整两个堆的大小 > if (maxHeap.size() > minHeap.size() + 1) { > minHeap.offer(maxHeap.poll()); > } else if (minHeap.size() > maxHeap.size()) { > maxHeap.offer(minHeap.poll()); > } > } > > public double getMedian() { > if (maxHeap.size() == minHeap.size()) { > return (maxHeap.peek() + minHeap.peek()) / 2.0; > } else if (maxHeap.size() > minHeap.size()) { > return maxHeap.peek(); > } else { > return minHeap.peek(); > } > } > > public static void main(String[] args) { > MedianCalculator calculator = new MedianCalculator(); > > calculator.insertData(5); > calculator.insertData(3); > calculator.insertData(7); > calculator.insertData(2); > calculator.insertData(6); > > System.out.println("中位数: " + calculator.getMedian()); > } > } > ``` > >

帮鱼友发一波抖音的内推消息,25 届实习的同学可以关注一波,有转正机会(组内现在很缺人)~ 事业部:抖音 Base 地:杭州 职位描述: 1、参与系统架构设计、优化,提升系统性能和开发效率,保证高并发高可靠; 2、通过不断的技术研究和创新,推动业务的快速发展和高效迭代; 3、善于从工作中抽象和归纳问题,用技术方案高效解决。 职位要求: 1、2025届本科及以上学历在读,计算机、软件工程等相关专业优先; 2、有扎实的数据结构和算法功底,计算机基础功底扎实; 3、至少熟练掌握一门编程语言(C/C /Java/Python/Golang/PHP等); 4、热爱编程,有强烈的求知欲、好奇心和进取心有较强的学习能力,能及时关注和学习业界最新技术; 5、每周可实习3天以上,可实习4个月以上, #求职# #内推# #抖音# #字节跳动#

下载 APP