程序员面试之葵花宝典1

我爱海鲸 2023-04-05 12:55:37 暂无标签

简介欲练此功,引刀自宫、相关面试题

2023-04-05 start

1、 分布式微服务如何保证数据一致性,请写出一般项目能用的可行性方案?

在分布式微服务架构中,数据一致性是一个非常重要的问题。因为数据被分布在不同的服务中,
如何确保这些服务之间的数据是一致的是一个挑战。以下是几个常用的可行性方案:

采用分布式事务:在分布式环境中,可以使用分布式事务来确保数据的一致性。
常见的分布式事务实现方式包括TCC、2PC、3PC等。通过这些机制,
可以保证在多个服务之间的数据操作是原子性的,要么全部执行成功,要么全部回滚。

使用消息队列:消息队列可以帮助不同的服务之间异步通信,从而降低服务之间的耦合度
,同时也可以保证数据的一致性。在服务执行某些操作时,可以将操作结果放入消息队列中
,然后订阅该队列的其他服务可以及时收到这个操作结果,并根据该结果更新本地数据。

最终一致性:最终一致性是一种折衷的方案,它允许在某个时间点上不同的服务之间的数据不一致,
但是在一段时间后最终会一致。通过这种方案,可以在一定程度上降低分布式事务和消息队列的复杂度。

需要注意的是,在具体实现时,需要根据业务需求和系统规模等因素综合考虑,选择最适合自己的方案。

2、为什么会发生线程安全,请举例说明?

线程安全是指多线程访问共享资源时,不会发生意外的结果。
当多个线程并发地访问同一个共享资源时,如果没有适当的控制,
就可能会导致一些线程修改了其他线程的数据,或者读取到了不一致的数据,从而引发一些问题。

以下是一些可能会导致线程安全问题的例子:

竞态条件:竞态条件指的是多个线程执行的顺序和时间不确定,从而导致共享资源的结果也不确定。
例如,多个线程并发地对一个计数器进行操作,如果没有适当的同步,就可能导致计数器的值不正确。

数据竞争:数据竞争指的是多个线程并发地对同一块内存区域进行读写操作,
而且至少有一个线程在写入。如果没有适当的同步,就可能导致内存中的数据出现不一致的情况。
例如,一个线程正在修改一个对象的属性,而另一个线程正在读取该对象的属性。

死锁:死锁指的是多个线程之间互相等待对方释放资源,从而导致所有线程都无法继续执行。
例如,线程A持有资源X,而线程B持有资源Y,线程A想要获取资源Y,线程B想要获取资源X
,两个线程都在等待对方释放资源,从而陷入死锁状态。

为了避免线程安全问题,需要使用适当的同步机制来确保多个线程之间的协调和同步。
常用的同步机制包括锁、信号量、条件变量等。同时,在编写多线程程序时,
需要注意对共享资源的访问方式和顺序,以及避免死锁等问题的出现。

3、 为什么不能用Redis替代MySQL?

Redis和MySQL都是不同类型的数据库,虽然它们都有存储和检索数据的功能,
但是它们有着不同的适用场景和优缺点。

Redis是一种内存数据库,数据存储在内存中,因此读取和写入数据的速度非常快。
它主要用于缓存和实时数据处理,例如用户会话数据、队列等。
但是,Redis不支持关系型数据模型,因此不适合存储结构化的数据。

MySQL是一种关系型数据库,它支持复杂的查询操作,并且具有数据完整性和一致性等特性,
可以用于存储结构化的数据。虽然它的读写速度不如Redis,但是它可以存储大量的数据,并且可以支持多种数据类型和索引。

因此,不能用Redis替代MySQL,因为它们是不同类型的数据库,适用于不同的应用场景。
如果需要存储结构化数据并进行复杂的查询操作,应该选择MySQL或其他关系型数据库。
如果需要缓存或实时数据处理等快速读写操作,可以使用Redis或其他内存数据库。

4、 哪些sql写法会使索引失效?

索引可以提高数据库查询性能,但是某些SQL写法可能会导致索引失效,
使查询变得缓慢,甚至导致全表扫描。以下是一些可能导致索引失效的SQL写法:

在WHERE子句中使用非函数表达式,例如:WHERE UPPER(column_name) = 'VALUE',
这会导致索引失效,因为函数会对列的值进行操作,使索引无法使用。

在LIKE子句中使用通配符(%),例如:WHERE column_name LIKE '%VALUE%',
这会导致索引失效,因为索引只能用于前缀匹配的情况。

在WHERE子句中使用不等于(<>)操作符,例如:WHERE column_name <> 'VALUE',
这会导致索引失效,因为不等于操作符无法使用索引。

在JOIN子句中使用不等于(<>)操作符,
例如:INNER JOIN table2 ON table1.column_name <> table2.column_name,
这会导致索引失效,因为不等于操作符无法使用索引。

在SELECT子句中使用函数,例如:SELECT COUNT(column_name),这会导致索引失效,
因为函数会对列的值进行操作,使索引无法使用。

在ORDER BY子句中使用非索引列排序,例如:ORDER BY non_index_column_name,
这会导致索引失效,因为MySQL需要对整个结果集进行排序,而不仅仅是索引列。

在GROUP BY子句中使用非索引列分组,例如:GROUP BY non_index_column_name,
这会导致索引失效,因为MySQL需要对整个结果集进行分组,而不仅仅是索引列。

在查询中使用OR操作符,例如:WHERE column_name = 'VALUE' OR column_name = 'VALUE2',
这会导致索引失效,因为MySQL无法同时使用多个索引。

综上所述,为了避免索引失效,应该尽可能使用简单的WHERE子句和JOIN子句,
避免在查询中使用函数、通配符、不等于操作符等。如果必须使用这些操作符,
可以考虑创建复合索引或使用全文索引等技术来提高查询性能。

5、列举你所熟悉的Linux命令。

ls:列出当前目录下的文件和文件夹。

cd:切换当前工作目录。

pwd:显示当前工作目录的路径。

mkdir:创建一个新的目录。

touch:创建一个新的空文件或更新一个已有文件的时间戳。

cp:复制文件或目录。

mv:移动文件或目录,或者更改文件或目录的名称。

rm:删除文件或目录。

cat:显示文件的内容。

less:按页显示文件内容。

grep:在文件中查找匹配的字符串。

find:在文件系统中查找符合指定条件的文件或目录。

chmod:更改文件或目录的权限。

chown:更改文件或目录的所有者。

ps:显示当前正在运行的进程信息。

top:实时显示系统资源的使用情况。

tar:打包和解压缩文件。

ssh:通过网络连接到远程计算机。

scp:在本地计算机和远程计算机之间复制文件。

wget:从网络下载文件。

6、在我的工作中,我使用了许多设计模式来帮助我实现各种业务需求。以下是我用到的一个设计模式的例子

设计模式:观察者模式(Observer Pattern)

使用场景:当一个对象的状态发生变化时,需要通知其他对象,
并在不改变对象之间的耦合性的情况下实现这种通知机制。

如何使用:首先定义一个Subject接口或抽象类,该接口或抽象类包含添加、
删除和通知观察者的方法。然后定义一个Observer接口或抽象类,
该接口或抽象类包含接收Subject通知的方法。接着实现具体的Subject类和Observer类,
具体的Subject类包含状态信息,并在状态发生变化时通知观察者,
具体的Observer类实现接收Subject通知的方法,并在接收到通知时执行相应的操作。
最后,在程序中创建Subject对象和多个Observer对象,将Observer对象注册到Subject对象中
,并在Subject对象的状态发生变化时通知所有的Observer对象。

用途:我曾经在一个电商平台的项目中使用了观察者模式。在该项目中,
用户可以订阅自己感兴趣的商品,并在商品降价或库存有货时收到通知。
为了实现这一功能,我创建了一个Subject类来表示商品,
创建了一个Observer类来表示用户,
并在Subject对象的状态发生变化时通知所有订阅了该商品的Observer对象。
通过使用观察者模式,我成功地实现了电商平台中的商品订阅功能,提高了用户的购物体验。

7、 有一个100T超大文件,每行是一条员工信息,格式:姓名、年龄、性别、部门,找出公司年龄最大的男女员工分别是谁,写出内存使用率最优解算法思路。

由于文件非常大,不能一次性将整个文件读入内存中处理,因此我们需要采用一种分块处理的方法来解决这个问题。

算法思路如下:

首先将100T的文件拆分成多个小文件,每个小文件包含一定数量的员工信息记录,
这个数量需要根据系统内存大小和处理效率来确定。

对于每个小文件,我们可以使用内存中的哈希表或红黑树等数据结构来存储员工信息,
并根据年龄来判断是否需要更新最大年龄员工的记录。

每个小文件处理完毕后,将最大年龄员工记录保存到磁盘文件中,然后释放内存资源。

所有小文件处理完毕后,我们需要再次遍历磁盘中保存的最大年龄员工记录,
来确定公司中年龄最大的男女员工。

对于男女员工分别使用两个变量来保存最大年龄和员工姓名,遍历最大年龄员工记录,
当记录中的性别为男时,比较记录中的年龄和当前保存的最大年龄,如果年龄更大,
则更新最大年龄和员工姓名;当记录中的性别为女时,同理比较年龄并更新。

这种分块处理的方法可以降低内存使用率,并且通过调整每个小文件的大小,
可以在保证效率的前提下降低磁盘I/O的开销。同时,
使用哈希表或红黑树等数据结构可以提高员工信息的查找效率,实现快速的记录更新和查询。

8、有100个球,3个人(包括你),每次只能拿1个或者2个球,怎么才能保证你最后一个拿?

假设三个人的编号为A、B、C,其中A是你自己。

为了保证你能最后一个拿到球,我们可以采用以下策略:

首先,你必须保证在第一轮中拿到球的数量是1或2个。

如果你在第一轮中拿了1个球,那么你的下一步就是保证你每次都能拿到2个球,
这样你就能在最后一轮中拿到最后一个球。

如果你在第一轮中拿了2个球,那么你的下一步就是保证你每次都能拿到1个球,
这样你也能在最后一轮中拿到最后一个球。

如果你的对手也采用了和你相同的策略,并且在第一轮中拿了1个球,那么你可以在第二轮中拿2个球,
让自己恢复到最优策略。同理,如果对手在第一轮中拿了2个球,
那么你可以在第二轮中拿1个球,让自己恢复到最优策略。

通过这种策略,你可以保证最后一个拿到球的机会,
前提是你的对手们也是聪明的,能够采用最优策略。

9、一个商人花80块钱买了一件衣服,90块钱卖掉了,然后他觉得不划算,花100块钱又买回来了,过段时间110块又卖给同一个人。问他赚了多少或者亏了多少?

商人花了80元买了这件衣服,然后以90元的价格将其卖掉,这样他赚了10元。

但是,商人又花了100元将这件衣服买回来,然后以110元的价格又将其卖掉。
这样,他总共花费了80 + 100 = 180元,总共收入了90 + 110 = 200元。

因此,他赚了200 - 180 = 20元,也就是说他赚了20元钱。

10、 烧一根不均匀的木棍要用20分钟,现在有若干相同的木棍,问如何计时5分钟呢?

可以使用以下步骤计时5分钟:

将两根木棍并排放置,然后点燃两端。

等到其中一端的木棍燃烧完毕,也就是用去了20分钟的时间后,
将另一根木棍翻过来,使其燃烧的另一端接触着燃烧的木棍。

等到这根木棍燃烧完毕,也就是用去了5分钟的时间后,就可以停止计时了。

通过这种方法,我们可以使用不均匀的木棍来计时5分钟。
需要注意的是,要选择相同的木棍,并且保证两端的长度差异不要太大,以保证计时的准确性。

end

 

你好:我的2025