首页 > 数据库 > 数据库开发技术 > 美团二面,我是没想到还是AI
AI:是时候展示真正的技术了...动态题目、回答追问、智能评估。。。
美团的骑手“进门难”的问题近期备受社会关注,不过在秋招阶段很多技术同学也反馈入团难的问题。
因为前面文章中我也有介绍过,美团秋招会第一轮就直接使用AI面试官了。
这个问题不知道是否跟使用的AI面试有关系呢?
关于AI技术面试有关的题型和应对方式方法,请阅读前面的文章(文末附直接访问)。
有美团后端秋招的同学反馈,以为开团用AI技术面试后,后面就直接是真人面试了,没想到二面还是AI!
不过同学反馈问的问题倒是挺专业的,而且全程无废话,无刁难,难度也适中。
这里我也稍微整理下涉及到的面试技术点,希望能帮到大家。
应用层:为特定应用程序提供数据传输服务,例如 HTTP、DNS 等协议。数据单位为报文。
传输层(运输层):为进程提供通用数据传输服务。由于应用层协议很多,定义通用的传输层协议就可以支持不断增多的应用层协议。运输层包括两种协议:传输控制协议 TCP,提供面向连接、可靠的数据传输服务,数据单位为报文段;用户数据报协议 UDP,提供无连接、尽最大努力的数据传输服务,数据单位为用户数据报。TCP 主要提供完整性服务,UDP 主要提供及时性服务。
网络层:为主机提供数据传输服务。而传输层协议是为主机中的进程提供数据传输服务。网络层把传输层传递下来的报文段或者用户数据报封装成分组。
数据链路层:网络层针对的还是主机之间的数据传输服务,而主机之间可以有很多链路,链路层协议就是为同一链路的主机提供数据传输服务。数据链路层把网络层传下来的分组封装成帧。
物理层:考虑的是怎样在传输媒体上传输数据比特流,而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异。
其中表示层和会话层用途如下:
表示层 :数据压缩、加密以及数据描述,这使得应用程序不必关心在各台主机中数据内部格式不同的问题。
会话层 :建立及管理会话。
五层协议没有表示层和会话层,而是将这些功能留给应用程序开发者处理。
在向下的过程中,需要添加下层协议所需要的首部和尾部,而在向上的过程中不断拆开首部和尾部。
路由器只有下面三层协议,因为路由器位于网络核心中,不需要为进程或者应用程序提供服务,因此也就不需要传输层和应用层。
1、使用 dmesg 命令
这个命令用来查看内核启动时产生的日志信息,通常包含硬件检测和加载模块等信息。
dmesg
如果想要查看更早的日志或者保存的输出,可以用 -T 参数来显示时间戳,或者用 -c 清除现有的日志。
dmesg -T
2、使用 journalctl 命令
journalctl 是 Systemd 系统和服务管理器的一部分,用来查看由 Systemd 产生的日志。它非常灵活,可以查看从启动到现在的所有日志。
journalctl -b
小贴士
如果你想查看启动时某个特定服务的日志,可以使用
journalctl -u <service>.service。
3、/var/log/messages
有些系统可能会将日志记录到 /var/log/messages 文件中,这个文件类似于 syslog,也是记录系统运行期间的各种日志。
less /var/log/messages
无缓冲的 channel 是同步的,而有缓冲的 channel 是异步的。
空(nil)channel:
已经关闭的 channel:
value, ok := <-stop接收到的value会返回一个零值,并且的ok等于false。注意:
有一个向通道发送数据的 goroutine 和一个从通道接收数据的 goroutine,如果发送方在关闭通道之前已经发送了一些数据,但接收方还没有接收这些数据,那么在通道关闭后,接收方仍然可以从通道中接收到这些数据,每次接收操作都会返回
true的ok值,直到所有数据都被接收完毕,才会返回返回false的ok值。
如果按锁粒度划分,有以下3种,包含了他们的区别
表锁:开销小,加锁快;锁定力度大,发生锁冲突概率高,并发度最低;不会出现死锁。
行锁:开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高。
页锁:开销和加锁速度介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般。
选择性原则:对于经常用于筛选(特别是作为 WHERE 子句的一部分)的列创建索引。选择性高的列更适合作为索引的依据,即那些具有高唯一值比例的列。
频繁查询原则:为经常出现在 SELECT 查询中的列创建索引。特别是那些被频繁用来做 JOIN 或者 GROUP BY 的列。
排序和分组原则:如果一个列经常被用来进行 ORDER BY 或 GROUP BY 操作,则考虑为该列创建索引。
最左前缀原则:在复合索引中,查询使用的索引字段顺序应该与索引定义的顺序一致,并且从最左边开始。例如,如果索引是 (A, B, C),那么 WHERE A = ? 和 WHERE A = ? AND B = ? 都可以使用这个索引,但 WHERE B = ? 则不能。
避免更新频繁的列:尽量不要为经常更新的列创建索引,因为每次数据更新时索引也需要更新,这会增加写操作的时间开销。
覆盖索引原则:创建包含所有查询需要字段的索引,这样数据库可以直接从索引中获取数据,而不需要额外访问表数据(这被称为“覆盖索引”或“索引覆盖”)。
限制索引数量:每个表上的索引数量应该有限制,过多的索引会降低写操作的性能。考虑到每个索引都会占用存储空间,因此要平衡索引带来的读取性能提升和额外的存储成本。
使用合适的数据类型:索引列应尽量使用适合的数据类型,以减少索引的大小并提高性能。比如主键索引,大多数情况都会使用整型,二叔字符串。
简单的可以从如下方面进行介绍
在实现技术细节中,我们加上并发控制的代码示例。
package main
import (
"context"
"fmt"
"net/smtp"
"sync"
"time"
"gopkg.in/gomail.v2"
)
// EmailTask 结构体表示一个待发送的邮件任务
type EmailTask struct {
To string
Subject string
Body string
}
// sendEmail 发送单个邮件
func sendEmail(task EmailTask) error {
m := gomail.NewMessage()
m.SetHeader("From", "your-email@example.com")
m.SetHeader("To", task.To)
m.SetHeader("Subject", task.Subject)
m.SetBody("text/html", task.Body)
dialer := gomail.NewDialer("smtp.example.com", 587, "your-email@example.com", "your-password")
if err := dialer.DialAndSend(m); err != nil {
return fmt.Errorf("failed to send email: %w", err)
}
return nil
}
// worker 是一个 goroutine 函数,它不断地从队列中取出任务并执行
func worker(id int, tasks chan EmailTask, wg *sync.WaitGroup) {
defer wg.Done()
for task := range tasks {
fmt.Printf("Worker %d processing email to %s\n", id, task.To)
if err := sendEmail(task); err != nil {
fmt.Printf("Error sending email to %s: %v\n", task.To, err)
} else {
fmt.Printf("Email sent to %s\n", task.To)
}
}
}
func main() {
// 初始化邮件队列
tasks := make(chan EmailTask, 10)
// 创建 WaitGroup 以等待所有 workers 完成
var wg sync.WaitGroup
// 启动 5 个 workers
const numWorkers = 5
for i := 0; i < numWorkers; i++ {
wg.Add(1)
go worker(i+1, tasks, &wg)
}
// 添加一些任务到队列中
go func() {
tasks <- EmailTask{"alice@example.com", "Welcome!", "Welcome to our service!"}
tasks <- EmailTask{"bob@example.com", "Reset Password", "Please reset your password."}
tasks <- EmailTask{"charlie@example.com", "Important Update", "We have important updates for you."}
close(tasks)
}()
// 等待所有 workers 完成
wg.Wait()
fmt.Println("All emails have been processed.")
}
解读main.go
初始化一个 tasks队列。创建一个 WaitGroup用于同步。启动多个 workers 处理队列中的任务。 向队列中添加几个示例任务。 关闭队列,并等待所有 workers 完成。
注意事项
以上,点亮【赞与在看】让我们心中充满力量、披荆斩棘、不惧未来!
【推荐阅读】
关于作者:一位热爱技术,并在职场与自媒体间探索的实践者,希望通过分享个人经验和见解,帮助更多人实现自我成长和价值。
如果您对我的公众号内容感兴趣,欢迎关注我。
也可以在下方添加我微信和一支烟花AI社区技术群,一起交流技术、职场心得。
原文作者:皇子谈技术;如有侵权,请联系管理员删除。