
六年后端经验,目前二线城市找机会回一线。
PS:事后我冷静下来,回忆思路大概花了 10+分钟,然后整个 coding 过程也就 15+分钟吧。
func QuickSort(arr []int) { if len(arr) == 0 { return } fmt.Println(arr) pv := 0 pl := 1 pr := len(arr) - 1 for pl <= pr { if pv < pl { // -- 右边 for arr[pv] < arr[pr] { pr -= 1 } arr[pv], arr[pr] = arr[pr], arr[pv] pv = pr pr -= 1 // fmt.Println(arr, pl, pr, pv) } else if pv > pr { // -- 左边 for arr[pv] > arr[pl] { pl += 1 } arr[pv], arr[pl] = arr[pl], arr[pv] pv = pl pl += 1 // fmt.Println(arr, pl, pr, pv) } } QuickSort(arr[:pv]) QuickSort(arr[pv+1:]) } 1 BenWang 240 天前 35+ 以后不打算面试了,没上进心了,等被裁,然后躺平。 |
2 lasuar 240 天前 没准备到位。 |
5 xuzhzzz 240 天前 云原生岗位就谈了个 docker-compose 项目落地到 K8S 吗 |
6 emSaVya 240 天前 一面挂确实太伤了。大概率以后都没机会再面了。 |
7 ldx78203199 240 天前 讲道理 一面问题不难,快排算是送分题 |
8 hahasong 240 天前 还是第一次见这样写快排,这比较条件很绕 |
9 Yc1992 240 天前 你这快排复盘都没写对 |
10 youyouzi 239 天前 为什么你的快排写这么复杂啊? function quickSort(arr) { if (arr.length <= 1) { return arr; } const pivot = arr[0]; const left = []; const right = []; for (let i = 1; i < arr.length; i++) { if (arr[i] < pivot) { left.push(arr[i]); } else { right.push(arr[i]); } } return [...quickSort(left), pivot, ...quickSort(right)]; } 这样不是蛮简单? |
11 youyang 239 天前 有时候也靠运气 |
12 klusfq OP @ldx78203199 主要是太久没写,加上大脑宕机了,确实可惜。。。 |
19 Yc1992 239 天前 @klusfq #13 for arr[pv] > arr[pl] { pl += 1 } 当 pv=0, 所有 arr[pl]都< arr[0] 的时候,index 直接越界了 你有打的功夫 不如自己问问 ai 代码哪里有问题 |
20 allencloud 239 天前 GC 的最佳实践问题 怎么问的,应该怎么答?让我抄抄答案。。。 太惭愧了,自己在中厂,OOM 都是通过加容器内存解决的。。。 |
21 OP @Yc1992 首先,我很感谢你指出我 coding 的问题; 其次,这个代码我基本就是回忆+vi 裸写,快速过了面试官 case 就到此为止了; 再次,你如果愿意指教就别卖关子,不愿意也无所谓; 最后,发帖本来就是为了分享经验,社区交流本来就互通有无,请别以那种高高在上的姿态在那儿点评; PS:边界 case 没处理到位这是 bug ,至少思路没错,不知道你的优越感打哪儿来的。 |
22 klusfq OP @allencloud 在 Go 语言中编写 GC 友好的代码是优化程序性能的关键。以下是一些实践建议,旨在减少垃圾收集器的压力并提高程序的运行效率: 1. 对象池复用:对于频繁创建和销毁的小对象,可以使用对象池来复用对象,避免频繁的内存分配和回收。但需注意,对象池不适合所有场景,特别是对象较大或内存管理复杂时,可能会增加同步开销。 2. 避免短生命周期的大对象:尽量减少大对象的临时使用,因为它们会快速晋升到老生代,增加 GC 的负担。 3. 控制并发内存分配:在高并发场景下,过多的并发内存分配会增加 GC 的频率,考虑使用同步池等机制来集中管理内存分配。 4. 减少不必要的指针使用:无指针值的传递和存储可以减少 GC 的工作量,尤其是在数据结构中,如果不需要通过指针访问,尽量使用值类型。 5. 结构体字段布局优化:将指针字段放在结构体的前面,非指针字段放在后面,这样 GC 可以更快地完成扫描。 6. 利用逃逸分析减少分配:理解逃逸分析的工作原理,编写代码以避免不必要的堆分配。可以通过编译器标志(如-gcflags=-m )来查看哪些对象逃逸到了堆上,并尝试优化。 7. 字符串拼接避免使用+或 fmt.Sprintf:频繁的字符串拼接会导致大量临时字符串对象的生成,考虑使用 strings.Builder 或 bytes.Buffer 来累积字符串。 8. 合理设置 GC 参数:根据应用的具体情况调整 GC 的参数,如设置合适的堆增长因子、调整 GC 触发的阈值,但需谨慎,不当的调整可能适得其反。 9. 并发标记与清理:了解 Go 的 GC 机制,特别是从 Go 1.5 版本开始引入的三色标记法及其并发收集的改进,这有助于理解为何某些代码实践对 GC 友好。 10. 避免内存泄漏:确保所有资源在不再需要时被正确释放,避免长时间持有无用的对象引用,这直接关系到 GC 的效率。 来自 deepseek |
23 kivmi 236 天前 @youyouzi 你这个空间复杂度上去了,最好还是使用原地快排,楼主那个是原地快排 func quickSortInPlace(arr []int, low, high int) { if low < high { p := partition(arr, low, high) // 分区操作 quickSortInPlace(arr, low, p-1) quickSortInPlace(arr, p+1, high) } } func partition(arr []int, low, high int) int { pivot := arr[high] // 选最后一个元素为主元 i := low for j := low; j < high; j++ { if arr[j] < pivot { arr[i], arr[j] = arr[j], arr[i] // 交换 i++ } } arr[i], arr[high] = arr[high], arr[i] // 主元归位 return i } |
26 JZ8ZW193q6W9Awgy 234 天前 @klusfq #3 有房贷真的是一把枷锁,让人不能动弹。。。 |