【算法岗面试】某小厂D机器学习

简介: (1)使实例对象变为可调用对象__call__类似在类中重载()运算符,使得类实例对象可以像调用普通函数一样,即使用对象名():

1.__call__魔法方法(完成)

(1)使实例对象变为可调用对象

__call__类似在类中重载()运算符,使得类实例对象可以像调用普通函数一样,即使用对象名()

class Pig:
    # 定义__call__方法
    def __call__(self,name,add):
        print("调用__call__()方法",name,add)
pig = Pig()
pig("你是猪吗?","不是哦")
# 调用__call__()方法 你是猪吗? 不是哦

通过在Pig类中实现__call__方法,使得实例对象pig变为可调用对象。对于可调用对象,名称()等价于名称.__call__。即上面的代码等价于为pig.__call__("你是猪吗?", "不是哦")。

python中的可调用对象:

自定义函数

python内置函数

上面的类实例对象

(2)弥补hasattr()函数短板

hasattr(当前对象, 属性)函数能够判断当前对象是否包含对应的属性 or 方法,但是不能判断同名情况,是指类属性 还是 类方法。

类实例对象包含的方法,也是可调用对象(有__call__()方法),但是类属性不是可调用对象。所以如下栗子的say类方法是可调用对象,拥有__call__()方法。

class CLanguage:
    def __init__ (self):
        self.name = "language"
        self.add = "english"
    def say(self):
        print("hello world!")
clangs = CLanguage()
if hasattr(clangs,"name"):
    print(hasattr(clangs.name,"__call__"))
print("**********")
if hasattr(clangs,"say"):
    print(hasattr(clangs.say,"__call__"))

(3)再来一个栗子

class Entity:
'''调用实体来改变实体的位置。'''
  def __init__(self, x):
      self.x = x
  def __call__(self):
      '''改变实体的位置'''
      print('self.x:', self.x)
entity = Entity(1)
entity()
================================
output:
self.x: 1

2.yield的用法

一个打印斐波那契数列的栗子:

def fab(max): 
    n, a, b = 0, 0, 1 
    while n < max: 
        yield b      # 使用 yield
        # print b 
        a, b = b, a + b 
        n = n + 1
for n in fab(5): 
    print (n)

yield 的作用就是把一个函数变成一个 generator,调用 fab(5) 不会执行 fab 函数,而是返回一个 iterable 对象!

在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b 时,fab 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。

也可以手动调用 fab(5) 的 next() 方法(因为 fab(5) 是一个 generator 对象,该对象具有 next() 方法):

>>>f = fab(5) 
>>> f.next() 
1 
>>> f.next() 
1 
>>> f.next() 
2 
>>> f.next() 
3 
>>> f.next() 
5 
>>> f.next() 
Traceback (most recent call last): 
 File "<stdin>", line 1, in <module> 
StopIteration

3.C++的左值和右值引用(没答上)

这玩意还要好好学学:C++11的左值引用与右值引用总结

4.input=8 ∗ 8 8*88∗8,filter=3 ∗ 3 3*33∗3,stride=1,padding=1卷积结果

padding后是9乘9,然后和卷积核运算后是7乘7。

5.GBDT的特征怎么选择

决策树常用于分类,目标就是将具有 P PP 维特征的 n nn 个样本分到 C CC 个类别中,相当于做一个映射 C = f ( n ) C = f(n)C=f(n) ,将样本经过一种变换赋予一个 l a b e l labellabel。可以把分类的过程表示成一棵树,每次通过选择一个特征 p i pipi 来进行进一步分叉分类。

决策树中的特征重要性,不像线性回归一样可以用系数表示特征重要性。而根据每次分叉选择哪个特征对样本进行划分,能够又快又准地对样本进行分类,即根据不同的特征选择方案,我们分为了:ID3、C4.5、CART等算法。

image.png

6.智能指针怎么解决交叉引用,造成的内存泄漏

结论:创建对象时使用shared_ptr强智能指针指向,其余情况都使用weak_ptr弱智能指针指向。

(1)交叉引用的栗子:

当A类中有一个指向B类的shared_ptr强类型智能智能,B类中也有一个指向A类的shared_ptr强类型智能指针。

main函数执行后有两个强智能指针指向了对象A,对象A的引用计数为2,B类也是:

#include <iostream>
#include <memory>
using namespace std;
class B;
class A{
public:
    shared_ptr<B> _bptr;
};
class B{
public:
    shared_ptr<A> _aptr;
};
int main(){
    shared_ptr<A> aptr(new A());
    shared_ptr<B> bptr(new B());
    aptr->_bptr = bptr;
    bptr->_aptr = aptr;
    return 0;
}

image.png

而当主函数mainreturn返回后,对象A的引用计数减一变为1(aptr没指向A对象了),B对象也是,引用计数不为0,即不能析构2个对象释放内存,造成内存泄漏。

(2)解决方案

将类A和类B中的shared_ptr强智能指针都换成weak_ptr弱智能指针;

class A{
public:
    weak_ptr<B> _bptr;
};
class B{
public:
    weak_ptr<A> _aptr;
};

weak_ptr弱智能指针,虽然有引用计数,但实际上它并不增加计数,而是只观察对象的引用计数。所以此时对象A的引用计数只为1,对象B的引用计数也只为1。

image.png

7. C++多线程了解不?

多线程指的是在一个程序进程中处理控制流的多路并行通道,它在所有操作系统上为运行该程序提供了相同程度的并发性。C++ 11 之后添加了新的标准线程库 std::thread,std::thread 在 <thread> 头文件中声明。

(1)并行和并发的概念:

并行:同时执行,计算机在同一时刻,在某个时间点上处理两个或以上的操作。(如下图)

判断一个程序是否并行执行,只需要看某个时刻上是否多两个或以上的工作单位在运行。一个程序如果是单线程的,那么它无法并行地运行。利用多线程与多进程可以使得计算机并行地处理程序(当然 ,前提是该计算机有多个处理核心)。

image.png

并发:同一时间段内可以交替处理多个操作。如下图。每个队列都有自己的安检窗口,两个队列中间没有竞争关系,队列中的某个排队者只需等待队列前面的人安检完成,然后再轮到自己安检。

image.png

如果我们将程序的结构设计为可以并发执行的,那么在支持并行的机器上,我们可以将程序并行地执行。因此,并发重点指的是程序的设计结构,而并行指的是程序运行的状态。并发编程,是一种将一个程序分解成小片段独立执行的程序设计方法。

(2)并发的基本方法

多进程:

如你和小伙伴要开发一个项目,但是已经放假回家了,所以通过wechat联系,各自工作时互不干扰。这里的小伙伴代表线程,工作地点代表一个处理器,这个场景的每个小伙伴是一个单线程的进程(拥有独立的处理器)。

多个进程独立地运行,它们之间通过进程间常规的通信渠道传递讯息(信号,套接字,文件,管道等),这种进程间通信不是设置复杂就是速度慢,这是因为为了避免一个进程去修改另一个进程,操作系统在进程间提供了一定的保护措施,当然,这也使得编写安全的并发代码更容易。运行多个进程也需要固定的开销:进程的启动时间,进程管理的资源消耗。

多线程:

上学时,你和小伙伴在实验室共同讨论问题,头脑风暴,更有效地沟通项目。这里的场景即只有一个处理器,所有小伙伴都是属于同一进程的线程。

C++11 标准提供了一个新的线程库,内容包括了管理线程、保护共享数据、线程间的同步操作、低级原子操作等各种类。标准极大地提高了程序的可移植性,以前的多线程依赖于具体的平台,而现在有了统一的接口进行实现。

在当个进程中运行多个线程也可以并发。线程就像轻量级的进程,每个线程相互独立运行,但它们共享地址空间,所有线程访问到的大部分数据如指针、对象引用或其他数据可以在线程之间进行传递,它们都可以访问全局变量。进程之间通常共享内存,但这种共享通常难以建立且难以管理,缺少线程间数据的保护。因此,在多线程编程中,我们必须确保每个线程锁访问到的数据是一致的。

(3)C++11中的并发与多线程

C++11 新标准中引入了几个头文件来支持多线程编程:(所以我们可以不再使用 CreateThread 来创建线程,简简单单地使用 std::thread 即可。)

< thread > :包含std::thread类以及std::this_thread命名空间。管理线程的函数和类在 中声明.

< atomic > :包含std::atomic和std::atomic_flag类,以及一套C风格的原子类型和与C兼容的原子操作的函数。

< mutex > :包含了与互斥量相关的类以及其他类型和函数

< future > :包含两个Provider类(std::promise和std::package_task)和两个Future类(std::future和std::shared_future)以及相关的类型和函数。

< condition_variable > :包含与条件变量相关的类,包括std::condition_variable和std::condition_variable_any。

8.头文件functional(C++11特性)

<functional>是C++标准库中的一个头文件,定义了C++标准中多个用于表示函数对象(function object)的类模板,包括算法操作、比较操作、逻辑操作;

以及用于绑定函数对象的实参值的绑定器(binder)。这些类模板的实例是具有函数调用运算符(function call operator)的C++类,这些类的实例可以如同函数一样调用。不必写新的函数对象,而仅是组合预定义的函数对象与函数对象适配器(function object adaptor),就可以执行非常复杂的操作。

9.小结

算法项目,C++11特性问了几个,常见机器学习算法都问。

相关文章
|
4天前
|
算法 Java
Java面试题:解释垃圾回收中的标记-清除、复制、标记-压缩算法的工作原理
Java面试题:解释垃圾回收中的标记-清除、复制、标记-压缩算法的工作原理
13 1
|
10天前
|
机器学习/深度学习 人工智能 自然语言处理
机器学习之深度学习算法概念
深度学习算法是一类基于人工神经网络的机器学习方法,其核心思想是通过多层次的非线性变换,从数据中学习表示层次特征,从而实现对复杂模式的建模和学习。深度学习算法在图像识别、语音识别、自然语言处理等领域取得了巨大的成功,成为人工智能领域的重要技术之一。
23 3
|
11天前
|
人工智能 自然语言处理 算法
昆仑万维携手南洋理工大学抢发Q*算法:百倍提升7B模型推理能力
【7月更文挑战第4天】昆仑万维与南洋理工大学推出Q*算法,大幅提升7B规模语言模型的推理效能。Q*通过学习Q值模型优化LLMs的多步推理,减少错误,无需微调,已在多个数据集上展示出显著优于传统方法的效果。尽管面临简化复杂性和效率挑战,这一创新为LLM推理能力提升带来重大突破。[论文链接:](https://arxiv.org/abs/2406.14283)**
15 1
|
12天前
|
机器学习/深度学习 数据采集 人工智能
|
4天前
|
算法 Java 程序员
Java面试题:解释Java的垃圾回收机制,包括常见的垃圾回收算法。介绍一下Java的垃圾回收算法中的标记-压缩算法。
Java面试题:解释Java的垃圾回收机制,包括常见的垃圾回收算法。介绍一下Java的垃圾回收算法中的标记-压缩算法。
8 0
|
5天前
|
算法 Java 开发者
Java面试题:Java内存探秘与多线程并发实战,Java内存模型及分区:理解Java堆、栈、方法区等内存区域的作用,垃圾收集机制:掌握常见的垃圾收集算法及其优缺点
Java面试题:Java内存探秘与多线程并发实战,Java内存模型及分区:理解Java堆、栈、方法区等内存区域的作用,垃圾收集机制:掌握常见的垃圾收集算法及其优缺点
8 0
|
5天前
|
存储 算法 Java
Java面试题:解释JVM的内存结构,并描述堆、栈、方法区在内存结构中的角色和作用,Java中的多线程是如何实现的,Java垃圾回收机制的基本原理,并讨论常见的垃圾回收算法
Java面试题:解释JVM的内存结构,并描述堆、栈、方法区在内存结构中的角色和作用,Java中的多线程是如何实现的,Java垃圾回收机制的基本原理,并讨论常见的垃圾回收算法
7 0
|
12天前
|
机器学习/深度学习 人工智能 供应链
|
14天前
|
机器学习/深度学习 数据采集 算法
【机器学习】CART决策树算法的核心思想及其大数据时代银行贷款参考案例——机器认知外界的重要算法
【机器学习】CART决策树算法的核心思想及其大数据时代银行贷款参考案例——机器认知外界的重要算法
|
17天前
|
机器学习/深度学习 分布式计算 算法
在机器学习项目中,选择算法涉及问题类型识别(如回归、分类、聚类、强化学习)
【6月更文挑战第28天】在机器学习项目中,选择算法涉及问题类型识别(如回归、分类、聚类、强化学习)、数据规模与特性(大数据可能适合分布式算法或深度学习)、性能需求(准确性、速度、可解释性)、资源限制(计算与内存)、领域知识应用以及实验验证(交叉验证、模型比较)。迭代过程包括数据探索、模型构建、评估和优化,结合业务需求进行决策。
22 0