码迷,mamicode.com
首页 > 其他好文 > 详细

大厂面试题(一)

时间:2020-04-03 13:43:10      阅读:281      评论:0      收藏:0      [点我收藏+]

标签:输入参数   限制   更新   空间换时间   最大的   今天   fat   指标   nic   

1. SQL题目

题目:有一张用户签到表【t_user_attendence】,标记每天用户是否签到(说明:该表包含所有用户所有工作日的出勤记录) ,包含三个字段:日期【fdate】,用户id【fuser_id】,用户当天是否签到【fis_sign_in:0否1是】;

问题1:请计算截至当前每个用户已经连续签到的天数(输出表仅包含当天签到的所有用户,计算其连续签到天数)

输出表【t_user_consecutive_days】:用户id【fuser_id】,用户联系签到天数【fconsecutive_days】

解答逻辑非常简单,只需要用max和datediff。

问题1答案:

思路:先找用户最近一次未签到日期,再用今天减那个日期

create table t_user_consecutive_days as 
select fuser_id
,datediff(20200322,fdate_max) fconsecutive_days
from
    (select fuser_id
    ,max(fdate) fdate_max
    from t_user_attendence
    where fis_sign_in = 0
    group by fuser_id
    ) t1
;
问题1修改:

思路:我觉得还得限制用户是今天的。

create table t_user_consecutive_days as 
select fuser_id
,datediff(20200322,fdate_max) fconsecutive_days
from
    (select fuser_id
    ,max(fdate) fdate_max
    from t_user_attendence
    where fis_sign_in = 0
    group by fuser_id
    ) t1
where fuser_id in ( select fuser_id
    from t_user_attendence
    where fdate = 20200322)
;

问题2:请计算每个用户历史以来最大的连续签到天数(输出表为用户签到表中所有出现过的用户,计算其历史最大连续签到天数)

输出表【t_user_max_days】:用户id【fuser_id】,用户最大连续签到天数【fmax_days】

 1 问题2答案:把用户所有签到记录转化成一条0-1字符串序列,用0做split切割,计算切出来的1序列组中的最大长度
 2 
 3 create table t_user_max_days as
 4 select fuser_id
 5 ,max(length(cut_fsign_record)) as fmax_days
 6 (select fuser_id
 7 ,fsign_record
 8 ,cut_fsign_record
 9 from
10     (select fuser_id
11     ,wm_concat(fis_sign_in) fsign_record
12     from t_user_attendence
13     group by fuser_id
14     ) t1
15 lateral view explode(split(fsign_record,0)) t as cut_fsign_record
16 ) t2
17 where cut_fsign_record<>‘‘
18 group by fuser_id
19 ;

 

 1 问题2答案:没看懂,修改
 2 
 3 create table t_user_max_days as
 4 select fuser_id
 5 ,max(sign_in) 
 6 from
 7     (select fuser_id
 8     ,fdate-lag(fate) over (partition by fuser_id order by fate desc )  as sign_in from 
 9     (select fuser_id,fdate 
10     from t_user_attendence
11     where fis_sign_in =0
12     order by fdate desc)a
13  ) t1
14 group by fuser_id
15 ;

 2. Python题目

题目:针对股票的最大回撤率指标定义,给出代码实现思路。给定的是产品所有交易日的净值序列,且其净值序列已按照日期排序。

最大回撤率:在选定周期内任一历史时点往后推,产品净值走到最低点时的收益率回撤幅度的最大值。

追问:如何在提升计算效率?

这道题类似的题目其实在leecode也有,这个大概是变化但类似版本(可以搜leecode股票最大回报);因为团队里处理比较多金融资产数据,这个指标是策略中最常见的指标之一,所以也是一道工作中攒下来的题目。这个指标的计算优化问题真的非常值得问,我后面会列几个版本的代码思路和实现代码。

通常最简单的计算实现,会需要O(n2)的计算复杂度;可以针对如何降低计算复杂度,专门追问。

 1 最大回撤率:输入参数都是按照日期降序排列的净值序列
 2 基础实现版本:
 3 
 4 def max_drawdown(accnavArr):
 5 mdd = 0
 6 for i in range(0, len(accnavArr)):
 7 for j in range(i + 1, len(accnavArr)):
 8 drawdown = accnavArr[i] / accnavArr[j] - 1
 9 if drawdown < mdd:
10 mdd = drawdown
11 return mdd
12 空间换时间实现版本:
13 
14 把每个时间点计算的最大值都存到一个列表结构中,最大回撤的计算只需要再依赖这个列表进行多一次循环计算。
15 
16 def maxDrawdownGainCal(accnavArr):      # 默认accnavArr按日期降序排列
17 maxDrawdown = 10000
18 maxGain =0
19 arr_len = len(accnavArr)
20 maxList = [0.0] * arr_len
21 minList = [0.0] * arr_len
22 maxList[arr_len-1] = accnavArr[arr_len-1]
23 minList[arr_len-1] = accnavArr[arr_len-1]
24 for i in range(arr_len-2,-1,-1):
25 if accnavArr[i] > maxList[i+1]:
26 maxList[i] = accnavArr[i]
27 else:
28 maxList[i] = maxList[i+1]
29 if accnavArr[i] < minList[i+1]:
30 minList[i] = accnavArr[i]
31 else:
32 minList[i] = minList[i+1]
33 for i in range(0,arr_len):
34 mdd = (accnavArr[i]/maxList[i]-1)
35 mg = (accnavArr[i]/minList[i]-1)
36 if mdd < maxDrawdown : maxDrawdown = mdd
37 if mg > maxGain : maxGain = mg
38 return maxDrawdown,maxGain
39 当前最优版本:
40 
41 每个时间点同时更新最大值和最大回撤,两个指标,不需要额外空间,且只做一次列表循环计算。
42 
43 def maxDrawdownGainCal(accnavArr):      # 默认accnavArr按日期降序排列
44     maxDrawdown = 10000
45     maxGain =0
46     arrLen = len(accnavArr)
47     startMdd = accnavArr[arrLen-1]
48     startGain = accnavArr[arrLen-1]
49     for i in range(arrLen-2,-1,-1):
50         if accnavArr[i] > startMdd:
51             startMdd = accnavArr[i]
52         mdd = (accnavArr[i]/startMdd-1)
53         if accnavArr[i] < startGain:
54             startGain = accnavArr[i]
55         mg = (accnavArr[i]/startGain-1)
56         if mdd < maxDrawdown : maxDrawdown = mdd
57         if mg > maxGain : maxGain = mg
58     return maxDrawdown,maxGain

 参考:https://mp.weixin.qq.com/s/HRo1HYog-N6QORsl4WY03Q

大厂面试题(一)

标签:输入参数   限制   更新   空间换时间   最大的   今天   fat   指标   nic   

原文地址:https://www.cnblogs.com/zhanghongpan/p/12625875.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!