【python量化交易】—— Alpha选股策略 - Qteasy自定义交易策略【附源码】
使用qteasy创建并回测Alpha选股交易策略
- 使用`qteasy`创建并回测Alpha选股交易策略
- 策略思想
- 第一种自定义策略设置方法,使用持仓数据和选股数据直接生成比例交易信号PS信号:
- 第二种自定义策略设置方法,使用`PT`交易信号设置持仓目标:
- 第三种自定义策略设置方法:
使用qteasy
创建并回测Alpha选股交易策略
我们今天使用qteasy
来回测一个alpha选股交易策略,qteasy
是一个功能全面且易用的量化交易策略框架,Github地址在这里。使用它,能轻松地获取历史数据,创建交易策略并完成回测和优化,还能实盘运行。项目文档在这里。
为了继续本章的内容,您需要安装qteasy【教程1】,并下载历史数据到本地【教程2、),详情可以参考更多教程【教程3】。
建议您先按照前面教程的内容了解qteasy
的使用方法,然后再参考这里的例子创建自己的交易策略。
策略思想
本策略每隔1个月定时触发计算SHSE.000300成份股的过去的EV/EBITDA并选取EV/EBITDA大于0的股票,随后平掉排名EV/EBITDA不在最小的30的股票持仓并等权购买EV/EBITDA最小排名在前30的股票
回测数据为:SHSE.000300沪深300指数成份股
回测时间为:2016-04-05 到 2021-02-01
import qteasy as qt
import pandas as pdd
import numpy as np
在选股之前,需要检查需要的历史数据
EV/EBITDA数据并不直接存在于qteasy定义的数据类型中,需要通过几个数据组合计算出来
EV/EBITDA = (Market Capitalization + Total Debt - Total Cash) / EBITDA
上面几个数据分别代表总市值、总负债、总现金及现金等价物,这些数据需要从qteasy
内置的数据类型中分别提取,并使用上面的公式计算后,作为选股因子。排除掉小于0的因子后,将所有选股因子从小到大排列,选出因子排在最前的30支股票,将手中的全部资金平均分配投入到所有选中的股票中持有一个月,直到下一次选股为止。
我们可以通过下面的方法检查数据检查结果。
htypes = 'total_mv, total_liab, c_cash_equ_end_period, ebitda'
shares = qt.filter_stock_codes(index='000300.SH', date='20220131')
print(shares[0:10])
dt = qt.get_history_data(htypes, shares=shares, asset_type='any', freq='m')one_share = shares[24]df = dt[one_share]df['ev_to_ebitda'] = (df.total_mv + df.total_liab - df.c_cash_equ_end_period) / df.ebitda
输出结果如下
['000001.SZ', '000002.SZ', '000063.SZ', '000066.SZ', '000069.SZ', '000100.SZ', '000157.SZ', '000166.SZ', '000301.SZ', '000333.SZ']
有了上面的数据定义,我们就可以创建这样的选股策略了。
实际上,我们可以使用好几种不同的方法实现同样的选股策略:
第一种自定义策略设置方法,使用持仓数据和选股数据直接生成比例交易信号PS信号:
使用GeneralStrategy
策略类,计算选股因子后,去掉所有小于零的因子,排序后提取排名前三十的股票
按以下逻辑生成交易信号:
1,检查当前持仓,如果持仓的股票不在选中的30个中间,则全数卖出
2,检查当前持仓,如果新选中的股票没有持仓,则等权买入新增选中的股票
设置交易信号类型为PS
,生成交易信号
由于生成交易信号需要用到持仓数据,因此不能使用批量生成模式,只能使用stepwise
模式
策略的定义如下
class AlphaPS(qt.GeneralStg):def realize(self, h, r=None, t=None, pars=None):# 从历史数据编码中读取四种历史数据的最新数值total_mv = h[:, -1, 0] # 总市值total_liab = h[:, -1, 1] # 总负债cash_equ = h[:, -1, 2] # 现金及现金等价物总额ebitda = h[:, -1, 3] # ebitda,息税折旧摊销前利润# 从持仓数据中读取当前的持仓数量,并找到持仓股序号own_amounts = t[:, 0]owned = np.where(own_amounts > 0)[0] # 所有持仓股的序号not_owned = np.where(own_amounts == 0)[0] # 所有未持仓的股票序号# 选股因子为EV/EBIDTA,使用下面公式计算factors = (total_mv + total_liab - cash_equ) / ebitda# 处理交易信号,将所有小于0的因子变为NaNfactors = np.where(factors < 0, np.nan, factors)# 选出数值最小的30个股票的序号arg_partitioned = factors.argpartition(30)selected = arg_partitioned[:30] # 被选中的30个股票的序号not_selected = arg_partitioned[30:] # 未被选中的其他股票的序号(包括因子为NaN的股票)# 开始生成交易信号signal = np.zeros_like(factors)# 如果持仓为正,且未被选中,生成全仓卖出交易信号own_but_not_selected = np.intersect1d(owned, not_selected)signal[own_but_not_selected] = -1 # 在PS信号模式下 -1 代表全仓卖出# 如果持仓为零,且被选中,生成全仓买入交易信号selected_but_not_own = np.intersect1d(not_owned, selected)signal[selected_but_not_own] = 0.0333 # 在PS信号模式下,+1 代表全仓买进 (如果多只股票均同时全仓买进,则会根据资金总量平均分配资金)return signal
创建一个Operator
对象,并运行这个策略。
由于策略使用了当前持仓数据,因此只能使用stepwise
模式回测
alpha = AlphaPS(pars=(),par_count=0,par_types=[],par_range=[],name='AlphaPS',description='本策略每隔1个月定时触发计算SHSE.000300成份股的过去的EV/EBITDA并选取EV/EBITDA大于0的股票',data_types='total_mv, total_liab, c_cash_equ_end_period, ebitda',strategy_run_freq='m',data_freq='d',window_length=100)
op = qt.Operator(alpha, signal_type='PS')
op.op_type = 'stepwise'
op.run(mode=1,asset_type='E',asset_pool=shares,trade_batch_size=100,sell_batch_size=1,trade_log=True)
输出结果如下:
====================================| || BACK TESTING RESULT || |====================================qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 0.0ms
time consumption for operation back looping: 6s 192.6msinvestment starts on 2016-04-05 00:00:00
ends on 2021-02-01 00:00:00
Total looped periods: 4.8 years.-------------operation summary:------------
Only non-empty shares are displayed, call
"loop_result["oper_count"]" for complete operation summarySell Cnt Buy Cnt Total Long pct Short pct Empty pct
000301.SZ 1 1 2 10.3% 0.0% 89.7%
000786.SZ 2 2 4 27.5% 0.0% 72.5%
000895.SZ 1 2 3 66.4% 0.0% 33.6%
002001.SZ 2 2 4 56.9% 0.0% 43.1%
002007.SZ 0 1 1 68.3% 0.0% 31.7%
002027.SZ 2 2 4 41.3% 0.0% 58.7%
002032.SZ 2 2 4 6.9% 0.0% 93.1%
002044.SZ 1 1 2 1.8% 0.0% 98.2%
002049.SZ 1 1 2 5.1% 0.0% 94.9%
002050.SZ 4 4 8 13.8% 0.0% 86.2%
... ... ... ... ... ... ...
603806.SH 3 3 6 62.1% 0.0% 37.9%
603899.SH 3 3 6 38.1% 0.0% 61.9%
000408.SZ 2 3 5 35.5% 0.0% 64.5%
002648.SZ 1 1 2 5.2% 0.0% 94.8%
002920.SZ 1 1 2 5.1% 0.0% 94.9%
300223.SZ 1 1 2 5.2% 0.0% 94.8%
300496.SZ 1 1 2 10.5% 0.0% 89.5%
600219.SH 0 1 1 6.1% 0.0% 93.9%
603185.SH 1 1 2 5.2% 0.0% 94.8%
688005.SH 1 1 2 3.5% 0.0% 96.5% Total operation fee: ¥ 750.28
total investment amount: ¥ 100,000.00
final value: ¥ 182,142.87
Total return: 82.14%
Avg Yearly return: 13.22%
Skewness: -0.36
Kurtosis: 2.40
Benchmark return: 65.96%
Benchmark Yearly return: 11.06%------strategy loop_results indicators------
alpha: 0.035
Beta: 1.175
Sharp ratio: 1.244
Info ratio: 0.005
250 day volatility: 0.113
Max drawdown: 19.03% peak / valley: 2018-05-22 / 2019-01-03recovered on: 2019-04-01===========END OF REPORT=============
第二种自定义策略设置方法,使用PT
交易信号设置持仓目标:
在完成选股因子的计算之后,直接设置每个股票的持仓目标,这样就不需要使用知道持仓数据,直接输出持仓目标信号
,在回测过程中根据实际持仓量生成交易信号。
class AlphaPT(qt.GeneralStg):def realize(self, h, r=None, t=None, pars=None):# 从历史数据编码中读取四种历史数据的最新数值total_mv = h[:, -1, 0] # 总市值total_liab = h[:, -1, 1] # 总负债cash_equ = h[:, -1, 2] # 现金及现金等价物总额ebitda = h[:, -1, 3] # ebitda,息税折旧摊销前利润# 选股因子为EV/EBIDTA,使用下面公式计算factors = (total_mv + total_liab - cash_equ) / ebitda# 处理交易信号,将所有小于0的因子变为NaNfactors = np.where(factors < 0, np.nan, factors)# 选出数值最小的30个股票的序号arg_partitioned = factors.argpartition(30)selected = arg_partitioned[:30] # 被选中的30个股票的序号not_selected = arg_partitioned[30:] # 未被选中的其他股票的序号(包括因子为NaN的股票)# 开始生成PT交易信号signal = np.zeros_like(factors)# 所有被选中的股票的持仓目标被设置为0.03,表示持有3.3%signal[selected] = 0.0333# 其余未选中的所有股票持仓目标在PT信号模式下被设置为0,代表目标仓位为0signal[not_selected] = 0 return signal
生成一个Operator对象,运行回测
alpha = AlphaPT(pars=(),par_count=0,par_types=[],par_range=[],name='AlphaSel',description='本策略每隔1个月定时触发计算SHSE.000300成份股的过去的EV/EBITDA并选取EV/EBITDA大于0的股票',data_types='total_mv, total_liab, c_cash_equ_end_period, ebitda',strategy_run_freq='m',data_freq='d',window_length=100)
op = qt.Operator(alpha, signal_type='PT')
res = op.run(mode=1,asset_type='E',asset_pool=shares,PT_buy_threshold=0.00, # 如果设置PBT=0.00,PST=0.03,最终收益会达到30万元PT_sell_threshold=0.00,trade_batch_size=100,sell_batch_size=1,maximize_cash_usage=True,trade_log=True)
回测结果如下:
====================================| || BACK TESTING RESULT || |====================================qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 7.2ms
time consumption for operation back looping: 6s 308.5msinvestment starts on 2016-04-05 00:00:00
ends on 2021-02-01 00:00:00
Total looped periods: 4.8 years.-------------operation summary:------------
Only non-empty shares are displayed, call
"loop_result["oper_count"]" for complete operation summarySell Cnt Buy Cnt Total Long pct Short pct Empty pct
000301.SZ 1 1 2 10.3% 0.0% 89.7%
000786.SZ 2 3 5 27.5% 0.0% 72.5%
000895.SZ 1 1 2 68.7% 0.0% 31.3%
002001.SZ 2 2 4 57.5% 0.0% 42.5%
002007.SZ 0 1 1 68.3% 0.0% 31.7%
002027.SZ 6 7 13 41.3% 0.0% 58.7%
002032.SZ 3 1 4 7.5% 0.0% 92.5%
002044.SZ 1 1 2 1.8% 0.0% 98.2%
002049.SZ 1 1 2 5.1% 0.0% 94.9%
002050.SZ 4 4 8 13.8% 0.0% 86.2%
... ... ... ... ... ... ...
603806.SH 5 3 8 62.1% 0.0% 37.9%
603899.SH 2 3 5 36.3% 0.0% 63.7%
000408.SZ 3 5 8 35.5% 0.0% 64.5%
002648.SZ 1 1 2 5.2% 0.0% 94.8%
002920.SZ 1 1 2 5.1% 0.0% 94.9%
300223.SZ 1 2 3 5.2% 0.0% 94.8%
300496.SZ 1 1 2 10.5% 0.0% 89.5%
600219.SH 1 1 2 6.1% 0.0% 93.9%
603185.SH 1 1 2 5.2% 0.0% 94.8%
688005.SH 1 2 3 5.2% 0.0% 94.8% Total operation fee: ¥ 985.25
total investment amount: ¥ 100,000.00
final value: ¥ 189,723.44
Total return: 89.72%
Avg Yearly return: 14.18%
Skewness: -0.41
Kurtosis: 2.87
Benchmark return: 65.96%
Benchmark Yearly return: 11.06%------strategy loop_results indicators------
alpha: 0.044
Beta: 1.134
Sharp ratio: 1.284
Info ratio: 0.011
250 day volatility: 0.120
Max drawdown: 20.95% peak / valley: 2018-05-22 / 2019-01-03recovered on: 2019-09-09===========END OF REPORT=============
第三种自定义策略设置方法:
使用FactorSorter策略类,直接生成交易策略的选股因子,再根据
FactorSorter策略的选股参数实现选股,本质上与第二种方式相同,但是
可以大大减少代码量
设置交易信号类型为PT,生成持仓目标,自动生成交易信号
class AlphaFac(qt.FactorSorter): # 注意这里使用FactorSorter策略类def realize(self, h, r=None, t=None, pars=None):# 从历史数据编码中读取四种历史数据的最新数值total_mv = h[:, -1, 0] # 总市值total_liab = h[:, -1, 1] # 总负债cash_equ = h[:, -1, 2] # 现金及现金等价物总额ebitda = h[:, -1, 3] # ebitda,息税折旧摊销前利润# 选股因子为EV/EBIDTA,使用下面公式计算factor = (total_mv + total_liab - cash_equ) / ebitda# 对比第二种策略定义方法,使用FactorSorter策略类可以直接处理选股因子# 从而大大降低代码量# 由于使用因子排序选股策略,因此直接返回选股因子即可,策略会自动根据设置条件选股return factor
同样创建一个Operator对象,回测交易策略
注意这个交易策略需要更多的参数用于因子选股:
max_sel_count=30
设置选股数量,最多选出30个股票condition='greater'
设置筛选条件,仅筛选因子大于ubound的股票ubound=0.0
设置筛选条件,仅筛选因子大于0的股票weighting='even'
设置股票权重,所有选中的股票平均分配权重sort_ascending=True
设置排序方式,因子从小到大排序选择头30名
alpha = AlphaFac(pars=(),par_count=0,par_types=[],par_range=[],name='AlphaSel',description='本策略每隔1个月定时触发计算SHSE.000300成份股的过去的EV/EBITDA并选取EV/EBITDA大于0的股票',data_types='total_mv, total_liab, c_cash_equ_end_period, ebitda',strategy_run_freq='m',data_freq='d',window_length=100,max_sel_count=30, # 设置选股数量,最多选出30个股票condition='greater', # 设置筛选条件,仅筛选因子大于ubound的股票ubound=0.0, # 设置筛选条件,仅筛选因子大于0的股票weighting='even', # 设置股票权重,所有选中的股票平均分配权重sort_ascending=True) # 设置排序方式,因子从小到大排序选择头30名
op = qt.Operator(alpha, signal_type='PT')
res = op.run(mode=1,asset_type='E',asset_pool=shares,PT_buy_threshold=0.0,PT_sell_threshold=0.0,trade_batch_size=100,sell_batch_size=1)
回测结果如下:
====================================| || BACK TESTING RESULT || |====================================qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 9.4ms
time consumption for operation back looping: 5s 831.0msinvestment starts on 2016-04-05 00:00:00
ends on 2021-02-01 00:00:00
Total looped periods: 4.8 years.-------------operation summary:------------
Only non-empty shares are displayed, call
"loop_result["oper_count"]" for complete operation summarySell Cnt Buy Cnt Total Long pct Short pct Empty pct
000301.SZ 1 2 3 10.3% 0.0% 89.7%
000786.SZ 2 3 5 27.5% 0.0% 72.5%
000895.SZ 1 0 1 62.6% 0.0% 37.4%
002001.SZ 2 2 4 55.8% 0.0% 44.2%
002007.SZ 3 1 4 68.3% 0.0% 31.7%
002027.SZ 2 9 11 41.3% 0.0% 58.7%
002032.SZ 2 0 2 5.9% 0.0% 94.1%
002044.SZ 1 1 2 1.8% 0.0% 98.2%
002049.SZ 1 1 2 5.1% 0.0% 94.9%
002050.SZ 4 5 9 13.8% 0.0% 86.2%
... ... ... ... ... ... ...
603517.SH 1 1 2 1.8% 0.0% 98.2%
603806.SH 6 3 9 39.8% 0.0% 60.2%
603899.SH 1 1 2 31.0% 0.0% 69.0%
000408.SZ 3 6 9 35.5% 0.0% 64.5%
002648.SZ 1 1 2 5.2% 0.0% 94.8%
002920.SZ 1 1 2 1.7% 0.0% 98.3%
300223.SZ 1 1 2 5.2% 0.0% 94.8%
600219.SH 1 1 2 6.1% 0.0% 93.9%
603185.SH 1 1 2 5.2% 0.0% 94.8%
688005.SH 1 1 2 5.2% 0.0% 94.8% Total operation fee: ¥ 928.22
total investment amount: ¥ 100,000.00
final value: ¥ 159,072.14
Total return: 59.07%
Avg Yearly return: 10.09%
Skewness: -0.28
Kurtosis: 3.29
Benchmark return: 65.96%
Benchmark Yearly return: 11.06%------strategy loop_results indicators------
alpha: -0.012
Beta: 1.310
Sharp ratio: 1.191
Info ratio: -0.010
250 day volatility: 0.105
Max drawdown: 20.49% peak / valley: 2018-05-22 / 2019-01-03recovered on: 2019-12-26===========END OF REPORT=============
相关文章:

【python量化交易】—— Alpha选股策略 - Qteasy自定义交易策略【附源码】
使用qteasy创建并回测Alpha选股交易策略 使用qteasy创建并回测Alpha选股交易策略策略思想第一种自定义策略设置方法,使用持仓数据和选股数据直接生成比例交易信号PS信号:第二种自定义策略设置方法,使用PT交易信号设置持仓目标:第三…...

简单记录下:Navicat 导出表结构至 Excel
首先我们需要通过sql语句查询出相关的表结构的结构 SELECT COLUMN_NAME AS 字段名称,COLUMN_TYPE AS 字段类型,IF(IS_NULLABLENO,否,是) AS 是否必填,COLUMN_COMMENT AS 注释FROM INFORMATION_SCHEMA.COLUMNSWHERE table_schema bs-gdsAND table_name sys_menu;查询的结构如下…...

黑马基于Web-socket的java聊天室基本解析
要是用Web-socket协议,我们要前端upgrade升级成web-socket协议 首先我们要引入springboot的websocket起步依赖,这样子方便使用,自己指定版本注意 <dependency><groupId>org.springframework.boot</groupId><artifactId&…...

【操作系统期末速成】内存管理|内存的装入模块在装入内存的方式|分配管理方式|页面置换算法|页面置换
🎥 个人主页:深鱼~🔥收录专栏:操作系统🌄欢迎 👍点赞✍评论⭐收藏 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到…...

图和网络笔记
文章目录 1. A X 0 AX0 AX02. A T Y 0 A^TY0 ATY03. A X 0 AX0 AX0和 A T Y 0 A^TY0 ATY0的关系 1. A X 0 AX0 AX0 一个图可以由节点和边组成,假设我们有一个节点notes :n4,边edges:m5的有向图,表示如下 通过以上电路…...
请求外部系统报错
报错信息: nested exception is com.google.common.util.concurrent.ExecutionError: java.lang.NoSuchMethodError: com.google.common.net.HostAndPort.getHostText()Ljava/lang/String; 在网上看了好几篇文章,和我的都不符合。 后面自己发现是我的系…...

电路板维修【四】
【开关电源输出电压偏低不稳,用示波器立马锁定故障范围】:https://www.bilibili.com/video/BV1pf421D73K?vd_source3cc3c07b09206097d0d8b0aefdf07958 可以用示波器查看MOS的输出波形来查看其是否损坏: 电源芯片的供电电压来回跳变…...
(程序设计语言)传值、传引用
1、传值(传递值): 在传值的情况下,函数接收到的是参数的一个副本,而不是参数本身。这意味着函数内部对参数的修改不会影响到原始值。传值通常用于基本数据类型(如整数、浮点数、布尔值等)的传递…...
一次基类类型对象无法被传递问题的分析
看下面一段代码: // proj2.cpp #include <iostream> using namespace std; class CharShape { public:CharShape(char ch) : _ch(ch) {};virtual void Show() 0; protected:char _ch; // 组成图形的字符 }; class Triangle : public CharShape { public:Tr…...

windows设置Redis服务后台自启动
问题 在日常开发过程中,redis是我们常用的缓存工具,但是由于redis对于Linux系统进行开发的,在Linux系统里可以通过修改redis.conf从而从而实现后台启动。 daemonize no 改成 daemonize yes 但是在window上如何也进行后台运行呢,…...

掌握Linux常用命令,扫平面试需求障碍
cd 切换目录。 > cd ../ #切换到父级目录 > cd /tmp # 切换到/tmp目录 > cd ~ # 切换到当前用户的家目录 ls命令 查看文件与目录的命令,list 的缩写。 > ls -l #列出长数据串,包含文件的属性与权限数据等 > ls -a #列出隐藏…...
c语言之文件打开模式
在c语言中,文件打开模式如下 r读模式: 允许对文件读取信息。若文件不存在,则会报错 w写模式: 允许向文件写入信息,若文件不存在,则创建一个文件 #include<stdio.h>int main() {FILE *fp;int i;char ay;fpfo…...

与禹老师学前端vue3学习汇总
24.5.15: 创建Vue3工程 1.确定自己电脑有没有nodejs环境,在cmd中输入node,如果出现Node.js的版本号说明已经有这个环境了,否则搜索Node.js安装 2.先在D盘创建一个文件夹Vue3_Study,然后在这个空文件夹中右键选择终端…...

Linux网络编程——HTTP协议的理解与运用
目录 前言 一、认识URL 二、认识HTTP样例 三、HTTP的报头内容 1.url 2. Content-Type 3.Method 方法 1.GET方法 2.POST方法 4、状态码 5.cookie和session 前言 我们知道,协议就是一种约定,客户端与服务端统一的用这种约定进行传输数据。我们…...
RestTemplate接口请求发送json、form数据格式以及处理接口错误状态码400 null
在使用RestTemplate发送HTTP请求时,你可以通过不同的方式发送JSON或表单数据(application/x-www-form-urlencoded)。同时,处理接口错误状态码(如400)和返回null的情况也是很重要的。以下是一些示例代码&…...

《Python编程从入门到实践》day29
# 昨日知识点回顾 修改折线图文字和线条粗细 矫正图形 使用内置格式 # 今日知识点学习 15.2.4 使用scatter()绘制散点图并设置样式 import matplotlib.pyplot as plt import matplotlib matplotlib.use(TkAgg)plt.style.use(seaborn-v0_8) # 使用内置格式 fig, ax plt.subpl…...

UIKit之图片浏览器
功能需求 实现一个图片浏览器,点击左右按钮可以切换背景图,且更新背景图对应的索引页和图片描述内容。 分析: 实现一个UIView的子类即可,该子类包含多个按钮。 实现步骤: 使用OC语言,故创建cocoa Touch类…...

如何查看SNMP设备的OID
什么是OID和MIB OID OID 代表对象标识符。 OID 唯一地标识 MIB 层次结构中的托管对象。 这可以被描述为一棵树,其级别由不同的组织分配。MIB MIB(管理信息基)提供数字化OID到可读文本的映射。 使用MIB Browser扫描OID 我的设备是一台UPS SN…...

什么?你设计接口什么都不考虑?
如果让你设计一个接口,你会考虑哪些问题? 1.接口参数校验 接口的入参和返回值都需要进行校验。 入参是否不能为空,入参的长度限制是多少,入参的格式限制,如邮箱格式限制 返回值是否为空,如果为空的时候是…...

2024年3月 青少年等级考试机器人理论真题二级
202403 青少年等级考试机器人理论真题二级 第 1 题 一个机器小车,用左右两个电机分别控制左右车轮,左侧电机转速是100rpm,右侧电机转速是50rpm,则此机器小车?( ) A:原地右转 B&am…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...

tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...