用户2df4f

新闻专业
分享
1
心动的Offer
困困的一天天

【游戏行业】米哈游-游戏音频设计-面经

3.10号投递简历,无内推,到现在4.30号五一过节前收到终面挂的感谢信,历时一个多月终于结束了这次算不上愉快但收获颇多的校招经历。总而言之,认识到了自己很多的不足,但在某些方面也深感无奈。 关于此岗位的面经真的太少了,也算是自己所能做的一点贡献。 楼主是音乐艺术生,专业对口,虽不是985211,但为艺术一本学校大四生,在校专业成绩靠前,去年有在某老牌游戏公司担任音频设计正式参与开发的实习经验以及不少在校经验,简历可以说是还过得去,个人作品亦算拿的出手,可仍然没有信心。在经过了十几天的筛选,于3月底无内推的情况下收到了测试题邮件,我感到非常激动和感谢。因自身也玩米哈游游戏,对米哈游公司有一定了解,已经作为了工作去向的首选之一,简历未挂,当时我认为已经成功迈出了第一步。 关于测试题,自然是非常认真的细心打磨(个人认为米哈游的测试题相比于其它大厂稍难一点,重点在要提前了解游戏行业里这一岗位的规范制作)测试题发出后经过了一个清明节,节后很快就收到了米哈游hr的消息,邀请我参加一面面试,对此我甚是惊喜。通知的一面时间已经排到了好几天后,在这段时间里也做了很多准备,希望在面试上有好的表现。 一面 项目组负责人面 大约20分钟 1.首先是双方的自我介绍 2.与目前其它岗位大多面经里提到的不太一样,我的一面氛围实际上总体来说是比较严肃的,面试官也跟我说这是米哈游第一次在音频这个岗位上进行校招,会比较严格。 我虽是设计相关,却不和其它校招设计岗位一样,未就我的作品和测试题做出任何有关设计思路和制作流程的提问,可能对我真正参与过游戏开发的实习经历比较感兴趣,开场就深挖、对我实习中做的所有工作进行详细的了解。(若有想应聘此岗位的小伙伴们,我建议简历一定要真实,你做了什么就写什么,千万不能夸大。) 3.未来规划 4.反问,提了一个我自己想知道的问题,这里负责人跟我说的很详细,特别感谢他。回答结束后有问我何时能到岗。 一面结束后一个小时通知我顺利通过,接下来进入到二面。 二面 音频总监 大约20分钟 1.自我介绍 2.未来规划(需具体说明,非常非常非常详细的那种) 3.因时间久远,有些记不太清了,大概是根据了不了解米哈游游戏的程度进行问答,这里我主要答了原神,之后面试官根据我的回答进行反问,例如角色特点。(特别提醒,最好详细准备自己所答的游戏的优缺点,将每一个环节都分析到位,包括npc小怪) 4.印象深刻的游戏,分析优点 5.目前在学习的新知识 二面结束同样一个小时后通知我顺利通过,进入到了终面。 得知我已经成功进入到终面的那一刻,我觉得自己的胜利就在眼前,距离我特别想去的公司还有一步之遥,我依然是非常认真的准备我的面试,就算得知是终面,可能就是hr面也不敢松懈下来。 终面 HrBP 大约15分钟 这次面我的是一位看起来很年轻的小姐姐,介绍自己是这个部门的BP,然后因为有看我的简历,直接省去了自我介绍的环节,对我的简历进行一些提问。 当听到是HrBP的时候,我其实心里有松了一口气,应该不会再像之前两面这么严肃,可能是个快乐的过程, 但没想到,噩梦就此开始。 1.这个专业小众,是怎么想到要去学的呢?你的学校不在上海也不是上海人,对工作地点有什么要求吗? 我诚实回答是个人喜好,一开始就想学这个专业。对工作地点更看重公司成长空间,没有硬性要求。 BP对我的回答是有点惊讶,其惊讶程度在我原来并非是在高中时候感觉学习别的专业成绩不太好,另走的音频设计这条道路。听到对方这么评价我时,我也有些震惊,为何会有如此想法?也不理解我不是本地人的话难道就不能投上海公司了? 2.问我pt是不是我们常用的软件。 对于这个问题,老实说至今我也不太清楚为什么这么问,业界内使用pt的人占比非常多,即便米哈游不使用pt,我也写了自己会使用市面上其它常用软件。 3.了解米哈游游戏吗?原神等级? 4.原神在音频设计上的缺点,目前有哪些能改进?(答出来了) 5.如果进了原神项目组,想要做哪个部分的工作(角色,环境,场景,还是语音等),对比同类音频设计师你自己的优势在哪里,之后根据自己的回答,反问游戏里这部分值得提升的地方 我认为自己是踩了坑,在反问时有关提升这个方面我回答的并不好,也认识到了自己的不足,没有多方面思考和准备到自己回答的这点上,又因为太过紧张,脑子没转过来所以没答好,可能这就是我失败的铺垫。 在我没很好的回答出来后,BP告诉我,能来到她这里的人已经所剩不多了,既然到了终面,那肯定有一定技术水准,可是他们更希望能找到现在可以对米哈游游戏立刻提供优化点的人才,而不是纯粹的光有一些水平却没有思考能力提出问题的人,否则想提升技术大可去外包公司。 我本来想做稍微的有关"提升技术大可去外包公司"的这个回答加以反驳,可到最后我深思熟虑下来,担心再给对方造成不好印象,只能承认自己的临场反应不够和准备不充分,在这点上我确实不够优秀。(经过这次面试后,我有更加仔细的去听原神的音效,并且找到了许多可以优化的地方,可如今也多说无用了) 6.玩什么类型的游戏最多? 我回答了玩国产游戏比较多,本还想继续回答其它游戏,可就在此时,BP打断了我,认为我只玩国产游戏不行,它们都达不到高水准,米哈游的游戏在海外多国国家发行, 更需要放眼国际的人才。 在BP说完后,我立刻对自己进行了一些解释,因为我简历上写的游戏经历是国内外五五开,买过掌机和家庭主机,并没有只玩国产游戏,但3A游戏玩的确实少了,这是我的不足。 7.是否了解Wwise? 由于之前的实习经历主要用的是CRI,Wwise是自学阶段(国内对游戏音频中间件教学极少,大多靠自学或进公司培训学习),我诚实告知我的Wwise学习进度(已到工作可用水平),没想到BP又一次打断我:是否能在一个月内入职前将Wwise学会。 我并不了解所谓"学会"包括了哪个程度,是不是需要达到301这样的资深音效师级别,但我相信自己的学习能力,回答了自己没有问题。 8.是否有其它offer? 9.反问阶段,也是我对于米哈游校招经历中最不愉快的一个节点 终面面试期间,这位BP屡次问到我是否有过面试培训,觉得我的回答太过正规,且在最后反问阶段对于我的提问:公司期望什么样的员工,再次质问我。 我个人坦诚道我没有经历过面试培训,事实也是如此,我不懂如何为自己解释对方才能相信,同时不明白假如真有过面试培训,是否在应聘过程中就是不耻行为了。因此只能无奈道我问的问题纯粹是希望提升自己的个人能力,能更好的在公司发展,这就是我的实话实说,百口莫辩,也认为对我的态度有些不尊重了。 此时BP对于我的回答给予肯定还是否定不相信我并不知晓,也不是我主要关注的内容,之后我认真听她对我的问题进行的相关答复,大致内容为: 米哈游不是像别的只会做换皮游戏的某些大公司 ,实力强劲,量少却精,开发的项目深得国内外玩家喜欢,进来时首先就要确保熟悉米哈游游戏和业务,这个岗位并没有什么培训,入职后便要迅速上手,换言之, 个人实力过硬,有自己的想法,哪怕是校招生,也最好能达到社招水平。 结束终面面试后我的心情可以说的上是非常糟糕,除了BP对我不是很尊重这点外,也对于我的能力又有了很大程度的认识反省,感觉自己在对方眼里不过就是个还行的本质废物。 对那些没有回答上来或是回答不好的问题,我进行了深刻总结,再次进入到了一个学习提升自我的阶段,我认为自己在这阶段有了或多或少的提升,等待结果中的同时抱着侥幸的心理很希望米哈游能够给我一个机会,在之后体现我的个人能力其实不止这些。 然而在经历过漫长的十几天等待后,我收到了感谢信。可老实说,等待时间过长早已磨平了我的所有信心和希冀,最后没有特别伤心,可以说是如释重负,结果我不意外。虽说难过在所难免,之前面试顺利的离谱都让我沾沾自喜,认可自己达到了要求,米哈游亦是我的首选公司之一,好像曙光就在眼前,可事实的降临仍然让我遭受到了相当程度的打击,与此同时也让我对米哈游公司有了一个新的认知高度。 如果还有机会再次参加招聘,在Hr通知时,也请不要连续三次念错面试者的名字了,更何况我的名字没有生僻字存在。 总结:音频设计这一行在国内依然小众,虽然声音在游戏里不可或缺,但许多游戏公司还是采取了外包的方式没有特别重视,因此校招生能够投递的公司实际上非常少,甚至能说是少的无比可怜,依然多是社招形式并需要一定工作经验。然而许多公司对此岗位并不开放校招,有此专业的国内学校也过少教学游戏音频中间件,几乎可以说是没有,又何来工作经验和熟悉此软件流程一说呢? 这又是有些可悲的现实问题了,较为残酷。 希望各位小伙伴一定要把握住每一次校招机会,在作品上多花心思,面试准备充分,对自己的个人水平有深刻的了解,多玩游戏多分析,提升自己技术水平并需知自己究竟想要做的是什么,这是最重要的。 马上五月份了,我的春招还未结束,目前手头有一个offer,二个面试通过评估中,还有少数几家在简历筛选阶段,我不会就此气馁倒下,我的个人规划向来明确,那就是我想在这条道路上越走越远,初心不忘。
分享
评论
原味笔面经
陈治宇
北京超职科技有限公司_产品测试实习生

Hello~近期在找新的机会吗? 这个岗位考虑一下不? 职位描述: 1. 负责电话接听、客人来访迎送等招待工作; 2. 文件收发、全员通讯录更新、员工门禁卡管理; 3. 负责行政物资及办公用品的采购、管理工作,协助员工完成领用工作; 4. 负责公司会议室安排、会前准备工作; 5. 协助上级主管对各项行政事务的安排及执行; 6. 完成上级交给的其它事务性工作。 任职要求: 1. 大专以上学历,身高162cm以上; 2. 半年或一年以上工作经验,优秀应届生也可; 3. 办事沉稳、细心、领悟能力强,性格温和,有良好的团队合作意识; 4. 熟练使用office办公软件及自动化设备,具备基本的网络知识; 5. 普通话标准,无沟通障碍,待人接物大方得体,有礼貌,懂得基本行政管理常识。 职位关键词:前台 职位亮点:不打卡 工作地点:北京
分享
评论
我这里招人
Candy

面试必会!Java后端开发岗位并发部分高频面试题分享

进程和线程的区别? 进程是系统资源调度的最小单位;线程是CPU调度的最小单位 进程是比线程更大的概念,进程之间彼此独立,一个进程里可以包含多个线程,多线程共享一部分资源,因此彼此相互影响比多进程更大 多线程共享一部分进程的内存区域,也有自己私有的区域 进程在执行时拥有独立的内存单元,多个线程共享进程的内存,如代码段、数据段、扩展段;但每个线程拥有自己的栈段和寄存器组。 进程和线程消耗什么系统资源? 线程共享的包括: 进程ID,优先级 代码区:代码编译后的可执行机器指令。 数据区:进程地址空间中的数据区,这里存放的是全局变量 堆区:new出来的数据就存放在这个区域 线程独立拥有: 线程id:用于区分每个线程 线程优先级:用于调度 1.栈区:栈帧中保存了函数的调用嵌套、返回值、调用其它函数的参数、该函数使用的局部变量以及该函数使用的寄存器信息 2.程序计数器:接下来执行那一条指令 3.寄存器:进程运行时的计算数据,进程切换时必须保存这些数据 i++是原子性的么?怎么保证原子性? i++不具有原子性,因为在+1之前可能其他线程改变了i的值 通过JUC中的Atomic,或者使用锁保证原子性 什么是上下⽂切换? ⼀般线程的个数都⼤于 CPU 核⼼的个数,⽽⼀个 CPU 核⼼在任意时刻只能被⼀个线程使⽤,为了让这些线程都能得到执⾏, CPU 轮流给每个线程分配时间⽚。当⼀个线程的时间⽚⽤完的时候就会重新处于就绪状态让给其他线程使⽤,这个过程就是⼀次上下⽂切换。 当前任务在执⾏完 CPU 时间⽚切换到另⼀个任务之前会先保存⾃⼰的状态,以便下次再切换回这个任务时,可以再加载这个任务的状态。 任务从保存到再加载的过程就是⼀次上下⽂切换。 如何减少上下文切换? 1.避免锁的使用。多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据。 2.CAS算法。Java的Atomic包使用CAS算法来更新数据,而不需要加锁。使用最少线程。 3.避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态。 4.协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。 线程通信的方式和区别? 1.共享对象。在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信,典型的共享内存通信方式就是通过共享对象进行通信。 例如synchronized关键字进行线程同步,实现通信 2.while轮询,不断检测某个条件是否成立,比较浪费CPU资源, 此外存在可见性问题,线程都是先把变量读取到本地线程栈空间,然后再去再去修改的本地变量。因此,如果线程B每次都在取本地的 条件变量,那么尽管另外一个线程已经改变了轮询的条件,它也察觉不到,这样也会造成死循环。 3.wait/notify机制 在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过明确的发送消息来显式进行通信,在java中典型的消息传递方式就是wait()和notify()。缺点是当一个线程还未开始执行时,过早的notify是无效的。 4管道通信。就是使用java.io.PipedInputStream 和 java.io.PipedOutputStream进行通信 Java线程生命周期和切换过程 状态类型: 1.new 初始,线程被创建,未调用start() 2.runnable 运行(java将os中的就绪和运行状态统称:运行中) 3.blocked 阻塞(被锁阻塞) 4.waiting 等待(等待其他线程通知或中断,wait()进入notify()或者notifyAll()可以唤醒,a.join()会在进程a结束后唤醒) 5.time_waiting 超时等待(超过指定时间自行唤醒,sleep(),设置了Timeout参数的Object.wait(),Thread.join() ) 6.terminated 终止(执行完毕或者发生异常后结束) 状态转换: 1.线程创建之后它将处于 NEW状态,调⽤ start() ⽅法后开始运⾏,进入Runnable(可运⾏) 状态。 2.当线程获得了 cpu 时间⽚(timeslice)后就处于 RUNNING(运⾏) 状态。 (os隐藏了就绪和运行状态,Java统称这两种状态为RUNNABLE) 3.当线程执⾏ wait() ⽅法之后,线程进⼊ WAITING(等待)状态。进⼊等待状态的线程需要依靠其他线程的通知才能够返回到RUNNABLE状态,⽽ TIME_WAITING(超时等待) 设置了等待时间,当超时时间到达后 Java 线程将会返回到 RUNNABLE 状态。 4.当线程调⽤同步⽅法时,在没有获取到锁的情况下,线程将会进⼊到 BLOCKED(阻塞) 状态。 5.线程执行完毕后会进⼊到 TERMINATED(终⽌) 状态。 线程状态切换的方式 object类提供的方法,只能在synchronized同步代码块中使用 wait() notify() notifyAll() Thread类提供的方法 sleep() join():b线程内调用a.join()会让a先执行完毕,然后b继续执行 yield(),表示当前线程优先级较低,可以切换到其他线程,是对线程调度的建议,而非强制 thraed.setDaemon(true) 方法可以将一个线程设置为守护线程,所有非守护线程结束时会杀死守护线程 juc提供的方法,配合ReentrantLock使用 await() signal() signalAll() condition.await()可以指定等待的条件,更加灵活 sleep wait的区别和共同点? sleep来自Thread类,可以在任何地方使用 让线程暂停一段时间,释放cpu,但是不会释放锁,暂停结束后重新等待cpu分配时间片 sleep() ⽅法执⾏完成后,线程会⾃动苏醒。或者可以使⽤ wait(longtimeout) 超时后线程会⾃动苏醒。 注: Thread.Sleep(0)的作用,就是触发操作系统立刻重新进行一次CPU竞争,竞争的结果也许是当前线程仍然获得CPU控制权,也许会换成别的线程获得CPU控制权。 wait是object的方法,主要用于线程通信,wait只能在同步代码块中使用(拿到锁之后才能使用) 让线程进入锁对象的等待池中,进入等待状态,在指定时间内释放cpu和锁,时间结束后恢复,进入阻塞状态,重新竞争锁,没有指定时间就需要其他线程notify notify()和 notifyAll()有什么区别? 1.如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁。 2.当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争。 3.优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用 wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。 为什么wait方法和notify方法要在基类,在其他类行不行? 因为 wait 和 notify 方法必须要在同步代码块中才能调用,而同步代码块锁的是对象,调用该对象的 wait 方法,线程会进入该对象的等待池中,和 Thread 无关。 waiting和blocked的区别?Wait超时后会怎样? 进入waiting状态时,会释放锁,并且之后不会主动获取锁,唤醒之后进入阻塞状态,重新尝试获取锁 blocked状态会主动尝试获取锁 Java线程的三种启动方式,优缺点? 1.实现Runable接口,重写run方法 new Thread(new MyRunnable()).start(); 2.实现Callable接口,重写call方法,可以获取计算结果 FutureTask<Integer> ft = new FutureTask<>(new Th3()); new Thread(ft).start(); System.out.println(ft.get()); 3.继承Thread,覆盖 run() 方法,直接start即可,不需要new Thread mt.start() 4.匿名内部类创建线程 new Thread(new Runnable() { public void run() {} } }).start(); 实现 Runnable 和 Callable 接口的类只能当做一个可以在线程中运行的任务,不是真正意义上的线程,因此最后还需要通过 Thread 来调用。 继承Thread可以理解为一个线程,直接调用start即可 实现接口会更好一些,因为: Java 不支持多重继承,因此继承了 Thread 类就无法继承其它类,但是可以实现多个接口; 类可能只要求可执行就行,继承整个 Thread 类开销过大。 线程run和start的区别,为什么我们调⽤ start() ⽅法时会执⾏ run() ⽅法,为什么我们不能直接调⽤ run() ⽅法? new ⼀个 Thread,线程进⼊了新建状态。调⽤ start() ⽅***启动⼀个线程并使线程进⼊了就绪状态,当分配到时间⽚后就可以开始运⾏了。 start() 会执⾏线程的相应准备⼯作,然后⾃动执⾏ run() ⽅法的内容,这是真正的多线程⼯作。 但是,直接执⾏ run() ⽅***把 run()⽅法当成⼀个 main 线程下的普通⽅法去执⾏,并不会在某个线程中执⾏它,所以这并不是多线程⼯作。 总结: 调⽤ start() ⽅法⽅可启动线程并使线程进⼊就绪状态,直接执⾏ run() ⽅法的话不会以多线程的⽅式执⾏。 如何结束线程? interrupt(): 如果该线程处于阻塞、限期等待或者无限期等待状态,那么就会抛出 InterruptedException,从而提前结束该线程。但是不能中断 I/O 阻塞和 synchronized 锁阻塞。 thread.start(); thread.interrupt(); interrupted(): 如果一个线程的 run() 方法执行一个无限循环,并且没有执行 sleep() 等会抛出 InterruptedException 的操作,那么调用线程的 interrupt() 方法就无法使线程提前结束。 但是调用 interrupt() 方***设置线程的中断标记,此时调用 interrupted() 方***返回 true。因此可以在循环体中使用 interrupted() 方法来判断线程是否处于中断状态,从而提前结束线程。 其他用于线程管理的类? CountDownLatch: 维护一个计数器,每次调用countDown()时计数器-1,当计数器为0时,因调用 await() 方法而在等待的线程就会被唤醒。 CountDownLatch countDownLatch = new CountDownLatch(1); countDownLatch.await(); countDownLatch.countDown(); //计数器-1 countdownlatch实现原理 CyclicBarrier public CyclicBarrier(int parties) public CyclicBarrier(int parties, Runnable barrierAction) 循环屏障,当阻塞线程达到指定个数时将会全部唤醒它们,然后继续开始计数。 有两个构造函数,其中 parties 指示计数器的初始值,第二个构造方法有一个 Runnable 参数,这个参数的意思是最后一个到达线程要做的任务 CyclicBarrier cyclicBarrier = new CyclicBarrier(10); cyclicBarrier.await(); //每次调用await时计数器-1,计数器为0时唤醒之前阻塞的线程 Semaphore 可以控制对互斥资源的访问线程数。 Semaphore semaphore = new Semaphore(3); //最大同时访问数3 semaphore.acquire(); //获取,获取不到则阻塞 semaphore.tryAcquire(); //尝试获取 semaphore.release(); //释放当前资源,计数器+1 semaphore.availablePermits() //输出剩余可访问数 LockSupport 可以让线程在任意位置阻塞和唤醒线程。和wait notify的区别有两点: (1)wait和notify都是Object中的方法,在调用这两个方法前必须先获得锁对象,但是park不需要获取某个对象的锁就可以锁住线程。 (2)notify只能随机选择一个线程唤醒,无法唤醒指定的线程,unpark却可以唤醒一个指定的线程。 LockSupport.park(); //阻塞当前线程 LockSupport.unpark(t2); //唤醒指定线程 线程池是什么,好处? 1.降低资源消耗。通过重复利⽤已创建的线程降低线程创建和销毁造成的消耗。 2.提⾼响应速度。当任务到达时,任务可以不需要的等到线程创建就能⽴即执⾏。 3.提⾼线程的可管理性。线程是稀缺资源,如果⽆限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使⽤线程池可以进⾏统⼀的分配,调优和监控。 重复创建线程为什么会开销过大? 1.必须为线程堆栈分配并初始化一大块内存。 2.需要进行系统调用,系统从用户态切换到内核态,创建和注册新线程。 3.需要创建,初始化描述符并将其添加到JVM内部数据结构中。 线程池的创建方法和参数,等待队列,拒绝策略 我们可以使用ThreadPoolExecutor来创建线程池 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); 我们可以看出创建线程池有七个参数,而上述我们通过Executors工具类来创建的线程池就一两个参数,其他参数它都帮我们默认写死了,我们只有真正理解了这几个参数才能更好的去使用线程池。下面我们来看看这七个参数(线程池参数) 1.corePoolSize 核心线程数(线程池的基本大小)当我们提交一个任务到线程池时就会创建一个线程来执行任务.当我们需要执行的任务数大于核心线程数了就不再创建, 如果运行的线程少于 corePoolSize,则创建新线程来处理任务,即使线程池中的其他线程是空闲的;如果我们调用了prestartAllCoreThreads()方法线程池就会为我们提前创建好所有的基本线程。 2.maximumPoolSize 最大线程数:线程池允许创建的最大线程数。如果队列已经满了,且已创建的线程数小于最大线程数,则线程池就会创建新的线程来执行任务。这里有个小知识点,如果我们的队列是用的无界队列,这个参数是不会起作用的,因为我们的任务会一直往队列中加,队列永远不会满(内存允许的情况)。 3.keepAliveTime 空闲线程最大生存时间。当前线程数大于核心线程数时,结束多余的空闲线程等待新任务的最长时间,直到线程池中的线程数不超过核心线程数。但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0。 4.unit 线程存活时间的的单位。可选的单位有days、hours等。 5.workQueue 任务队列。主要分为三种: 1.直接握手队列: 队列容量为0,,如果没有线程立即可用来运行它,将不会进入队列,而是直接构建新的线程来运行它。一般最大线程数无限制,因此要注意线程数无限增长的问题。( 此策略在处理可能具有内部依赖关系的请求集时避免锁定) 2.无界队列:队列容量为无限,当核心线程都在运行任务时,新任务都将进入队列等待,此时最大线程数的设置是无效的。当任务的处理速度小于增加速度时,可能出现队列无限增长的问题。(可以用于平滑瞬时大量请求) 3.有界队列:队列容量有限,有助于防止资源耗尽,但是难以控制。队列大小和最大线程数需要相互权衡 大队列和较小的最大线程数可以地减少CPU使用率,操作系统资源和上下文切换开销,但会导致人为的低吞吐量。如果任务经常被阻塞(比如I/O限制),那么系统可以调度比我们允许的更多的线程。 使用小队列通常需要较大的maximumPoolSizes,这会使CPU更繁忙,但可能会遇到不可接受的调度开销,这也会降低吞吐量。 ArrayBlockingQueue:数组实现的有界阻塞队列,先进先出,支持公平锁和非公平锁 LinkedBlockingQueue:链表实现,先进先出,默认长度为Integer.MAX_VALUE,默认长度有OOM风险 LinkedBlockingDeque:链表实现的双向阻塞队列,队列头尾可以增删元素,并发环境下可以将锁的竞争最多降低到一半 PriorityBlockingQueue:支持优先级排序的无界队列,默认自然顺序,重写compareTo()方法定义排序规则,不保证同优先级元素的顺序 DelayQueue:实现PriorityBlockingQueue实现延迟获取的无界队列,创建元素时可以指定间隔多久才能从队列中取出该元素。 SynchronousQueue:不存储元素的阻塞队列,每个put操作必须等待take操作,否则无法添加元素,支持公平锁和非公平锁,一个使用场景是Executors.newCachedThreadPool()会在新任务到来时创建新线程,有空闲线程会重复使用,空闲超过60s后回收 LinkedTransferQueue:链表实现的无界阻塞队列,多了transfer和tryTransfer方法 6.threadFactory 用户设置创建线程的工厂,我们可以通过这个工厂来创建有业务意义的线程名字。我们可以对比下自定义的线程工厂和默认的线程工厂创建的名字。 默认产生线程的名字:pool-5-thread-1 自定义线程工厂产生名字:testPool-1-thread-1 7.RejectedExecutionHandler 线程池拒绝策略。线程池关闭或队列和最大线程数已满时都会触发。当队列和线程池都满了说明线程池已经处于饱和状态。必须要采取一定的策略来处理新提交的任务。jdk默认提供了四种拒绝策略: ThreadPoolExecutor.AbortPolicy:默认策略,丢弃任务并抛出RejectedException异常。适合比较关键的业务,及时发现并发容量上界 ThreadPoolExecutor.DiscardPolicy:丢失任务且不抛出异常,适合无关紧要的业务 ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,重新提交被拒绝的任务。 ThreadPoolExecutor.CallerRunsPolicy:由线程池所在的线程处理该任务 参数如何设置? 1.一般我们如果任务为耗时IO型比如读取数据库、文件读写以及网络通信的的话这些任务不会占据很多cpu的资源但是会比较耗时:线程数设置为2倍CPU数以上,充分的来利用CPU资源。 2.一般我们如果任务为CPU密集型的话比如大量计算、解压、压缩等这些操作都会占据大量的cpu。所以针对于这种情况的话一般设置线程数为:1倍cpu+1。为啥要加1,很多说法是备份线程。又说留个空的做切换。 3.如果既有IO密集型任务,又有CPU密集型任务,这种该怎么设置线程大小?这种的话最好分开用线程池处理,IO密集的用IO密集型线程池处理,CPU密集型的用cpu密集型处理。以上都只是理算情况下的估算而已,真正的合理参数还是需要看看实际生产运行的效果来合理的调整的。 核心线程,最大线程数,判断执行流程? 任务提交时,判断的顺序为 corePoolSize --> workQueue --> maximumPoolSize。 1.如果运行线程少于核心线程数,则创建新线程来处理任务,即使线程池中的其他线程是空闲的 如果我们调用了prestartAllCoreThreads()方法线程池就会为我们提前创建好所有的基本线程。 2.如果线程池中的线程数量大于等于核心线程数且小于最大线程数(动态修改了coreSize才会出现这种情况),任务来了首先放在队列中, 只有当队列满时才创建新的线程处理任务。如果设置的核心线程数 和 最大线程数 相同,则创建的线程池的大小是固定的,这时如果有 新任务提交,若工作队列未满,则将请求放入工作队列中,等待有空闲的线程去从工作队列中取任务并处理; 3.如果运行的线程数量大于等于最大线程数,这时如果工作队列已经满了,则通过handler所指定的拒绝策略来处理任务; 自带的4种线程池为什么不推荐使用? 一般不使用Executors创建线程池, 1.FixedThreadPool和SingleThreadPool,允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM 2.CachedThreadPool和ScheduledThreadPool允许创建的线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。 建议使用 new ThreadPoolExecutor(),自定义7个参数。 1.SingleThreadExecutor 单线程线程池,可以保证任务顺序执行,还可以进行生命周期管理。 ExecutorService executorService = Executors.newSingleThreadExecutor(); for (int i = 0; i < 5; i++) { final int j = i; executorService.execute(() -> { System.out.println(j + " " + Thread.currentThread().getName()); }); } executorService.shutdown(); 2.CachedThreadPool CachedThreadPool是一个没有核心线程的线程池,当新任务来临时,如果非核心线程在忙碌,则直接新创建一个线程。SynchronousQueue是一个手把手传递的一个阻塞队列,可见上面的教程。特点是任务基本不需要等待? //核心线程数0,最大线程数无限,等待时间60s,不存储元素的等待队列 public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } ExecutorService service = Executors.newCachedThreadPool(); 3.FixedThreadPool FixedThreadPool是一个固定线程数的线程池。 ExecutorService service = Executors.newFixedThreadPool(cpuCoreNum); 4.ScheduledThreadPoolExecutor ScheduledThreadPoolExecutor是定时任务线程池,其本质上依然是ThreadPoolExecutor。 ScheduledExecutorService service = Executors.newScheduledThreadPool(4); 线程池如何保证核心线程不被销毁?线程池的线程是如何做到复用的? 线程内部有while循环不停的执行getTask方法从阻塞队列中获取任务调用task.run()来执行任务,这样的话就达到了线程复用的目的。 //有任务,或者从队列中获取到了任务,则执行,否则 while (task != null || (task = getTask()) != null) getTask从队列中的take方法获取任务,如果为空,take方法则一直阻塞当前线程,保证线程不会挂掉。 线程池里的某个线程发生了异常,会发生什么? 当一个线程池里面的线程异常后: 当执行方式是execute时,可以看到堆栈异常的输出。 当执行方式是submit时,堆栈异常没有输出。但是调用Future.get()方法时,可以捕获到异常。 不会影响线程池里面其他线程的正常执行。 线程池会把这个线程移除掉,并创建一个新的线程放到线程池中。
分享
7
先马后看
阿译
东南大学·2022届

(4.26)连续三面(java后端),攒人品,求offer

一面:预计40-50min 自我介绍+项目介绍 项目难点和优化 开始怼项目引出redis es redis 在项目为什么这么设计,fork子进程,快照持久化,布隆,最大漏斗限流 项目数据库表的设计 引出 引擎,B+,红黑树,事务级别,间隙锁 项目难点怎么想到优化的,为什么 计网拥塞控制,慢开始 、 拥塞避免 、快重传 和 快恢复 在三握手的时候又问了一个场景,如何解决(sry有点点记不太清) 手撕--二叉树的奇偶层打印 反问(对自己评价,业务线) 二面:预计40min 自我介绍 + 项目介绍 疯狂问项目+简单问了参加的比(水)赛 表为什么这么设计 redis为什么这样使用 优化的时候,进行压测了么? 瓶颈的时候,最慢查询需要多久 比其他春招生的优势 ioc aop 代理 getBean(提了一些源码,后被面试官问别的问题打断了) 详细说说学习java的路线,为什么这样去学 说出java和golang的区别(由于简历写了会一点点go) 由上面引出了java的字节码,javac,jvm,操作系统堆内块分配,和java生态 反问(新人培养) 三面:25min 自我介绍+项目大概说一下 做这个项目的目的,得到的收获 有哪些offer 更想去哪个城市 大学中最有成就感的事情 反问(最快什么时候给offer) 希望能oc,真的想去北京,希望大家都能顺利找到工作,分享最近喜欢的一句话 人生当中成功只是一时的, 失败却是主旋律, 但是如何面对失败, 却把人分成了不同的样子. 有的人被失败击垮, 有的人能够不断的爬起来继续向前. 我想,真正的成熟,并不是追求完美, 而是直面自己的缺憾这才是生活的本质!
分享
10
原味笔面经
杜禹欣 贤于

字节跳动内推

投递邮箱: duyuxin@bytedance.com
分享
评论
超级内推
HR内推官
500强名企·HR(内推官)

腾讯科技内推

投递邮箱: zealen@quanlikeji.xin
分享
评论
超级内推
HR内推官
500强名企·HR(内推官)

字节跳动内推

投递邮箱: zealen@quanlikeji.xin
分享
评论
超级内推
HR内推官
500强名企·HR(内推官)

阿里巴巴内推

投递邮箱: zealen@quanlikeji.xin
分享
评论
超级内推
用户bb54d

第一次写简历

希望自己可以完成!
分享
1
原味笔面经
姜依彤
哈尔滨师范大学·2016届

【急急急招】上市公司实习生

************************************************ base:北京 朝阳门 快拿简历砸向我吧[让我看看][让我看看][勾引] 投递邮箱📪VivianJiang@careerintlinc.com
分享
评论
心动的Offer
超级运营官课代表

【超级简历x美团民宿】超级运营官|抢先准备秋招!3周救急实习!在线办公!21-24届可投!大厂含金量证书!不限专业!最后19个名额...

《初入职场的我们》大家都看了吗,想要get海归精英“王玥”同款的项目经历吗,机会来啦~超级简历与美团名宿联袂打造了的新一期【超级运营官】,21天快速掌握运营实践技巧,不仅可以学知识,还有大厂offer可以拿!还在发愁没有找到暑期实习的同学必须看过来! 21天内就可收获: 👉 美团民宿实习内推通道 👉 大厂背书运营项目证书 👉 主流媒体运营实战训练 👉 500强导师1V1简历辅导 👉 神秘礼品+现金礼 👉 美团民宿200元优惠券 超级简历承诺:该项目全程免费,快点扫码报名吧!
分享
12
心动的Offer
路平

百度内推

内推描述: 帮内推任何岗位,帮看进度 投递邮箱: somyo97@126.com
分享
评论
超级内推
用户26240
对外经济贸易大学·2024届

大一没经历怎么写offer

准备大一暑假开始第一段实习,有什么写offer上的建议吗
分享
1
肖大哈

有人要成都的应届前端吗

会vue全家桶和小程序
分享
1
心动的Offer

超级简历 APP

从简历直达offer,快人一步拿高薪

最新内推
35 名用户可以帮你内推
16 名用户可以帮你内推
13 名用户可以帮你内推
10 名用户可以帮你内推
9 名用户可以帮你内推
推荐投递
科锐福克斯
国商信息
国商信息
国商信息
国商信息
国商信息
国商信息
北京科美划一科技有限公司