关于数据埋点的认识以及在流量分析系统中的实际使用
文章目录
- 一、前言
- 二、“埋点”知多少
- 三、“埋点”有何用
- 四、几种埋点“姿势”
- 4.1 前端埋点
- 4.1.1 代码埋点
- 4.1.2 可视化埋点
- 4.1.3 无埋点
- 4.2 后端埋点
- 4.3 其它埋点
- 五、最理想的埋点方式?
- 六、流量分析系统中日志埋点
- 6.1 选择客户端埋点
- 6.2 服务器规划
- 七、日志埋点的实现
- 7.1 客户端埋点
- 7.2 服务器端开发(关键代码)
一、前言
所谓的埋点就是在应用中特定的流程收集一些信息,用来跟踪应用使用的状况,后续用来进一步优化产品或是提供运营的数据支撑,包括访问数(Visits),访客数(Visitor),停留时长(Time On Site),页面浏览数(Page Views)和跳出率(Bounce Rate)。这样的信息收集可以大致分为两种:页面统计(track this virtual page view),统计操作行为(track this button by an event),在为一些网页和App接下来进行流量分析以及描绘用户画像提供支持,是进行数据分析和挖掘的“第一步”。
二、“埋点”知多少
数据埋点作为数据采集的一种重要方式,主要用来记录和收集终端用户的操作行为,其基本原理是在App/H5/PC等终端部署采集的SDK代码,当用户的行为满足某种条件的时候,比如进入某个页面、点击某个按钮等,会自动触发记录和存储,然后这些数据会被收集并被传输到终端提供商,或者是通过后端采集用户使用服务过程中的请求数据。
一个典型的埋点采集处理流程如下图所示:
三、“埋点”有何用
终端提供商在收集到埋点数据之后,通过大数据处理、数据统计、数据分析、数据挖掘等加工处理,可以得到衡量产品状态的一些基本指标,比如活跃、留存、新增等大盘数据,从而洞察产品的状态。此外更重要的是随着数据挖掘等技术的兴起,埋点采集到的数据在以下方面的作用也越来越凸显:
驱动决策:ABtest、漏斗优化、用户增长、bug修复、精准营销、流失用户预警
驱动产品智能:智能推荐(千人千面)、场景化提示(私人助理)等
驱动安全:风险识别
四、几种埋点“姿势”
为了将海量数据采集得更加精准,为后续营造“纯净”的数据分析环境,埋点技术应运而生。数据基础夯实与否,取决于数据的采集方式。
埋点方式多种多样,按照埋点位置不同,可以分为前端(客户端)埋点与后端(服务器端)埋点,其中前端埋点包括:代码埋点、全埋点、可视化埋点。
4.1 前端埋点
前端埋点是在用户端(APP、Web、客户端)等嵌入数据采集代码,比如友盟等均采用的是前端埋点,比如通过嵌入一段代码就就可以对网页数据的访问数据进行采集。相比于后端埋点,前端埋点能方便收集到用户在界面上的行为数据,比如用户点了哪个按钮、页面之间的跳转次序、停留时长等,这些数据是后面进行数据分析的主要来源。
前端埋点技术有以下三类:
4.1.1 代码埋点
代码埋点是直接将采集SDK集成在终端,然后不断在此基础上添加调整采集方案,是目前主流的埋点采集方案,其优缺点如下:
优点:
高度定制、控制精准、采集的数据丰富准确
缺点:
首先是每当有采集需求,需要开发人员不断添加采集代码,工作量大;
其次变更采集策略,需要发布新版本,代价巨大,存在滞后效应;
最后由于采集代码常驻终端,不断将采集的用户行为数据进行记录和上报,对于终端尤其是移动终端来说还有耗电、消耗数据流量等负载,此外在数据上报传输的过程中也存在丢失数据的风险。
4.1.2 可视化埋点
由于代码埋点需要终端开发人员来执行采集方案,对业务的功能开发侵入性较高。有的公司开发出了可视化埋点技术,只需要产品与运营人员通过GUI界面进行鼠标简单点击,就可以随时增加、取消、调整采集数据的位置和方式,此种埋点方式避开了终端开发人员的介入,由需求人员直接执行采集,减轻了需求传递过程中的信息损耗和误解,另外可视化埋点技术往往由服务端直接下发采集的配置文件,而不用跟随版本发布,从而加快了数据采集的流程。
具体实现方式参考:
具体实现是SDK定时做界面截图,在截图的同时从界面UI的根对象开始遍历所有的可视化子对象,得到其层级关系。根据截图和UI元素的可视化信息重新渲染页面,识别可埋点的控件。当产品人员在后台管理端的截屏画面上点击可埋点控件,设置事件关联方面的配置,服务器保存这些配置,客户端在获取到这些配置信息以后,按照新配置采集数据。
4.1.3 无埋点
无埋点与可视化埋点原理基本一致,区别在于无埋点是先遍历所有的控件和操作行为的组合情况,然后将这些组合情况交给埋点后台,由数据分析人员选择对哪些组合的埋点数据进行分析,其优缺点如下:
优点:
收集数据全面,无漏报
缺点:
采集数据量巨大,增加了终端流量消耗和服务器存储负担。
埋点的上报时机相对呆板,不能灵活的根据特定的场景进行特殊设置
前端埋点的注意事项:
页面和控件标示上报要从顶层进行合理的设计,层次感要明显
埋点数据的漏报和重复上报如何衡量
前端埋点不仅可以处理不需要和服务器交互的曝光和点击事件,也可以将与服务器交互的结果,比如关注成功、分享成功、优惠券领取成功等原属于后端埋点里的事件放在前端来上报。
4.2 后端埋点
后端埋点为了避免前端埋点的以下问题:
前端埋点需要对采集的数据压缩、暂存,为减少移动端的数据流量,除一些需要实时上报的重要事件不限制网络环境,其它事件一般只在wifi情况下上报,因此数据会有延迟,丢数据等弊端,而在后端采集数据,由于数据是在内网传输,数据传输的即时性强,丢失数据的风险小。
前端埋点采集程序由于需要常驻,监测实时和延迟埋点上报,不可避免的带来额外的耗电。
前端埋点若要新增或调整采集方案,需要开发人员修改客户端代码,然后发版之后才能解决,受发布周期的影响较大,而且通常用户的版本更新并不会及时,这将导致新方案不能及时覆盖所有用户。虽然现在部分埋点管理后台也支持热配置更新,但功能一般都很弱,只支持一些基础的埋点事件热更新部署,
注意:
很多时候并不把后端埋点独立出来,而是混合在前端埋点中,等用户和服务器端的交互返回结果之后,将结果进行上报。
对一下需要精确采集的数据,比如代金券发放等,实施的时候尽量采用后端埋点,除非后端无法采集到所需要的数据,前端埋点只是用来参考。此外也可以将业务数据库代金券领取数据同步到数据仓库中进行分析。
4.3 其它埋点
路径埋点和独立埋点:
这部分的埋点根据业务对路径的追踪需求和SDK的开发能力,可为每个事件设计上下文的路径信息,路径信息的组成一般由页面、控件、行为三部分组成,而路径的深度也不宜太深,一般小于五层。
显性埋点和隐性埋点:
显性和隐性是从用户有感和无感来区分的,有感事件是用户的主动事件,比如展示和点击事件;无感事件主要用来处理后台的数据请求和拉取,用以监控和服务器的数据交互是否正常等,无感事件中常用的是扫描采集,比如app启动之后,扫描各设置开关的状态信息进行上报等
业务埋点和监测埋点:
业务埋点是从业务需求的角度而言,比如产品需要统计某个页面的曝光和点击,算法人员需要的推荐项点击率等;而监测埋点是从业务的流程上来讲的,一般是指隐性的(比如服务器交互的内容拉取情况、本地潜在信息的生成情况等),此外业务埋点中的关键部分也可以用作监测埋点。
五、最理想的埋点方式?
回到一开始的问题:何种埋点方式最理想呢?
正如同硬币有两面,任何单一的埋点方式都存在优点与缺点,企图通过简单粗暴的几行代码/一次部署、甚至牺牲用户体验的埋点方式,都不是企业所期望的。要满足精细化、精准化的数据分析需求,可根据实际需要的分析场景,选择一种或多种组合的采集方式,毕竟采集全量数据不是目的,实现有效的数据分析,从数据中找到关键决策信息实现增长才是重中之重。
因此,数据采集只是数据分析的第一步,数据分析的目的是洞察用户行为,挖掘用户价值,进而促进业务增长,故最理想的埋点方案是根据根据不同的业务和场景以及行业特性和自身实际需求,将埋点通过优劣互补方式进行组合,比如:
1、代码埋点+全埋点:在需要对落地页进行整体点击分析时,细节位置逐一埋点的工作量相对较大,且在频繁优化调整落地页时,更新埋点的工作量更加不容小觑,但复杂的页面存在着全埋点不能采集的死角,因此,可将代码埋点作为辅助,将用户核心行为进行采集,从而实现精准的可交叉的用户行为分析;
2、代码埋点+服务端埋点:以电商平台为例, 用户在支付环节,由于中途会跳转到第三方支付平台,是否支付成功需要通过服务器中的交易数据来验证,此时可通过代码埋点和服务端埋点相结合的方式,提升数据的准确性;
3、代码埋点+可视化埋点:因代码埋点的工作量大,可通过核心事件代码埋点,可视化埋点用于追加和补充的方式采集数据。
六、流量分析系统中日志埋点
6.1 选择客户端埋点
客户端埋点:支持 iOS、安卓、Web/H5、微信小程序,主要用于分析 UV、PV、点击量等基本指标。例:下图是Web端的埋点技术图:
6.2 服务器规划
七、日志埋点的实现
7.1 客户端埋点
在网页流量分析系统中,采用客户端网页埋点实现,在其中需要埋点的页面中的<head></head>
中加入如下代码:
<script src="tj.js"></script>
注:tj.js 就是需埋点的 js 文件
/**函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串。*/
function ar_encode(str)
{//进行URL编码return encodeURI(str);
}/**屏幕分辨率*/
function ar_get_screen()
{var c = "";if (self.screen) {c = screen.width+"x"+screen.height;}return c;
}/**颜色质量*/
function ar_get_color()
{var c = "";if (self.screen) {c = screen.colorDepth+"-bit";}return c;
}/**返回当前的浏览器语言*/
function ar_get_language()
{var l = "";var n = navigator;if (n.language) {l = n.language.toLowerCase();}elseif (n.browserLanguage) {l = n.browserLanguage.toLowerCase();}return l;
}/**返回浏览器类型IE,Firefox*/
function ar_get_agent()
{var a = "";var n = navigator;if (n.userAgent) {a = n.userAgent;}return a;
}/**方法可返回一个布尔值,该值指示浏览器是否支持并启用了Java*/
function ar_get_jvm_enabled()
{var j = "";var n = navigator;j = n.javaEnabled() ? 1 : 0;return j;
}/**返回浏览器是否支持(启用)cookie */
function ar_get_cookie_enabled()
{var c = "";var n = navigator;c = n.cookieEnabled ? 1 : 0;return c;
}/**检测浏览器是否支持Flash或有Flash插件*/
function ar_get_flash_ver()
{var f="",n=navigator;if (n.plugins && n.plugins.length) {for (var ii=0;ii<n.plugins.length;ii++) {if (n.plugins[ii].name.indexOf('Shockwave Flash')!=-1) {f=n.plugins[ii].description.split('Shockwave Flash ')[1];break;}}}elseif (window.ActiveXObject) {for (var ii=10;ii>=2;ii--) {try {var fl=eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash."+ii+"');");if (fl) {f=ii + '.0';break;}}catch(e) {}}}return f;
}/**匹配顶级域名*/
function ar_c_ctry_top_domain(str)
{var pattern = "/^aero$|^cat$|^coop$|^int$|^museum$|^pro$|^travel$|^xxx$|^com$|^net$|^gov$|^org$|^mil$|^edu$|^biz$|^info$|^name$|^ac$|^mil$|^co$|^ed$|^gv$|^nt$|^bj$|^hz$|^sh$|^tj$|^cq$|^he$|^nm$|^ln$|^jl$|^hl$|^js$|^zj$|^ah$|^hb$|^hn$|^gd$|^gx$|^hi$|^sc$|^gz$|^yn$|^xz$|^sn$|^gs$|^qh$|^nx$|^xj$|^tw$|^hk$|^mo$|^fj$|^ha$|^jx$|^sd$|^sx$/i";if(str.match(pattern)){ return 1; }return 0;
}/**处理域名地址*/
function ar_get_domain(host)
{//如果存在则截去域名开头的 "www."var d=host.replace(/^www\./, "");//剩余部分按照"."进行split操作,获取长度var ss=d.split(".");var l=ss.length;//如果长度为3,则为xxx.yyy.zz格式if(l == 3){//如果yyy为顶级域名,zz为次级域名,保留所有if(ar_c_ctry_top_domain(ss[1]) && ar_c_ctry_domain(ss[2])){}//否则只保留后两节else{d = ss[1]+"."+ss[2];}}//如果长度大于3else if(l >= 3){//如果host本身是个ip地址,则直接返回该ip地址为完整域名var ip_pat = "^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$";if(host.match(ip_pat)){return d;}//如果host后两节为顶级域名及次级域名,则保留后三节if(ar_c_ctry_top_domain(ss[l-2]) && ar_c_ctry_domain(ss[l-1])) {d = ss[l-3]+"."+ss[l-2]+"."+ss[l-1];}//否则保留后两节else{d = ss[l-2]+"."+ss[l-1];}}return d;
}/**返回cookie信息*/
function ar_get_cookie(name)
{//获取所有cookie信息var co=document.cookie;//如果名字是个空 返回所有cookie信息if (name == "") {return co;}//名字不为空 则在所有的cookie中查找这个名字的cookievar mn=name+"=";var b,e;b=co.indexOf(mn);//没有找到这个名字的cookie 则返回空if (b < 0) {return "";}//找到了这个名字的cookie 获取cookie的值返回e=co.indexOf(";", b+name.length);if (e < 0) {return co.substring(b+name.length + 1);}else {return co.substring(b+name.length + 1, e);}
}/**设置cookie信息操作符:0 表示不设置超时时间 cookie是一个会话级别的cookie cookie信息保存在浏览器内存当中 浏览器关闭时cookie消失1 表示设置超时时间为10年以后 cookie会一直保存在浏览器的临时文件夹里 直到超时时间到来 或用户手动清空cookie为止2 表示设置超时时间为1个小时以后 cookie会一直保存在浏览器的临时文件夹里 直到超时时间到来 或用户手动清空cookie为止* */
function ar_set_cookie(name, val, cotp)
{var date=new Date;var year=date.getFullYear();var hour=date.getHours();var cookie="";if (cotp == 0) {cookie=name+"="+val+";";}else if (cotp == 1) {year=year+10;date.setYear(year);cookie=name+"="+val+";expires="+date.toGMTString()+";";}else if (cotp == 2) {hour=hour+1;date.setHours(hour);cookie=name+"="+val+";expires="+date.toGMTString()+";";}var d=ar_get_domain(document.domain);if(d != ""){cookie +="domain="+d+";";}cookie +="path="+"/;";document.cookie=cookie;
}/**返回客户端时间*/
function ar_get_stm()
{return new Date().getTime();
}/**返回指定个数的随机数字串*/
function ar_get_random(n) {var str = "";for (var i = 0; i < n; i ++) {str += String(parseInt(Math.random() * 10));}return str;
}/* main function */
function ar_main() {//收集完日志 提交到的路径var dest_path = "http://127.0.0.1:8081/log?";var expire_time = 30 * 60 * 1000;//会话超时时长//处理uv//--获取cookie ar_stat_uv的值var uv_str = ar_get_cookie("ar_stat_uv");var uv_id = "";//--如果cookie ar_stat_uv的值为空if (uv_str == ""){//--为这个新uv配置id,为一个长度20的随机数字uv_id = ar_get_random(20);//--设置cookie ar_stat_uv 保存时间为10年ar_set_cookie("ar_stat_uv", uv_id, 1);}//--如果cookie ar_stat_uv的值不为空else{//--获取uv_iduv_id = uv_str;}//处理ss//--获取cookie ar_stat_ssvar ss_stat = ar_get_cookie("ar_stat_ss");var ss_id = ""; //sessin idvar ss_count = 0; //session有效期内访问页面的次数var ss_time = "";//--如果cookie中不存在ar_stat_ss 说明是一次新的会话if (ss_stat == ""){//--随机生成长度为10的session idss_id = ar_get_random(10);//--session有效期内页面访问次数为0ss_count = 0;//--当前事件ss_time = ar_get_stm()} else { //--如果cookie中存在ar_stat_ss//获取ss相关信息var items = ss_stat.split("_");//--ss_idss_id = items[0];//--ss_countss_count = parseInt(items[1]);//--ss_stmss_time = items[2];//如果当前时间-当前会话上一次访问页面的时间>30分钟,虽然cookie还存在,但是其实已经超时了!仍然需要重新生成cookieif (ar_get_stm() - ss_time > expire_time) {//--重新生成会话idss_id = ar_get_random(10);//--设置会话中的页面访问次数为0ss_count = 0;//--当前事件ss_time = ar_get_stm();}else{//--如果会话没有超时//--会话id不变//--设置会话中的页面方位次数+1ss_count = ss_count + 1;ss_time = ar_get_stm();}}//--重新拼接cookie ar_stat_ss的值value = ss_id+"_"+ss_count+"_"+ss_time;ar_set_cookie("ar_stat_ss", value, 0);//当前地址var url = document.URL;url = ar_encode(String(url));//当前资源名var urlname = document.URL.substring(document.URL.lastIndexOf("/")+1);urlname = ar_encode(String(urlname));//返回导航到当前网页的超链接所在网页的URLvar ref = document.referrer;ref = ar_encode(String(ref));//网页标题var title = document.title;title = ar_encode(String(title));//网页字符集var charset = document.charset;charset = ar_encode(String(charset));//屏幕信息var screen = ar_get_screen();screen = ar_encode(String(screen));//颜色信息var color =ar_get_color();color =ar_encode(String(color));//语言信息var language = ar_get_language();language = ar_encode(String(language));//浏览器类型var agent =ar_get_agent();agent =ar_encode(String(agent));//浏览器是否支持并启用了javavar jvm_enabled =ar_get_jvm_enabled();jvm_enabled =ar_encode(String(jvm_enabled));//浏览器是否支持并启用了cookievar cookie_enabled =ar_get_cookie_enabled();cookie_enabled =ar_encode(String(cookie_enabled));//浏览器flash版本var flash_ver = ar_get_flash_ver();flash_ver = ar_encode(String(flash_ver));//当前ss状态 格式为"会话id_会话次数_当前时间"var stat_ss = ss_id+"_"+ss_count+"_"+ss_time;//拼接访问地址 增加如上信息dest=dest_path+"url="+url+"&urlname="+urlname+"&title="+title+"&chset="+charset+"&scr="+screen+"&col="+color+"&lg="+language+"&je="+jvm_enabled+"&ce="+cookie_enabled+"&fv="+flash_ver+"&cnv="+String(Math.random())+"&ref="+ref+"&uagent="+agent+"&stat_uv="+uv_id+"&stat_ss="+stat_ss;//通过插入图片访问该地址document.getElementsByTagName("body")[0].innerHTML += "<img src=\""+dest+"\" border=\"0\" width=\"1\" height=\"1\" />";}window.onload = function(){//触发main方法ar_main();
}
说明:
①var dest_path = "http://127.0.0.1:8081/log?"
, 此处要改成日志服务器的地址,并且这个地址是能够被访问的,最后一个 "?"不要忘加,用来拼后续参数使用的。
②埋点的原理:js代码会动态在页面中创建一个宽和高都是1px的图片,图片的地址指向了1中定义的日志服务器中的图片,
document.getElementsByTagName("body")[0].innerHTML += "<img src=\""+dest+"\" border=\"0\" width=\"1\" height=\"1\" />";
7.2 服务器端开发(关键代码)
package com.logs.controller;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;@Controller
public class LogController {private Logger logger = LoggerFactory.getLogger(LogController.class);@RequestMapping("/log")public void log(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {//1.获取请求参数String qs = request.getQueryString();//2.对URL解码String decode = URLDecoder.decode(qs, "utf-8");//3.转换成需要处理的格式StringBuilder sb = new StringBuilder();String[] attrs = decode.split("&");for (String attr : attrs) {String[] kv = attr.split("=");String val = kv.length >= 2 ? kv[1] : "";sb.append(val+"|");}sb.append(request.getRemoteAddr());String logStr = sb.toString();
// System.out.println(logStr);logger.info(logStr);}
}
关于数据埋点的认识以及在流量分析系统中的实际使用相关推荐
- Python数据分析初探项目 基于Python数据可视化的网易云音乐歌单分析系统 大学编程作业(TUST 天津科技大学 2022年)
Python 数据分析初探项目 基于 Python 数据可视化的网易云音乐歌单分析系统 大学编程作业(TUST 天津科技大学 2022 年) Python 数据分析初探项目 基于 Python 数据可 ...
- 大数据离线---网站日志流量分析系统(1)---简介及框架
本次介绍网站日志流量分析系统,首先是简介和架构.后面会对架构中需要的每个模块的进行逐个介绍.本篇主要分为两个部分 网站日志流量分析系统简介 整体技术流程和架构 1. 网站日志流量分析系统简介 1.1点 ...
- 大数据实战:用户流量分析系统
---------------------------------------------------------------------------------------------------- ...
- 本机连接opc server有部分数据不刷新_实时数据库PI在企业MES系统中的应用
实时数据库是计算机控制系统和上层生产管理系统数据存储和展示的核心.结合河南天冠燃料乙醇有限公司MES系统应用实例,介绍了实时数据库PI的安装部署,建立信号量集和数据导入,以及客户端接口配置,数据库测试 ...
- python中显示第三行数据_Python从零开始第三章数据处理与分析①python中的dplyr(1)...
前言 我经常使用R的dplyr软件包进行探索性数据分析和数据处理. dplyr除了提供一组可用于解决最常见数据操作问题的一致函数外,dplyr还允许用户使用管道函数编写优雅的可链接的数据操作代码. 现 ...
- 大数据离线---网站日志流量分析系统---日志数据原始信息
这里式日志数据的原始信息 194.237.142.21 - - [18/Sep/2013:06:49:18 +0000] "GET /wp-content/uploads/2013/07/r ...
- 大数据毕业设计 基于时间序列的股票预测与分析系统 - 大数据分析
文章目录 1 简介 2 时间序列的由来 2.1 四种模型的名称: 3 数据预览 4 理论公式 4.1 协方差 4.2 相关系数 4.3 scikit-learn计算相关性 5 金融数据的时序分析 5. ...
- Android中的AOP编程之AspectJ实战实现数据埋点
文章背景 最近在给某某银行做项目的时,涉及到了数据埋点,性能监控等问题,那我们起先想到的有两种方案,方案之一就是借助第三方,比如友盟.Bugly等,由于项目是部署在银行的网络框架之内的,所以该方案不可 ...
- 企业级数据仓库:数据仓库概述;核心技术框架,数仓理论,数据通道Hive技术框架,HBase设计,系统调度,关系模式范式,ER图,维度建模,星型/雪花/星座模式,数据采集同步,业务数据埋点,数据仓库规范
文章目录 第一章 数据仓库概述 1.1 数据仓库简介 1.1.2 什么是数据仓库? 1.1.3 OLTP 与 OLAP 1.2 数据仓库技术架构 1.3 课程目标 第二章 核心技术框架 2.1 数据仓 ...
- 2022-itwangyang-前端数据埋点 SDK
前端数据埋点 SDK 前言 相信不少人因为项目中没有接触过数据埋点相关的内容,而没有花时间去了解它,总觉得这又是一个自己还不能涉及的方面,然而数据埋点本身并不难理解,只是很难做得好,本文会从 认识数据 ...
最新文章
- not optimal php,php环境配置 配置
- linux中rev命令详解,详解Linux中输出文件内容的rev与tac命令使用
- LeetCode之Rotate Array
- static代码块什么时候运行_健康的代码:什么时候该注释?
- Apache Spark 2.2.0 中文文档 - Spark RDD(Resilient Distributed Datasets)
- 域控服务器降级失败,降级域控制器时出错 - Windows Server | Microsoft Docs
- Django中Python3安装Crypto使用RSA
- 几个免费的IT技能学习视频网站
- 谷歌浏览器启动后,图标变成空白解决办法
- 【倒计时5天】PyCon China 2020 主题大揭秘!
- 智能家居-斐讯N1安装篇
- 推荐一款STM32F030K6T6兼容替换灵动MM32F031K6T6
- 比特鹏哥网课笔记(结构体,枚举,联合体,通讯录项目)
- java+poodle漏洞修复_SSLv3 Poodle攻击漏洞检测工具
- Springboot发送手机短信验证码并且校验
- git reset 3种方式
- k8s报错503或者其他网络错误 Readiness probe failed: HTTP probe failed with statuscode: 503
- 《青山翠影》玖 独行的时代 | 去程归程
- 面试干货!21个必知数据科学面试题和答案
- SMO组织的现状与发展
热门文章
- Dragonfly 三维可视化数据分析处理软件-切片分析工具使用教程
- 网站都变成灰色,一行代码就搞定了!
- iOS TestFlight Beta版本测试
- 浙江大学计算机学院复试拟录取名单,浙江大学计算机学院2015年考研复试拟录名单...
- [RK3288][Android6.0] 用户空间对音频寄存器的控制
- 分析锂电池充放电保护电路的特点及工作原理
- CUBA Platform
- 生成扩散模型漫谈:DDIM = 高观点DDPM
- 开机动画desc.txt描述文件的分析
- Art of Problem Solving: Proof without Words