2021.3.30-蚂蚁金服-后端开发-实习-二面

1 Python装饰器(Decorator)
转载自:https://www.zhihu.com/question/26930016
还参考了添加链接描述
装饰器是Python的一个重要部分,他是修改其他函数的功能的函数,有助于让代码更简短。本质上是一个函数,可以让其他函数在不需要任何变动的前提下增加额外功能,返回值也是一个函数对象。经常用于有切面需求的场景,如插入日志、性能测试、事务处理、缓存和权限校验等场景。

def outer(x):
    a=x
    def inner(y):
        b=y
        print(a+b)
    return inner
f1=outer(2)
f1(10)#返回12

一般一个函数运行结束的时候,临时变量会被销毁。但是闭包是一个特别的情况。当外函数发现,自己的临时变量会在将来的内函数中用到,自己在结束的时候,返回内函数的同时,会把外函数的临时变量同内函数绑定在一起。这样即使外函数已经结束了,内函数仍然能够使用外函数的临时变量。这就是闭包的强大之处。

先介绍两个概念:
嵌套函数:如果在一个函数的内部还定义了另一个函数(注意: 是定义,不是引用!),这个函数就叫嵌套函数。外部的我们叫它外函数,内部的我们叫他内函数。 内函数在自己作用域内查找局部变量失败后,会进一步向上一层作用域里查找。
闭包(Closure):闭包是Python编程一个非常重要的概念。如果一个外函数中定义了一个内函数,且内函数体内引用到了体外的变量,这时外函数通过return返回内函数的引用时,会把定义时涉及到的外部引用变量和内函数打包成一个整体(闭包)返回。

1 简单装饰器 @符号为装饰器的语法糖,在定义函数时使用,避免再一次赋值操作

args称之为Non-keyword Variable Arguments,无关键字参数;
**kwargs称之为keyword Variable Arguments,有关键字参数;
当函数中以列表或者元组的形式传参时,就要使用
args;
当传入字典形式的参数时,就要使用**kwargs。

def use_logging(func):
    def wrapper(*args, **kwargs): #wrapper包裹函数
        logging.warn("%s is running" % func.__name__)
        return func(*args,**kwargs)
    return  wrapper
@use_logging
def bar():
    print("i am bar")
@use_logging
def foo():
    print("i am foo")
bar()
foo()

2 带参数的装饰器 是对原有装饰器的函数封装,并返回一个装饰器,可以理解为带有参数的闭包。

import logging
def use_logging(level):
    def decorator(func):
        def wrapper(*args, **kwargs):
            if level=="warn":
                logging.warn("%s is running" % func.__name__)
            return func(*args)
        return wrapper
    return decorator
@use_logging(level="warn")
def foo(name='foo'):
    print("i am %s" % name)
foo()

3 类装饰器,灵活度大 高内聚 封装性等优点,可以依靠内部的call方法,当使用@形式的装饰器附加到函数上时,会调用此方法。

class Foo(object):
    def __init__(self,func):
        self._func=func
    def __call__(self):
        print('class decorator running')
        self._func
        print('class decorator ending')
@Foo
def bar():
    print('bar')
bar()

4 内装饰器 @staticmethod @classmethod @property

装饰器的顺序:
@a
@b
@c
def f():
执行顺序为f=a(b(c(f)))

2 Java异常处理机制,自定义异常
Java异常分为两类:
error,JVM无法解决的问题;exception ,可以处理的问题
异常处理机制:
将异常处理的程序代码集中在一起,与正常的程序代码分开,Java提供的异常处理是抓抛模型。如果出现异常,会生成一个异常类对象,该异常对象将被交给Java运行时系统,过程称为抛出(throw)异常。
try – catch – finally
自定义异常类:
在Java中要想创建自定义异常,需要继承Throwable或者他的子类Exception。一般的,用户自定义异常类都是RuntimeException的子类。自定义异常类通常需要编写几个重载的构造器;自定义的异常对象通过throw抛出;自定义异常最重要的就是异常类的名字,当异常出现时,可以根据名字判断异常类型。
3 mysql连接方式:
左连接 右连接 外连接 内连接
4 Java多线程编程 线程池
线程池原理
接收任务,放入仓库
工作线程从仓库取任务,执行
当没有任务时,线程阻塞,当有任务时唤醒线程执行
以下内容参考:https://blog.csdn.net/zs18753479279/article/details/114177661?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161724450216780262542439%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=161724450216780262542439&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_v2~rank_v29-1-114177661.pc_v2_rank_blog_default&utm_term=%E7%BA%BF%E7%A8%8B%E6%B1%A0

线程池ThreadpoolExecutor
池化技术:为了减少每次获取资源的消耗,提高对资源的利用率。
好处:降低资源的消耗、提高响应速度、方便管理
1 线程池的创建方式
newSingleThreadExecutor:一个单线程的线程池
newFixedThreadPool:固定大小的线程池
newCachedThreadPool:可缓存的线程池
newScheduledThreadPool:大小无限的线程池
2 线程池状态
Running 正常状态,等待接受新的任务,处理等待队列中的任务
ShutDown 不接受新的任务,会处理等待队列中的任务
Stop 不接受新的任务,不再处理等待队列中的任务,终端正在执行任务的线程
Tidying 所有任务都销毁 workcount为0 线程池状态在转换为tidying状态时,会执行terminated方法
terminated:terminated方法结束后,线程池状态变成这个。
创建线程池的七大参数
int corePoolSize, //核心线程池大小,线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会被销毁。
int maximumPoolSize, //一个任务被提交到线程池以后,首先会找有没有空闲存活线程,如果有则直接将任务交给这个空闲线程来执行,
//如果没有则会缓存到工作队列( BlockingQueue workQueue)中, 如果工作队列满了,才会创建一个新线程,然后从工作队列的头部取出一个任务交由新线程来处理,而将刚提交的任务放入工作队列尾部。线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize指定。
long keepAliveTime, //一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁
TimeUnit unit, //超时单位
BlockingQueue workQueue, //新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务
ThreadFactory threadFactory, //为线程池提供创建新线程的线程工厂
RejectedExecutionHandler handler //当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,会拒绝执行。

Executors各个方法的弊端:
线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,可以更加明确线程池的运行规则,规避资源耗尽的风险。
1 FixedThreadPool和SingleThreadPool允许请求的队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM
2 CachedThreadPool和ScheduledThreadPool,允许创建的线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM

拒绝策略
ThreadPoolExecutor 拒绝策略定义: 如果当前同时运行的线程数量达到最大线程数量并且队列也已经被放满了任务时;

new ThreadPoolExecutor.AbortPolicy(): //该拒绝策略为:拒绝新任务的处理,并抛出异常—超出最大承载,就会抛出异常;最大承载=maximumPoolSize + BlockingQueue
new ThreadPoolExecutor.CallerRunsPolicy(): //该拒绝策略为:调用执行自己的线程运行任务 哪来的去哪里 main线程进行处理
new ThreadPoolExecutor.DiscardPolicy(): //该拒绝策略为:不处理新任务,直接丢弃掉。
new ThreadPoolExecutor.DiscardOldestPolicy(): //该拒绝策略为队列满了,尝试去和最早的进程竞争,不会抛出异常

5 将一个表分组,然后取每个分组的前K个
select 1的意思是增加临时列,列中的值为1.即select后面的数字是几增加的列中的值为几。
select count(1) 得到的是表的行数
取第一个:

SELECT t1.`id`,t1.`num` FROM `test_group_limit` t1
WHERE NOT EXISTS(SELECT 1 FROM  test_group_limit WHERE t1.`id`=id AND num>t1.`num`);

取前三个:

SELECT t1.`id`,t1.`num` FROM `test_group_limit` t1
WHERE 3>(SELECT COUNT(1) FROM  test_group_limit WHERE t1.`id`=id AND num>t1.`num`)
order by t1.id asc,t1.num desc

答案在这个链接里:https://blog.csdn.net/dongyuxu342719/article/details/77992730

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值