Python面试题及答案2024百度,本着什么原则,才能写出优秀的代码,2024Python大厂面试知识分享

举个例子:

page = data[‘page’]

size = data[‘size’]

这样的写法就没有下面的写法好:

page = data.get(‘page’, 1)

size = data.get(‘size’, 10)

继续,项目中依赖的库是不是及时升级更新了?

积极,及时的升级可以避免跨大版本升级,因为跨大版本升级往往会带来很多问题。

还有就是在遇到一些安全漏洞时,升级是一个很好的解决办法。

最后一点,单元测试完善吗?覆盖率高吗?

说实话,程序员喜欢写代码,但往往不喜欢写单元测试,这是很不好的习惯。

有了完善,覆盖率高的单元测试,才能提高项目整体的健壮性,才能把因为修改代码带来的 BUG 的可能性降到最低。

重构

随着代码规模越来越大,重构是每一个开发人员都要面对的功课,Martin Fowler 将其定义为:在不改变软件外部行为的前提下,对其内部结构进行改变,使之更容易理解并便于修改。

重构的收益是明显的,可以提高代码质量和性能,并提高未来的开发效率。

但重构的风险也很大,如果没有理清代码逻辑,不能做好回归测试,那么重构势必会引发很多问题。

这就要求在开发过程中要特别注重代码质量。除了上文提到的一些规范之外,还要注意是不是滥用了面向对象编程原则,接口之间设计是不是过度耦合等一系列问题。

那么,在开发过程中,有没有一个指导性原则,可以用来规避这些问题呢?

当然是有的,接着往下看。

高级阶段


最近刚读完一本书,Bob 大叔的**《架构整洁之道》**,感觉还是不错的,收获很多。

全书基本上是在描述软件设计的一些理论知识。大体分成三个部分:编程范式(结构化编程、面向对象编程和函数式编程),设计原则(主要是 SOLID),以及软件架构(其中讲了很多高屋建翎的内容)。

总体来说,这本书中的内容可以让你从微观(代码层面)和宏观(架构层面)两个层面对整个软件设计有一个全面的了解。

其中 SOLID 就是指面向对象编程和面向对象设计的五个基本原则,在开发过程中适当应用这五个原则,可以使软件维护和系统扩展都变得更容易。

五个基本原则分别是:

  1. 单一职责原则(SRP)

  2. 开放封闭原则(OCP)

  3. 里氏替换原则(LSP)

  4. 接口隔离原则(ISP)

  5. 依赖倒置原则(DIP)

单一职责原则(SRP)

A class should have one, and only one, reason to change. – Robert C Martin

一个软件系统的最佳结构高度依赖于这个系统的组织的内部结构,因此每个软件模块都有且只有一个需要被改变的理由。

这个原则非常容易被误解,很多程序员会认为是每个模块只能做一件事,其实不是这样。

举个例子:

假如有一个类 T,包含两个函数,分别是 A()B(),当有需求需要修改 A() 的时候,但却可能会影响 B() 的功能。

这就不是一个好的设计,说明 A()B() 耦合在一起了。

开放封闭原则(OCP)

Software entities should be open for extension, but closed for modification. – Bertrand Meyer, Object-Oriented Software Construction

如果软件系统想要更容易被改变,那么其设计就必须允许新增代码来修改系统行为,而非只能靠修改原来的代码。

通俗点解释就是设计的类对扩展是开放的,对修改是封闭的,即可扩展,不可修改。

看下面的代码示例,可以简单清晰地解释这个原则。

void DrawAllShape(ShapePointer list[], int n)

{

int i;

for (i = 0; i < n; i++)

{

struct Shape* s = list[i];

switch (s->itsType)

{

case square:

DrawSquare((struct Square*)s);

break;

case circle:

DrawSquare((struct Circle*)s);

break;

default:

break;

}

}

}

上面这段代码就没有遵守 OCP 原则。

假如我们想要增加一个三角形,那么就必须在 switch 下面新增一个 case。这样就修改了源代码,违反了 OCP 的封闭原则。

缺点也很明显,每次新增一种形状都需要修改源代码,如果代码逻辑复杂的话,发生问题的概率是相当高的。

class Shape

{

public:

virtual void Draw() const = 0;

}

class Square: public Shape

{

public:

virtual void Draw() const;

}

class Circle: public Shape

{

public:

virtual void Draw() const;

}

void DrawAllShapes(vector<Shape*>& list)

{

vector<Shape*>::iterator I;

for (i = list.begin(): i != list.end(); i++)

{

(*i)->Draw();

}

}

通过这样修改,代码就优雅了很多。这个时候如果需要新增一种类型,只需要增加一个继承 Shape 的新类就可以了。完全不需要修改源代码,可以放心扩展。

里氏替换原则(LSP)

Require no more, promise no less.– Jim Weirich

这项原则的意思是如果想用可替换的组件来构建软件系统,那么这些组件就必须遵守同一个约定,以便让这些组件可以相互替换。

里氏替换原则可以从两方面来理解:

第一个是继承。如果继承是为了实现代码重用,也就是为了共享方法,那么共享的父类方法就应该保持不变,不能被子类重新定义。

子类只能通过新添加方法来扩展功能,父类和子类都可以实例化,而子类继承的方法和父类是一样的,父类调用方法的地方,子类也可以调用同一个继承得来的,逻辑和父类一致的方法,这时用子类对象将父类对象替换掉时,当然逻辑一致,相安无事。

第二个是多态,而多态的前提就是子类覆盖并重新定义父类的方法。

为了符合 LSP,应该将父类定义为抽象类,并定义抽象方法,让子类重新定义这些方法。当父类是抽象类时,父类就是不能实例化,所以也不存在可实例化的父类对象在程序里,也就不存在子类替换父类实例(根本不存在父类实例了)时逻辑不一致的可能。

举个例子:

看下面这段代码:

class A{

public int func1(int a, int b){

return a - b;

}

}

public class Client{

public static void main(String[] args){

A a = new A();

System.out.println(“100-50=” + a.func1(100, 50));

System.out.println(“100-80=” + a.func1(100, 80));

}

}

输出;

100-50=50

100-80=20

现在,我们新增一个功能:完成两数相加,然后再与 100 求和,由类 B 来负责。即类 B 需要完成两个功能:

  1. 两数相减

  2. 两数相加,然后再加 100

现在代码变成了这样:

class B extends A{

public int func1(int a, int b){

return a + b;

}

public int func2(int a, int b){

return func1(a,b) + 100;

}

}

public class Client{

public static void main(String[] args){

B b = new B();

System.out.println(“100-50=” + b.func1(100, 50));

System.out.println(“100-80=” + b.func1(100, 80));

System.out.println(“100+20+100=” + b.func2(100, 20));

}

}

输出;

100-50=150

100-80=180

100+20+100=220

可以看到,原本正常的减法运算发生了错误。原因就是类 B 在给方法起名时重写了父类的方法,造成所有运行相减功能的代码全部调用了类 B 重写后的方法,造成原本运行正常的功能出现了错误。

这样做就违反了 LSP,使程序不够健壮。更通用的做法是:原来的父类和子类都继承一个更通俗的基类,原有的继承关系去掉,采用依赖、聚合,组合等关系代替。

接口隔离原则(ISP)

Clients should not be forced to depend on methods they do not use. –Robert C. Martin

软件设计师应该在设计中避免不必要的依赖。

ISP 的原则是建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法要尽量少。

也就是说,我们要为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。

在程序设计中,依赖几个专用的接口要比依赖一个综合的接口更灵活。

单一职责与接口隔离的区别:

  1. 单一职责原则注重的是职责;而接口隔离原则注重对接口依赖的隔离。

  2. 单一职责原则主要是约束类,其次才是接口和方法,它针对的是程序中的实现和细节; 而接口隔离原则主要约束接口。

举个例子:

首先解释一下这个图的意思:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img



既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Python开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注Python)
img

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、全套PDF电子书

书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。

四、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

五、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-N6CVhZWt-1712442773131)]

  • 18
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值