使用R语言生成CDISC SDTM.AE domain
写在前面
- 使用的是Rstudio
- 其实R已经有生成sdtm相关的package,以下代码仅作为练习R语言的语法,不是高效生成sdtm的方法
- 代码中没有解决的问题包括:EPOCH相关的逻辑没有考虑partial date的情况;在使用arrange() function做-SEQ排序时,关于大小写英文字母的排序机制似乎与SAS语言的sort function有所不同,导致使用相同的排序变量,通过R和SAS排序后,record的顺序会有不同;输出xpt结果是乱码,暂时输出到csv文件中。
- 还没有写生成SUPPAE的代码
- 代码参考了以下材料
Generating .xpt files with SAS, R and Python
https://www.pharmasug.org/proceedings/2021/EP/PharmaSUG-2021-EP-057.pdf
Yotube @mycsg
mycsg TASKS-SDTMGEN
以下是R代码
setwd('C://R_software')
library(haven)
library(dplyr)
library(tidyverse)
library(sas7bdat)
library(SASxport)
library(Hmisc)
# import source data
raw_ae_001 <- read_sas('C://rawdata/ae_001.sas7bdat')
raw_meddrathsaurus <- read_sas('C://rawdata/meddrathesaurus.sas7bdat')
sdtm_dm <- read_sas('C://sdtmdata/SDTM/DM.sas7bdat')
sdtm_se <- read_sas('C://rawdata/SE.sas7bdat')
# Update the variable name to uppercase, because var name is case sensitive in R
names(raw_ae_001) <- toupper(names(raw_ae_001))
names(raw_meddrathsaurus) <- toupper(names(raw_meddrathsaurus))
# Filter ae raw data with AETERM not missing, and keep necessary variables
ae <- raw_ae_001 %>%
select(SUBJECT,RECORDPOSITION,AETERM,AESTDAT_RAW,AESTTIM,AEENDAT_RAW,AEENTIM,
AESEV_STD,AESER_STD,AEACN_STD,AEREL_STD,AEREL_WD_STD,AEPATT_STD,AEOUT_STD,AESCONG_STD,
AESDISAB_STD,AESDTH_STD,AESHOSP_STD,AESLIFE_STD,AESMIE_STD,AEONGO) %>%
filter(AETERM != "")
# Update AETERM value to uppercase in order to merge with source MedDRA coding data
ae$AETERM <- toupper(ae$AETERM)
# Filter MedDRA source data with AE pannel only
meddra <- raw_meddrathsaurus %>%
filter(PANEL=="AE")
# Merge AE and MedDRA data (left join) by AETERM, create AESTDTC/AEENDTC
ae1 <- merge (ae, meddra, by.x = c("AETERM"), by.y = c("VERBATIM"), all.x = T) %>%
# create AESTDTC
mutate(
stdayn = suppressWarnings(as.numeric(word(AESTDAT_RAW,1))), ### as.numeric>>input, word>>scan
stday = if_else(!is.na(stdayn), str_pad(stdayn, width = 2, pad = "0"), "-"), ### is.na>>not missing, !>>not, str_pad>>put xx.
stmonthc = str_to_upper(word(AESTDAT_RAW, 2)), ### str_to_upper>>uppercase
stmonth = case_when(
stmonthc == "JAN" ~ "01",
stmonthc == "FEB" ~ "02",
stmonthc == "MAR" ~ "03",
stmonthc == "APR" ~ "04",
stmonthc == "MAY" ~ "05",
stmonthc == "JUN" ~ "06",
stmonthc == "JUL" ~ "07",
stmonthc == "AUG" ~ "08",
stmonthc == "SEP" ~ "09",
stmonthc == "OCT" ~ "10",
stmonthc == "NOV" ~ "11",
stmonthc == "DEC" ~ "12",
TRUE ~ "-"
),
styear = word(AESTDAT_RAW,3),
styear1 = if_else((styear == "UNK") | (is.na(styear)), "-", styear), ### | >> or
aestdate = str_c(styear1, stmonth, stday, sep = "-"), ### str_c >> catx
AESTDTC = if_else(AESTTIM != "", str_c(aestdate, str_pad(AESTTIM, width = 5, pad = "0"), sep = "T"), aestdate),
AESTDTC = if_else(str_sub(AESTDTC, -5) == "-----", "", AESTDTC),
AESTDTC = if_else(str_sub(AESTDTC, -4) == "----", str_sub(AESTDTC,end=-5), AESTDTC),
AESTDTC = if_else(str_sub(AESTDTC, -2) == "--", str_sub(AESTDTC,end=-3), AESTDTC)
) %>%
# create AEENDTC
mutate(
endayn = suppressWarnings(as.numeric(word(AEENDAT_RAW,1))), ### as.numeric>>input, word>>scan
enday = if_else(!is.na(endayn), str_pad(endayn, width = 2, pad = "0"), "-"), ### is.na>>not missing, !>>not, str_pad>>put xx.
enmonthc = str_to_upper(word(AEENDAT_RAW, 2)), ### str_to_upper>>uppercase
enmonth = case_when(
enmonthc == "JAN" ~ "01",
enmonthc == "FEB" ~ "02",
enmonthc == "MAR" ~ "03",
enmonthc == "APR" ~ "04",
enmonthc == "MAY" ~ "05",
enmonthc == "JUN" ~ "06",
enmonthc == "JUL" ~ "07",
enmonthc == "AUG" ~ "08",
enmonthc == "SEP" ~ "09",
enmonthc == "OCT" ~ "10",
enmonthc == "NOV" ~ "11",
enmonthc == "DEC" ~ "12",
TRUE ~ "-"
),
enyear = word(AEENDAT_RAW,3),
enyear1 = if_else((enyear == "UNK") | (is.na(enyear)), "-", enyear), ### | >> or
aeendate = str_c(enyear1, enmonth, enday, sep = "-"), ### str_c >> catx
AEENDTC = if_else(AEENTIM != "", str_c(aeendate, str_pad(AEENTIM, width = 5, pad = "0"), sep = "T"), aeendate),
AEENDTC = if_else(str_sub(AEENDTC, -5) == "-----", "", AEENDTC),
AEENDTC = if_else(str_sub(AEENDTC, -4) == "----", str_sub(AEENDTC,end=-5), AEENDTC),
AEENDTC = if_else(str_sub(AEENDTC, -2) == "--", str_sub(AEENDTC,end=-3), AEENDTC)
)
# Create AE domain vars
ae2 <- ae1 %>%
cbind(
STUDYID=c("PROTOCOLID"),
DOMAIN=c("AE"),
USUBJID=str_c(c("PROTOCOLID-0"),substr(ae1$SUBJECT,4,6),c("-00"),substr(ae1$SUBJECT,7,9)), # str_c() is catx() in SAS
SUBJID=ae1$SUBJECT,
AESPID=str_c(c("AE_001-"),ae1$RECORDPOSITION),
AELLT=ae1$LLT_NAME,
AELLTCD=ae1$LLT_CODE,
AEDECOD=ae1$PT_NAME,
AEPTCD=ae1$PT_CODE,
AEHLT=ae1$HLT_NAME,
AEHLTCD=ae1$HLT_CODE,
AEHLGT=ae1$HGT_NAME,
AEHLGTCD=ae1$HGT_CODE,
AEBODSYS=ae1$SOC_NAME,
AEBDSYCD=ae1$SOC_CODE,
AESOC=ae1$SOC_NAME,
AESOCCD=ae1$SOC_CODE,
AESEV=ae1$AESEV_STD,
AESER=ae1$AESER_STD,
AEACN=ae1$AEACN_STD,
AEREL=ae1$AEREL_STD,
AERELNST=ae1$AEREL_WD_STD,
AEPATT=ae1$AEPATT_STD,
AEOUT=ae1$AEOUT_STD,
AESCONG=ae1$AESCONG_STD,
AESDISAB=ae1$AESDISAB_STD,
AESDTH=ae1$AESDTH_STD,
AESHOSP=ae1$AESHOSP_STD,
AESLIFE=ae1$AESLIFE_STD,
AESMIE=ae1$AESMIE_STD
)
# Merge AE and SDTM.DM by USUBJID, create AESTDY/AEENDY
sdtm_dm <- select(sdtm_dm,USUBJID,RFSTDTC,RFENDTC)
ae3 <- merge (ae2, sdtm_dm, by = c("USUBJID"), all.x = T) %>%
mutate(
aestdt=as.Date(AESTDTC),
rfstdt=as.Date(RFSTDTC),
rfstdate=str_sub(RFSTDTC,1,10),
rfst_year=str_sub(RFSTDTC,1,4),
rfst_month=str_sub(RFSTDTC,6,7),
rfst_day=str_sub(RFSTDTC,9,10),
AESTDY=ifelse(!is.na(aestdt) & !is.na(rfstdt),
ifelse((aestdt>=rfstdt),aestdt-rfstdt+1,aestdt-rfstdt), ""
)
) %>%
mutate(
aeendt=as.Date(AEENDTC),
rfstdt=as.Date(RFSTDTC),
AEENDY=ifelse(!is.na(aeendt) & !is.na(rfstdt),
ifelse((aeendt>=rfstdt),aeendt-rfstdt+1,aeendt-rfstdt), ""
)
) %>%
# create AEENRTPT, AEENTPT
mutate(
AEENRTPT=ifelse(AEONGO==1,"ONGOING",""),
AEENTPT=ifelse(AEONGO==1,
ifelse(is.na(rfstdt)==T,"SCREENING","END OF STUDY"),""
)
)
# prepare SE dataset for creating EPOCH
sdtm_se <- select(sdtm_se,USUBJID,ETCD,SESTDTC,SEENDTC)
sest <- sdtm_se %>%
select(USUBJID,ETCD,SESTDTC) %>%
pivot_wider(names_from=ETCD, values_from=SESTDTC)
colnames(sest) <- c("USUBJID","st1","st2","st3")
seen <- sdtm_se %>%
select(USUBJID,ETCD,SEENDTC) %>%
pivot_wider(names_from=ETCD, values_from=SEENDTC)
colnames(seen) <- c("USUBJID","en1","en2","en3")
sesten <- merge (sest, seen, by = c("USUBJID"))
ae4 <- merge (ae3, sesten, by = c("USUBJID"), all.x = T)
ae5 <- ae4 %>%
mutate(EPOCH=NA) %>%
mutate(
EPOCH=ifelse((st1<=aestdt & aestdt<en1) | (aestdt<=en1 & is.na(st2)==T), "SCREENING",ifelse(st2<=aestdt & aestdt<=en2, "TREATMENT", "FOLLOW-UP"))
) %>%
#mutate(
# EPOCH=ifelse(!is.na(EPOCH)==T & !is.na(stday)==T, EPOCH, ifelse())
#) %>%
arrange(STUDYID,USUBJID,AEDECOD,AESTDTC,AEENDTC,AESPID) %>%
group_by(USUBJID) %>%
mutate(AESEQ=row_number())
# select target vars in AE
sdtm_ae <- select(ae5,STUDYID,DOMAIN,USUBJID,SUBJID,AESEQ,AESPID,
AETERM,AELLT,AELLTCD,AEDECOD,AEPTCD,AEHLT,AEHLTCD,AEHLGT,AEHLGTCD,AEBODSYS,AEBDSYCD,AESOC,AESOCCD,
AESEV,AESER,AEACN,AEREL,AERELNST,AEPATT,AEOUT,AESCONG,AESDISAB,AESDTH,AESHOSP,AESLIFE,AESMIE,
EPOCH,AESTDTC,AEENDTC,AESTDY,AEENDY,AEENRTPT,AEENTPT)
# convert following vars to numeric per CDSIC definition
sdtm_ae$AELLTCD <- as.numeric(sdtm_ae$AELLTCD)
sdtm_ae$AEPTCD <- as.numeric(sdtm_ae$AEPTCD)
sdtm_ae$AEHLTCD <- as.numeric(sdtm_ae$AEHLTCD)
sdtm_ae$AEHLGTCD <- as.numeric(sdtm_ae$AEHLGTCD)
sdtm_ae$AEBDSYCD <- as.numeric(sdtm_ae$AEBDSYCD)
sdtm_ae$AESOCCD <- as.numeric(sdtm_ae$AESOCCD)
sdtm_ae$AESTDY <- as.numeric(sdtm_ae$AESTDY)
sdtm_ae$AEENDY <- as.numeric(sdtm_ae$AEENDY)
# convert NA to null
sdtm_ae$AESTDY[is.na(sdtm_ae$AESTDY)] <- ""
sdtm_ae$AEENDY[is.na(sdtm_ae$AEENDY)] <- ""
# add label
label(sdtm_ae) <- "Adverse Events"
label(sdtm_ae$STUDYID) <- "Study Identifier"
label(sdtm_ae$DOMAIN) <- "Domain Abbreviation"
label(sdtm_ae$USUBJID) <- "Unique Subject Identifier"
label(sdtm_ae$SUBJID) <- "Subject Identifier for the Study"
label(sdtm_ae$AESEQ) <- "Sequence Number"
label(sdtm_ae$AESPID) <- "Sponsor-Defined Identifier"
label(sdtm_ae$AETERM) <- "Reported Term for the Adverse Event"
label(sdtm_ae$AELLT) <- "Lowest Level Term"
label(sdtm_ae$AELLTCD) <- "Lowest Level Term Code"
label(sdtm_ae$AEDECOD) <- "Dictionary-Derived Term"
label(sdtm_ae$AEPTCD) <- "Preferred Term Code"
label(sdtm_ae$AEHLT) <- "High Level Term"
label(sdtm_ae$AEHLTCD) <- "High Level Term Code"
label(sdtm_ae$AEHLGT) <- "High Level Group Term"
label(sdtm_ae$AEHLGTCD) <- "High Level Group Term Code"
label(sdtm_ae$AEBODSYS) <- "Body System or Organ Class"
label(sdtm_ae$AEBDSYCD) <- "Body System or Organ Class Code"
label(sdtm_ae$AESOC) <- "Primary System Organ Class"
label(sdtm_ae$AESOCCD) <- "Primary System Organ Class Code"
label(sdtm_ae$AESEV) <- "Severity/Intensity"
label(sdtm_ae$AESER) <- "Serious Event"
label(sdtm_ae$AEACN) <- "Action Taken with Study Treatment"
label(sdtm_ae$AEREL) <- "Causality"
label(sdtm_ae$AERELNST) <- "Relationship to Non-Study Treatment"
label(sdtm_ae$AEPATT) <- "Pattern of Adverse Event"
label(sdtm_ae$AEOUT) <- "Outcome of Adverse Event"
label(sdtm_ae$AESCONG) <- "Congenital Anomaly or Birth Defect"
label(sdtm_ae$AESDISAB) <- "Persist or Signif Disability/Incapacity"
label(sdtm_ae$AESDTH) <- "Results in Death"
label(sdtm_ae$AESHOSP) <- "Requires or Prolongs Hospitalization"
label(sdtm_ae$AESLIFE) <- "Is Life Threatening"
label(sdtm_ae$AESMIE) <- "Other Medically Important Serious Event"
label(sdtm_ae$EPOCH) <- "Epoch"
label(sdtm_ae$AESTDTC) <- "Start Date/Time of Adverse Event"
label(sdtm_ae$AEENDTC) <- "End Date/Time of Adverse Event"
label(sdtm_ae$AESTDY) <- "Study Day of Start of Adverse Event"
label(sdtm_ae$AEENDY) <- "Study Day of End of Adverse Event"
label(sdtm_ae$AEENRTPT) <- "End Relative to Reference Time Point"
label(sdtm_ae$AEENTPT) <- "End Reference Time Point"
#export to xpt
write.xport(sdtm_ae, file="C://R_software/ae_R.xpt")
# export to CSV
write.csv(sdtm_ae, file="C://R_software/ae.csv")
相关文章:
使用R语言生成CDISC SDTM.AE domain
写在前面 - 使用的是Rstudio - 其实R已经有生成sdtm相关的package,以下代码仅作为练习R语言的语法,不是高效生成sdtm的方法 - 代码中没有解决的问题包括:EPOCH相关的逻辑没有考虑partial date的情况;在使用arrange() function做…...
怎么防止源代码泄露?9种方法教会你!
怎么防止源代码泄露?首先要了解员工可以通过哪些方式将源代码传输出去! 物理方法: — 网线直连,即把网线从墙上插头拔下来,然后和一个非受控电脑直连; — winPE启动,通过光盘或U盘的winPE启动,甚…...
原生JS如何实现可配置DM码
原生JS如何实现可配置DM码 一、 DM码简介 1、 Data Matrix码 Data Matrix码是一种二维条形码,简称DM码,由美国公司International Data Matrix, Inc.(I.D. Matrix)在1994年发明,Data Matrix码中的行数和列数随二维码中存储的信息量而增加,信息限值是2335个字母数字字符…...
【Python】Python开发面试题库:综合考察面试者能力
文章目录 Python开发面试题库:综合考察面试者能力1. 基础语法与数据类型问题1:变量与数据类型问题2:列表与字典操作问题3:字符串操作问题4:元组解包问题5:集合操作问题6:基本运算问题7ÿ…...
大语言模型的sft
https://zhuanlan.zhihu.com/p/692892489https://zhuanlan.zhihu.com/p/692892489https://zhuanlan.zhihu.com/p/679450872https://zhuanlan.zhihu.com/p/6794508721.常...
Astar路径规划算法复现-python实现
# -*- coding: utf-8 -*- """ Created on Fri May 24 09:04:23 2024"""import os import sys import math import heapq import matplotlib.pyplot as plt import time 传统A*算法 class Astar:AStar set the cost heuristics as the priorityA…...
低-零功率技术在军事中的应用
“低-零功率”概念最先由美国国防部提出,主要是针对诸如俄罗斯等大国的远程传感器,帮助美军破除“灰色地带挑衅”的威胁。由于“灰色地带”冲突仅依托小规模军事力量,其强度维持在不足以引发美国及其盟国进行直接干预的程度,因此&…...
【培训】企业档案管理专题(私货)
导读:通过该专题培训,可以系统了解企业档案管理是什么、为什么、怎么做。尤其是对档案的价值认知,如何构建与新质生产力发展相适应的企业档案工作体系将有力支撑企业新质生产力的发展,为企业高质量发展贡献档案力量,提…...
某国资集团数据治理落地,点燃高质量发展“数字引擎”
某国有资产经营控股集团为快速提升集团的内控管理能力和业务经营能力,以数字化促进企业转型的信息化建设势在必行。集团携手亿信华辰开启数据治理项目,在数据方面成功解决“哪里来、怎么盘、怎么管、怎么用”的问题,不断推动企业数字化转型…...
2024.06.12【读书笔记】丨生物信息学与功能基因组学(第十四章 细菌和古细菌基因组 第二部分)【AI测试版】
读书笔记:《生物信息学与功能基因组学》第十四章 - 第二部分 摘要 第二部分深入讨论了基于不同标准的细菌和古细菌的分类方法,包括形态学、基因组大小和排列、生活方式以及与人类疾病的关系。此外,还探讨了基于核糖体RNA序列的分类方法&…...
企业数据API接口大全
一、工商信息 (1)精确获取企业唯一标识 根据企业名称、注册号或统一社会信用代码,获取企业唯一标识 (2)企业模糊查询 关键字名称模糊搜索匹配企业 (3)企业详情 根据企业唯一标识、企业名称…...
【HTML】格式化文本 pre 标签
文章目录 <pre> 元素中的文本以等宽字体显示,文本保留空格和换行符。 <pre> 元素支持 HTML 中的全局属性和事件属性。 示例: <pre> pre 元素中的文本 以等宽字体显示, 并且同时保留 空格 和 换行符。 </pre&…...
力扣每日一题(2024-06-13)2813. 子序列最大优雅度
基于官方题解,进行补充说明 给你一个长度为 n 的二维整数数组 items 和一个整数 k 。 items[i] [profiti, categoryi],其中 profiti 和 categoryi 分别表示第 i 个项目的利润和类别。 现定义 items 的 子序列 的 优雅度 可以用 total_profit distinct_…...
MySQL -- 优化
1. 查询优化 使用索引 示例:有一个包含数百万用户的表,名为 users,常见的查询是通过 email 字段查找用户。 CREATE INDEX idx_email ON users(email);通过创建索引 idx_email,SELECT * FROM users WHERE email exampleexample…...
学会python——密码校验(python实例三)
目录 1、认识Python 2、环境与工具 2.1 python环境 2.2 pycharm编译 3、纠正密码输入的格式问题 3.1 代码构思 3.2 代码示例 3.3 运行结果 4、总结 1、认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可…...
【Python】中的X[:,0]、X[0,:]、X[:,:,0]、X[:,:,1]、X[:,m:n]、X[:,:,m:n]和X[: : -1]
Python中 x[m,n]是通过numpy库引用数组或矩阵中的某一段数据集的一种写法,m代表第m维,n代表m维中取第几段特征数据。 通常用法: x[:,n]或者x[n,:] X[:,0]表示对一个二维数组,取该二维数组第一维中的所有数据,第二维中取第0个数据。 X[0,:]使用类比前者。 举例说明: x[:,0…...
【Java基础】OkHttp 超时设置详解
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
巴西:海外媒体投放,大舍传媒实现企业与巴西媒体间的交流
引言 随着全球化的进程,海外市场的开拓对于企业的发展至关重要。巴西作为南美洲最大的经济体和人口大国,具有巨大的商机。在与巴西媒体的交流中,大舍传媒的投放成为了一种高效的宣传和合作途径。 巴西媒体的多样性 巴西媒体以其丰富多样的…...
MT7981B+MT7976C+MT7531A RF定频测试方法
1、从下面网址下载QA软件包,然后在WIN系统下安装QA环境。 https://download.csdn.net/download/zhouwu_linux/89428691?spm1001.2014.3001.5501 在WINDOWS 7系统下先安装WinPcap_4_1_3.exe。 2、搭建硬件环境,电脑先连接仪器,主板网络与电…...
支持微信支付宝账单,极空间Docker部署一个开箱即用的私人账本『cashbook』
支持微信支付宝账单,Docker部署一个开箱即用的私人账本『cashbook』 哈喽小伙伴好,我是Stark-C~ 不知道屏幕前的各位富哥富姐们有没有请一个专业的私人财务助理管理自己的巨额资产,我不是给大家炫耀,我在月薪300的时候就已经有了…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
