贝壳找房,开的薪资很满意。

科技   2024-11-06 14:04   河南  

大家好,我是二哥呀。

贝壳找房也开奖了,星球里有球友拿到了大 SP,让他开始犹豫了起来。

贝壳算是房地产行业方面的 TOP,业务涵盖二手房、新房交易以及家装家居,百度百科显示:

2024年8月12日,贝壳发布2024年第二季度财务业绩,报告期内,净利润为26.9亿元,同比增长13.9%。

我也统计了一波 25 届秋招的开奖信息,放在了 Java 面试指南中,同步给大家参考一下。

  • 同学 1,25k*16,Java 岗,没透露学校,说爱了,还挺满意的。
  • 同学 2,总包 35 万,wlb 部门,学习没透露,说对贝壳的工作氛围很感兴趣
  • 同学 3,东南大学,总包 37,开发语言是 Go
  • 同学 4,本科 92(没说 9 还是 2),开了 23*16,后端开发岗

总体来说,比较符合贝壳的薪资定位,去年有硕士 211 的同学反馈说只给 18k 的侮辱价,今年算是比较大方的情况了,尤其是贝壳在业界竟然还有“WLB”的说法。

接下来,我们就以Java 面试指南中收录的同学 1 贝壳找房后端技术一面为例来看看,贝壳找房的面试官水准到底咋样。

背八股就认准三分恶的面渣逆袭

同学 1 贝壳找房后端技术一面

简单介绍一下项目

技术派是一个前后端分离的,面向互联网开发者的技术内容分享与交流平台,包括前端 PC 和管理后台。我们通过文章、教程、AI 助手等产品和服务,旨在打造一个激发开发者创作灵感,传播优质技术内容,陪伴开发者快速成长的技术社区。作为核心研发人员,我主要负责登录认证、消息通知、文章教程、AI 助手,以及管理后台的开发工作。

Spring用了什么设计模式

三分恶面渣逆袭:Spring中用到的设计模式

Spring 框架中用了蛮多设计模式的:

①、比如说工厂模式用于 BeanFactory 和 ApplicationContext,实现 Bean 的创建和管理。

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyBean myBean = context.getBean(MyBean.class);

②、比如说单例模式,这样可以保证 Bean 的唯一性,减少系统开销。

ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService1 = context.getBean(MyService.class);
MyService myService2 = context.getBean(MyService.class);

// This will print "true" because both references point to the same instance
System.out.println(myService1 == myService2);

③、比如说 AOP 使用了代理模式来实现横切关注点(如事务管理、日志记录、权限控制等)。

@Transactional
public void myTransactionalMethod() {
    // 方法实现
}

bean生命周期

Bean 的生命周期大致分为五个阶段:

三分恶面渣逆袭:Bean生命周期五个阶段
  • 实例化:Spring 首先使用构造方法或者工厂方法创建一个 Bean 的实例。在这个阶段,Bean 只是一个空的 Java 对象,还未设置任何属性。
  • 属性赋值:Spring 将配置文件中的属性值或依赖的 Bean 注入到该 Bean 中。这个过程称为依赖注入,确保 Bean 所需的所有依赖都被注入。
  • 初始化:Spring 调用 afterPropertiesSet 方法,或通过配置文件指定的 init-method 方法,完成初始化。
  • 使用中:Bean 准备好可以使用了。
  • 销毁:在容器关闭时,Spring 会调用 destroy 方法或 destroy-method 方法,完成 Bean 的清理工作。

bean是单例还是多例的,具体怎么修改

在 Spring 中,Bean 默认是单例的,即在整个 Spring 容器中,每个 Bean 只有一个实例。

可以通过在配置中指定 scope 属性,将 Bean 改为多例(Prototype)模式,这样每次获取的都是新的实例。

@Bean
@Scope("prototype")  // 每次获取都是新的实例
public MyBean myBean() {
    return new MyBean();
}

除了单例和多例,Spring 还支持其他作用域,如请求作用域(Request)、会话作用域(Session)等,适合 Web 应用中特定的使用场景。

三分恶面渣逆袭:Spring Bean支持作用域

为什么用b+树不用b树

B+ 树相比 B 树有几个显著优势:

首先,B+ 树的叶子节点通过链表相连,非常适合范围查询,如 ORDER BY 和 BETWEEN。

极客时间:B+树

只需要找到符合条件的第一个叶子节点,顺序扫描后续的叶子节点就可以了。相比之下,B 树的每次范围查询都需要回溯到父节点,查询效率较低。

极客时间:B 树

其次,B+ 树的非叶子节点不存储数据,能包含更多的键值指针,因此在相同节点容量下,B+ 树的层级更少,树的高度更低。较少的树层级意味着查找路径更短,从而减少磁盘 I/O 次数。

联合索引 (a, b),where a = 1 和 where b = 1,效果是一样的吗

不一样。

WHERE a = 1 能有效利用联合索引,因为 a 是联合索引的第一个字段,符合最左前缀匹配原则。而 WHERE b = 1 无法利用该联合索引,因为缺少 a 的匹配条件,MySQL 会选择全表扫描。

我们来验证一下,假设有一个 ab 表,建立了联合索引 (a, b)

CREATE TABLE ab (
    a INT,
    b INT,
    INDEX ab_index (a, b)
);

插入数据:

INSERT INTO ab (a, b) VALUES (12), (13), (21), (33), (22);

执行查询:

二哥的Java 进阶之路:最左前缀匹配的差异

通过 explain 可以看到,WHERE a = 1 使用了联合索引,而 WHERE b = 1 需要全表扫描,依次检查每一行。

事务ACID

事务是一个或多个 SQL 语句组成的一个执行单元,这些 SQL 语句要么全部执行成功,要么全部不执行,不会出现部分执行的情况。主要作用是保证数据库操作的一致性。

事务具有四个基本特性,也就是通常所说的 ACID 特性,即原子性、一致性、隔离性和持久性。

三分恶面渣逆袭:事务四大特性

慢查询怎么分析

首先,需要找到哪些 SQL 比较慢,可以启用慢查询日志,记录超过指定执行时间的查询。

也可以使用 show processlist; 查看当前正在执行的 SQL 语句,找出执行时间较长的 SQL。

或者在业务基建中加入对慢 SQL 的监控,常见的方案有字节码插桩、连接池扩展、ORM 框架扩展。

三分恶面渣逆袭:发现慢 SQL

然后,使用 EXPLAIN 命令查看查询执行计划,判断查询是否使用了索引,是否存在全表扫描等问题。

EXPLAIN SELECT * FROM your_table WHERE conditions;

最后,根据分析结果,通过添加或优化索引、调整查询语句或者增加内存缓冲区来优化 SQL。

explain分析后, type的执行效率等级,达到什么级别比较合适

从高到低的效率排序是 system、const、eq_ref、ref、range、index 和 ALL。

一般情况下,建议 type 值达到 const、eq_ref 或 ref,因为这些类型表明查询使用了索引进行精确匹配,效率较高。

如果是范围查询,range 类型也是可以接受的。

通常要避免出现 ALL 类型,因为它表示全表扫描,性能最低。

设计一个秒杀场景

在设计秒杀系统时,我们需要考虑高并发、库存控制和系统的稳定性。

在请求到达时,通过 Redis 预扣库存,并将请求加入消息队列进行排队。消费者队列异步处理订单生成,并将订单写入数据库。

在这个过程中,我们通过 Redis 实现库存控制,防止超卖。同时,为了避免重复下单和恶意刷单,可以使用分布式锁和动态令牌机制。

最后,系统还可以加入限流、降级,以保证系统的高可用性。

内容参考字星球嘉宾苏三的文章

手撕:3个线程交替打印1-100(伪代码就可以) ,  怎么让main线程等待这3个线程执行完再执行

可以使用 synchronized 和 wait/notify 来控制线程交替执行。同时,可以使用 Thread.join() 方法来让 main 线程等待这 3 个线程完成。

class PrintTask implements Runnable {
    private static int number = 1;        // 共享变量
    private int threadId;                 // 当前线程的编号
    private static final Object lock = new Object();

    public PrintTask(int threadId) {
        this.threadId = threadId;
    }

    @Override
    public void run() {
        while (number <= 100) {
            synchronized (lock) {
                if (number % 3 == threadId) {   // 判断是否当前线程的打印轮次
                    System.out.println("Thread-" + threadId + " prints: " + number++);
                    lock.notifyAll();           // 唤醒其他等待的线程
                } else {
                    try {
                        lock.wait();             // 不是当前线程轮次,进入等待
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    // 主线程
    public static void main(String[] args) {
        Thread t1 = new Thread(new PrintTask(0)); // Thread-0
        Thread t2 = new Thread(new PrintTask(1)); // Thread-1
        Thread t3 = new Thread(new PrintTask(2)); // Thread-2

        t1.start();
        t2.start();
        t3.start();

        try {
            t1.join();  // main 线程等待 t1 完成
            t2.join();  // main 线程等待 t2 完成
            t3.join();  // main 线程等待 t3 完成
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("所有线程执行完毕,Main 线程开始执行");
    }
}

三个线程交替打印:

  • PrintTask 实现了 Runnable 接口,定义了线程执行的任务逻辑。
  • 每个线程有一个唯一的 threadId,用来控制轮次(0、1、2)。
  • 通过 number % 3 == threadId 判断是否是当前线程的轮次。如果是,则打印并递增 number,然后调用 notifyAll() 唤醒其他线程。
  • 如果不是当前线程的轮次,调用 wait() 进入等待状态,等待其他线程唤醒。

让 main 线程等待 3 个线程完成:使用 Thread.join() 方法让 main 线程等待 t1、t2 和 t3 执行完毕后再继续执行。

其他题目

  • ThreadLocal,使用场景,原理
  • ArrayList,讲讲其他的List
  • ArrayList线程安全版本的容器
  • HashMap原理
  • ConcurrentHashMap原理

这几个之前出现过的题目,推荐大家直接去看星球嘉宾三分恶的面渣逆袭。

ending

一个人可以走得很快,但一群人才能走得更远。二哥的编程星球已经有 6500 多名球友加入了,如果你也需要一个良好的学习环境,戳链接 🔗 加入我们吧。这是一个 编程学习指南 + Java 项目实战 + LeetCode 刷题 + 简历精修 的私密圈子,你可以阅读星球专栏、向二哥提问、帮你制定学习计划、和球友一起打卡成长。

两个置顶帖「球友必看」和「知识图谱」里已经沉淀了非常多优质的学习资源,相信能帮助你走的更快、更稳、更远

欢迎点击左下角阅读原文了解二哥的编程星球,这可能是你学习求职路上最有含金量的一次点击。

最后,把二哥的座右铭送给大家:没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟。共勉 💪。

沉默王二
技术文通俗易懂,吹水文风趣幽默。学 Java,认准二哥的网站 javabetter.cn
 最新文章