前端白屏检测方案

2023-10-27

早期因为浏览器、技术、兼容性等诸多问题,导致网页的显示效果非常的单一,基本都是静态页,后续随着Angular、React、Vue等前端框架的出现,采用SPA单页面应用的方案越来越多。
用户和企业对于页面的稳定性、性能有了更高的诉求,根据Aberdeen Group的调研发现从浏览器输入地址开始访问到页面展示的最佳时间为3秒内,每多一秒的延迟会使客户满意度降低16%。Apdex(Application Performance Index)方法由 Peter Sevcik 于 2004 年首次描述。目标是有一个简单统一的开放标准来报告应用程序性能,而不管它是如何测量的。该标准将用户对应用的体验定义为三个等级,T为时间秒(s),如图1.1所示:

                                                        图1.1 等待时间和使用者情绪

所以各个公司对于自己公司应用的性能和稳定性都极为重视,有的依赖于三方提供的性能方案,国内的方案如: fundebug、岳鹰、arms,国外的产品有sentry,有的依赖于公司自己研发的方案。但是基于的原理基本都大同小异,我们这次主要谈论白屏的问题,中间也会穿插其他性能的介绍。首先,页面加载时,只有等js和css文件加载完成之后,首屏才能渲染,这就会导致出现白屏的问题,白屏是我们经常遇到的情况,白屏时间的长短影响用户对网站的第一印象,所以白屏问题很影响客户的使用体验。
近些年,公司业务高速发展,随着业务需求的增多,新兴的前端项目也是越来越多。此时对前端攻城师的交付质量有了更高的要求,性能方面是个重要的指标,白屏检测可以帮助前端人员在日常开发中预防白屏的发生,进而提升项目质量,提交客户的使用体验。下面会针对什么是白屏时间和如何检测做一个详细的介绍。

1 什么是"白屏时间"

白屏时间是指用户输入网站地址到浏览器开始显示内容的时间。当用户打开一个链接或者在浏览器输入一个地址开始访问的时候,就开始等待页面的展示,页面渲染的时间越短,用户等待的时间就越短,用户的感知越好,减少用户的跳出,这样可以极大的提升用户的体验。需要注意的是白屏并不是特指屏幕为白色,“白屏"也有可能是黑色的,重点是用户等待的时间过长,或者页面异常导致没有有效的页面,此类情况,我们都称之为"白屏”。
页面的白屏情况有以下几种:
(1)首屏加载前的白屏。
(2)页面代码崩溃导致的页面无法加载的白屏。
(3)资源代码错误导致spa无法渲染白屏。

1.1 正常"白屏"时间

1)白屏产生场景

此类白屏属于正常访问页面时产生的时间,中间涉及的为网络请求,资源加载,页面绘制等。此类正常的白屏时间是我们关注的性能指标,正常的白屏时间会给用户很大的观感体验,时间越短,用户的满意度和体验会越好。

2)白屏产生过程

白屏时间是页面展示过程中的一部分,所以就涉及到了一个老生常谈的问题———从浏览器输入地址到页面展示的过程,如图1.2所示。

                                                        图1.2 页面从url到展示过程

(1)DNS查询,域名解析,获取服务器的IP。
(2)建立TCP链接。
(3)客户端发送HTTP请求。
(4)服务器响应请求。
(5)浏览器解析并渲染页面。

                                                                图1.3 页面加载过程

如图1.3所示,我们可以很清楚的看到页面的整个加载过程,从输入url后到页面的渲染展示过程中的等待时间, 我们就视为"白屏时间",此类的白屏时间归类为正常的白屏,因为最终的结果是页面可以渲染出来的。对于这个时间的加载优化需要极为重视,因为性能问题是多种多样的。情况好点的,网站和应用程序产生一些微不足道的延迟,这些延迟会给用户一些不好的交互体验。也有及其糟糕的情况,那就是它们完全无法访问,对用户输入没有反应,或两者兼而有之。很多不利网站访问速度的因素会形成累加,从而严重影响网站的性能,导致网站访问速度变慢,用户体验低下,最终导致用户流失。

1.2 异常"白屏"

1)异常白屏产生场景

表现是浏览器无法查看有效页面,但是产生的这种情况的原因则不相同,正常的白屏为我们可以查看到页面加载完毕的结果,但是异常导致的白屏则不能,异常的白屏主要是发生在HTTP响应和浏览器渲染过程。

2)白屏原因

异常类的白屏可能是资源,或代码异常导致的页面白屏,这种情况下,我们正常检测白屏的代码可能还未加载,所以这时候无法使用正常的白屏方案检测,需要通过后端模拟浏览器访问,查看是否白屏。图1.4为通过后端检测出来的白屏,这类情况因为资源加载错误或js报错引发的"白屏",通过前端sdk无法监控到,所以需要通过后端模拟加载页面来查看是否出现"白屏"现象。

                                                                图1.4 异常资源白屏

2 白屏检测方案

2.1 首屏加载时白屏

针对首屏加载前的白屏,可以使用 Navigation Timing API 作为标准方案来作为白屏的时间。为了帮助开发者更好地衡量和改进前端页面性能,W3C性能小组引入了 Navigation Timing API ,实现了自动、精准的页面性能打点;开发者可以通过 window.performance 属性获取。Performance.timing 只读属性返回一个 PerformanceTiming 对象,这个对象包括了页面相关的性能信息。performance.navigation(定义了当前文档的导航信息,比如是重载还是向前向后等)。

1)Performance.timing浏览器兼容性

Performance.timing浏览器兼容性,如图1.5所示。

                                                        图1.5 Performance.timing兼容性介绍

2)performance.timing对应时间节点

在浏览器控制台,console输入performance可以查看到performance.timing相关时间节点m,如图1.6所示。

                                                图1.6 performance.timing参数介绍

通过navigation timing不仅可以帮助我们省去繁琐的手动打点操作,还可以帮助我们获取很多其他数据,对于整个时间节点的对应关系,如图1.7所示。

                                                图1.7 performance.timing参数说明

我们比较有用的页面性能数据大概包括如下几个:
(1)DNS查询耗时 :domainLookupEnd - domainLookupStart
(2)TCP链接耗时 :connectEnd - connectStart
(3)request请求耗时 :responseEnd - responseStart
(4)解析dom树耗时 : domComplete- domInteractive
(5)白屏时间 :responseStart - navigationStart
(6)domready时间 :domContentLoadedEventEnd - navigationStart
(7)onload时间 :loadEventEnd - navigationStart
(8)NavigationTiming的目的是用于分析页面整体性能指标。如果要获取个别资源(例如JS、图片)的性能指标,就需要使用Resource Timing API。

3)首屏加载白屏时间检测方案

A. 白屏时间收集

在上一小节,我们知道了通过performance可以计算白屏时间,白屏时间可以使用responseStart - navigationStart来计算,下面我们来实现一下主要的代码部分:

let t;
const result = {};
const _performance =
      window.performance || window.msPerformance || window.webkitPerformance;

if (_performance) {
  if (
    _performance.getEntriesByType &&
    _performance.getEntriesByType('navigation') &&
    _performance.getEntriesByType('navigation')[0]
  ) {
    t = _performance.getEntriesByType('navigation')[0];
  } else if (_performance.timing) {
    t = _performance.timing;
  }
  // 除了白屏指标,在这里我们还可以监控其他指标,比如dns,fcp,ttfb,domload等
  result.blankTime = (t.responseStart || t.domLoading) - t.navigationStart || t.fetchStart);
}

B. 数据上报

页面性能统计数据对丢失率要求比较低,并且性能统计应该在尽量不影响主流程的逻辑和页面性能的前提下进行。所以主要使用 img 标签的方式进行上报,虽然古老,但是不存在跨域的问题,基本是大家的首要选择方案。

var eventLogimg = new Image();
//  url为上报的数据内容
eventLogimg.src = url;

2.2 系统崩溃时白屏

对于崩溃式的白屏,我们一般通过检测的方式,进行排查,目前一般通过puppeteer无头浏览器进行模拟访问进行排查。
Puppeteer 是一个控制 headless Chrome 的 Node.js API 。它是一个 Node.js 库,通过 DevTools 协议提供了一个高级的 API 来控制 headless Chrome。它还可以配置为使用完整的(非 headless)Chrome。所有我们在浏览器的所有操作,都可以通过Puppeteer进行模拟和操作。
所以我们创建一个Puppeteer的服务应用,模拟访问,并对页面做白屏的计算,查看是否是白屏,简单使用的demo:

const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});
  await browser.close();
})();

1)检测方案

A. 通过MutationObserver检测

MutationObserver接口提供了监视对DOM树所做更改的能力。它被设计为旧的Mutation Events功能的替代品,该功能是DOM3 Events规范的一部分。
MutationObserver()创建并返回一个新的 MutationObserver 它会在指定的DOM发生变化时被调用。这个api可以实现对白屏的检测,具体实现原理是:
(1)侦听页面元素的变化;
(2)遍历每次新增的元素,并计算这些元素的得分总和;
(3)如果元素可见,得分为1 * weight(权重),如果元素不可见得分为0;
(4)最后根据得分判断是否是白屏。
通过前端设置项目的阀值,超过多少权重则表示为白屏,后端通过前端设置的配置,使用Puppeteer进行模拟浏览器访问,通过MutationObserver计算评分来判断是否出现白屏,如图1.8所示。

                                                                图1.8 白屏检测实现方案

相应的方法如下:
(1)disconnect()。阻止 MutationObserver 实例继续接收的通知,直到再次调用其observe()方法,该观察者对象包含的回调函数都不会再被调用。
(2)observe()。配置MutationObserver在DOM更改匹配给定选项时,通过其回调函数开始接收通知。
(3)takeRecords()。从MutationObserver的通知队列中删除所有待处理的通知,并将它们返回到MutationRecord对象的新Array中。
举一个简单的例子:

// 选择需要观察变动的节点
const targetNode = document.getElementById('observation-id');
// 观察器的配置(需要观察什么变动)
const config = { attributes: true, childList: true, subtree: true };
// 当观察到变动时执行的回调函数
const callback = function(mutationsList, observer) {
    // Use traditional 'for loops' for IE 11
    for(let mutation of mutationsList) {
        if (mutation.type === 'childList') {
            console.log('A child node has been added or removed.');
        }
        else if (mutation.type === 'attributes') {
            console.log('The ' + mutation.attributeName + ' attribute was modified.');
        }
    }
};
// 创建一个观察器实例并传入回调函数
const observer = new MutationObserver(callback);
// 以上述配置开始观察目标节点
observer.observe(targetNode, config);
// 之后,可停止观察
observer.disconnect();

>注意:因为我们是通过Puppeteer模拟浏览器访问,所以不存在MutationObserver的浏览器兼容问题。

B. 通过判断某个区域的元素是否存在

通过document.elementsFromPoint,进行取点,该函数返回还在特定坐标点下的HTML元素数组。在页面的onload事件后,获取界面十字线上的点,然后可以获取到里面的元素,因为这个能获取最里面的元素,所以就通过这个进行判断,如果排除html,body等容器标签,仍有标签存在,那就不是空白点,否则是空白点,根据业务需要设定空白点比值,大于这个值就是白屏,例如:垂直方向取10点个,水平方向取10个点,如果最后空白点的数量大于18个,代表页面白屏,进行页面白屏的报警触发。

// 检测白屏
const checkBlank = function () {
    if (!document.elementsFromPoint) {
        return;
    }
    // 排除body和html标签
    const excludeElements = ['body', 'html']
    // 计算画的多少无内容的标签
    let nothingElement = 0
    // 计算画的区域一共多少标签
    let totalElement = 0
    const getElements = (el) => {
        if (!el) return ''
        return (el.classList && el.classList[0]) || el.id || el.localName
    }
    const isWrap = (el) => {
        if (!el) return;
        totalElement++
        if (excludeElements.indexOf(getElements(el)) >= 0) {
            nothingElement++
        }
    }
    let elementsX, elementsY;
    // 画区域,检测区域内标签
    for (let i = 1; i < 10; i++) {
        elementsX = document.elementsFromPoint(window.innerWidth * i / 10, window.innerHeight / 2)
        elementsY = document.elementsFromPoint(window.innerWidth / 2, window.innerHeight * i / 10)
        isWrap(elementsX[0])
        isWrap(elementsY[0])
    }
    // 判断是否白屏
    if (totalElement - nothingElement < 2) {
        return true;
    }
    return false;
};

C. 通过图像识别

图像识别可以通过对页面访问时截取的图片做识别,查看图片是否为白屏。但是这个方案并不能检测所有的白屏,因为并不是所有的异常都会以白色的方式进行显示。

2)方案对比

方案\对比项 MutationObserver elementsFromPoint 图像识别
检测白屏 可以监控 可以监控 可以监控部分情境下白屏
性能 需要检测多个元素点 通过设置区域或关键点检测元素 通过图片识别
优势 通过权重的方式计算各个元素的占比,计算方式更合理 通过画点计算,性能更快 优势不明显
劣势 使用者需要针对不同的页面做详细的元素以及权重的设置,使用体验不好 可能某些区域没有足够的元素去检测导致白屏误报,所有也需要针对每个页面做白屏点设置 无法检测所有情况下的白屏

3 白屏检测方案实践

3.1 整体设计

我们的目标是对于正常情况下的白屏做汇总,通过汇总的表格内容查看,对于异常情况下的白屏需要做预警,当发现有异常的白屏,通过手机、短信等方式进行预警。所以我们最需要的是主动预警,这样我们就可以放心的睡觉了。当系统出现异常,系统马上通知我们,我们通过详情快速定位问题,修复bug,如图1.9所示。

                                                        图1.9 白屏检测告警模块

整体设计方案,如图1.10所示。

                                                        图1.10 白屏检测整体设计方案

用户接入sdk,并在管理系统设置项目信息、预警信息、白屏检测页面等配置。在正常白屏产生的情况下,sdk上报性能数据到日志中心,定时任务定时拉取日志中心的数据并做聚合汇总后,数据保存到数据库中,用户可以通过项目管理查看项目性能指标。对于异常的白屏内容,白屏服务定时检测页面,判断是否有白屏情况的产生,如果有白屏的情况产生则通过预警机制进行预警。用户收到预警信息后,可以在白屏检测系统查看白屏检测详情。

3.2 方案选择

正常的白屏就使用performance的属性来检测,对于异常的白屏,针对这三种方案,我们最终选择使用判断某个区域的元素个数来判断是否白屏。具体方案为垂直方向取20点个,水平方向取20个点,如果最后空白点的数量大于某个数值,代表页面白屏,通过取多个点来降低白屏检测错误率。
难点问题,因为很多页面为需要登陆才可以检测的页面,我们无法直接检测这样的页面,所以需要解决登陆的问题,在管理页面提供了用户填写鉴权方式功能,使用者根据自己项目的实际使用,设置字段和值,如图1.11所示。

                                                        图1.11 解决登录问题方案

通过白屏的定时检测,可以查看白屏检测的汇总结果,如图1.12所示,可以查看异常和正常的数量,通过详情,可以查看每个页面白屏检测的详情,如图1.13所示。

                                                               图1.12 白屏检测结果

图1.13 白屏检测结果详情

4 总结

页面性能差的话会非常影响用户体验,但是在使用过程中,页面性能差的情况并不少见。白屏是个重要的性能指标,我们的目标是记录所有的白屏情况,需要按照两种情况进行汇总,一个是正常的白屏情况,通过请求上报汇总,进行展示,可以通过上报的各个指标查看项目的详情。针对不同的情况做项目的优化。第二种是异常情况下的白屏,通过无头浏览器模拟访问项目页面,通过上面的方式检测页面是否白屏,并做记录和汇总,如果出现错误则进行预警。
白屏检测可以帮助我们详细的掌握我们项目的质量以及是否影响用户体验,同时在出现问题的时候可以及时收到预警反馈。在白屏检测中除了白屏时间的显示还有页面性能,dom加载时间以及是否有缓存,有无缓存的对比加载,有助于我们专注我们的项目已经优化项,可以把错误和不良体验扼杀在摇篮里。
在开发过程中,如何让页面更快更好更稳定的运行,是区分一个前端攻城狮专业水平和视野的重要指标,作为前端工程师最核心的价值或者责任就是将大伙所有努力的结果最终完美的呈现给客户,所以我们需要重视这些性能指标。通过对页面性能的提升,带给客户更好的产品体验,这样才会得到好的产品反馈,给企业带来价值。

参考资料

【1】https://developer.mozilla.org/zh-CN/docs/Web/API/Performance/timing
【2】https://www.w3.org/TR/navigation-timing/
【3】https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver
【4】https://www.w3.org/TR/DOM-Level-3-Events/
【5】https://www.apdex.org/?spm=a2c4g.11186623.2.8.7a0b5c7cSIyNEd

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

前端白屏检测方案 的相关文章

  • 监控显卡显存(python代码)

    一 前言 我和我同学的代码 分别占用14G显存 而显卡的显存只有24G 没有办法同时跑 所以 他先跑 我的代码时刻监控显存的使用情况 只要显卡显存大于14G 我的代码就自动启动 二 代码 import pynvml import time
  • Fiddler工具 — 9.命令行和状态栏

    1 命令行 命令行在Fiddler的左下方的黑色窗口 也叫 QuickExec 可以调用 Fiddler的内置命令 这一系列内置的函数用于筛选和操作会话列表中的session 会话 虽然它不是很显眼 但用好它 会让你的工作效率提高 N 倍
  • Vue + Element-ui组件上传图片报错问题解决方案

    在使用Vue和Element ui组件上传图片时 可能会遇到一些报错问题 以下是一些常见的问题及解决方案 报错 TypeError Cannot read property name of undefined 解决方案 这个错误通常是因为在
  • React安装依赖 node_modules中有下载依赖项但package.json文件中没有依赖

    React安装依赖 node modules中有下载依赖项但package json文件中没有依赖 直接在下载依赖项后 加 S 就可以解决 随机 id 生成器 uuid nanoid npm install nanoid S S save
  • Firefox浏览器-渗透测试插件推荐

    在日常工作中可能需要一些浏览器插件辅助我们做工作 下面是比较好的 当然不一定对你有用 找到适合自己的即可 FoxyProxy FoxyProxy是一个高级的代理管理工具 它完全替代了Firefox有限的代理功能 它提供比SwitchProx
  • Typecho 最新XC主题 去除域名授权全解密源码

    简介 Typecho 最新XC主题 去除域名授权全解密源码 这是一款多样式主题 首页支持六种主题样式 支持Pjax优化访问速度 多种单页 如友链 说说等 评论支持表情 自定义编辑器 支持其他样式功能 该主题功能性挺高 比较花里胡哨 感觉有一
  • 【面试】 前端竞争压力大?揭秘让你们学后端的真实动机!

    前端开发属于程序员吗 网友是这样回答的 看完前端同学的评论 我悟了 你们让人都去学后端卷 然后减小前端竞争压力是吧 哈哈哈 你们这帮老6 于是我去拿出了我收藏的 某前端招聘JD来盘一盘 那些觉得 是个人都能干前端 的同学们想必已经熟练掌握了
  • Element-Puls中el-upload组件结合vue-draggable-plus实现上传支持拖拽排序(并保留el-upload原有样式、预览、删除)等功能

    展示效果 需求 需求想要一个可拖拽排序的图片列表 但是发现el upload虽然可以实现照片墙 但是没办法拖拽 实现思路 使用 vue draggable plus 拖拽插件 隐藏Upload原有的已上传文件列表 自定义上传后文件列表的样式
  • 拼多多详情API开启运营比价新纪元

    随着互联网的快速发展 电商行业正在迅速崛起 拼多多作为一家新兴的电商平台 凭借其独特的营销策略和创新的商业模式 成为了电商行业的一匹黑马 在拼多多的成功背后 其详情API接口营销起到了至关重要的作用 本文将详细介绍拼多多详情API接口营销的
  • 如何给 unplugin-vue-components/vite 写一个简单的 resolver

    大部分工作 unplugin vue components 都已经处理好了 我们只需要接收组件名来判断是否是自己的组件 然后处理对应的导入逻辑 一共 3 个字段 as 重命名类似 import componentNameReName fro
  • 【连续和自适应资源需求估计】通过不断应用在线优化、选择和估计,SARDE能够有效地适应在线跟踪,并使用得到的集成技术减少模型误差(Python代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Python代码 数据 文章
  • Web 安全漏洞之 OS 命令注入

    什么是 OS 命令注入 上周我们分享了一篇 Web 安全漏洞之 SQL 注入 其原理简单来说就是因为 SQL 是一种结构化字符串语言 攻击者利用可以随意构造语句的漏洞构造了开发者意料之外的语句 而今天要讲的 OS 命令注入其实原理和 SQL
  • 每天10个前端小知识 <Day 8>

    1 Javascript中如何实现函数缓存 函数缓存有哪些应用场景 函数缓存 就是将函数运算过的结果进行缓存 本质上就是用空间 缓存存储 换时间 计算过程 常用于缓存数据计算结果和缓存对象 缓存只是一个临时的数据存储 它保存数据 以便将来对
  • 基于java的web仓库管理系统设计与实现

    基于java的web仓库管理系统设计与实现 I 引言 A 研究背景和动机 基于Java的Web仓库管理系统是近年来快速发展的领域之一 它提供了丰富的功能 如数据存储 数据检索 数据分析和数据可视化等 本文将重点介绍基于Java的Web仓库管
  • 低代码-添加按钮组件设计

    效果图 可拆分为以下细节 按钮列表 删除 两个操作需同步删除 点击外侧删除 点击复选框删除 添加 点击复选框添加 示例代码 技术栈 vue3 arco design ts less tailwindcss
  • 低代码-详情页组件设计

    效果图 详情页数据结构定义 layout 按钮数据 buttonLayout headButton 页头按钮 footButton 页脚按钮 详情页表单配置 config 配置组件列表 detailLayout 默认行为 进表单初始化 只展
  • chrome浏览器无法在地址栏输入内容搜索问题解决--图文

    关于日常遇到的小问题解决记录一下 1 导航栏录入信息后跳转错误 2 解决办法 默认百度搜索引擎地址错误 百度正确的搜索格式是 http www baidu com s wd s chrome浏览器中百度的搜索格式是 http www bai
  • 每日变更的最佳实践

    在优维公司内部 我们采用发布单的方式进行每天的应用变更管理 这里给各位介绍优维的最佳实践 变更是需要多角色合作的 而且他是整体研发流程的一部分 在优维内部 我们坚持每日变更 打通开发环节到最终发布上线的全过程 在保证质量的前提下 尽可能提升
  • 【js学习之路】遍历数组api之 `filter `和 `map`的区别

    一 前言 数组是我们在项目中经常使用的数据类型 今天我们主要简述作用于遍历数组的api filter 和 map 的区别 二 filter和map的共同点 首先 我们主要阐述一下 filter 和 map 的共同点 api的参数都是回调函数
  • 获取年与年之间的所有年份

    function getYearsBetween startYear endYear var years 存放结果的数组 for var year startYear year lt endYear year years push year

随机推荐

  • 《30天自制操作系统》入门方法总结

    30天自制操作系统 是一位日本大佬 川合秀实 老师所写的一本书 逻辑清晰 语言朴实 我跟着中文版的电子书学习了两天 感觉很好 在这里我就实操环节简单做一下总结 以帮助初学者更好的入门 1 操作系统和编辑器 我使用的是win10 64位 专业
  • 关联规则算法(Apriori算法、FP-Growth算法)小案例(python mlxtend)

    目录 一 Apriori 二 FP Growth 一 Apriori 算法理论部分参考 28条消息 Apriori算法与FP Tree算法 messi james的博客 CSDN博客 import pandas as pd 构造数据集 it
  • Unity打包安装包时出现CommandInvokationFailure: Gradle build failed.

    Unity打包安卓安装包时出现CommandInvokationFailure Gradle build failed 我首先是上网百度了一下 看到有许多方法 其中有人这样说 教训是 出现报错 不要上来就上网寻找答案 大家配置不一样 适合别
  • EMD(经验模态分解)算法 二

    上次基本搞懂了怎么用各种滤波器 这次重点看看EMD的算法应用 怎么调参数以产生不同的分解波形 EMD经验模态分解 emd lt as data frame emd xt diff load Load boundary wave stopru
  • 三进制计算机_一分钟基础:计算机为什么采用二进制?

    这是博主新想到的一个点子 旨在用最短的篇幅介绍知识 积少成多 希望朋友们能够有所收获 另外 最近事情属实太多 鸽了一个多月 感谢各位朋友没取关 我真不是在提醒各位取关 等忙完这段 希望自己也能做一个日更博主2333 PS 我改名了 最高权限
  • 请你说说instanceof 与 typeof的区别

    为什么 null instanceof Object是false 而typeof null是Object 在 JavaScript 中 null instanceof Object 的结果是 false 这是因为 null 是一个特殊的原始
  • android安卓开发调试经验

    android安卓开发调试经验 在哪查看错误信息 Run Console LogCat 常见错误 网络问题 检查权限
  • 【千律】C++基础:通过函数实现数据交换--指针方案

    include
  • 链表求和

    I 问题描述 你有两个用链表代表的整数 其中每个节点包含一个数字 数字存储按照在原来整数中相反的顺序 使得第一个数字位于链表的开头 写出一个函数将两个整数相加 用链表形式返回和 给出两个链表 3 gt 1 gt 5 gt null
  • RTT-移植Nano

    RTT 移植Nano 一 准备工作 STM32F103模板工程 RTT nano源码 https www rt thread org document site rt thread version rt thread nano an0038
  • Spring源码深度解析:九、bean的获取③ - createBeanInstance

    一 前言 文章目录 Spring源码深度解析 文章目录 createBeanInstance 的流程图如下 让我们根据流程图一步一步的学习一下spring是如何创建bean的吧 这篇文章是接着 Spring源码深度解析 八 bean的获取
  • 基于TensorFlow的CNN卷积网络模型花卉分类(1)

    一 项目描述 使用TensorFlow进行卷积神经网络实现花卉分类的项目 加载十种花分类 建立模型后进行预测分类图片 环境 win10 TensorFlow gpu 1 12 0 pycharm 训练集 训练数据存放路径为 D LearnM
  • 用bat批量重命名不同文件夹下的同名文件

    起因 手机B站离线的视频目录是这个样子的 视频的每一个分P都会生成一个文件夹 包含视频基本资料和一个名为80的文件夹 这个文件夹里放着后缀名为m4s的音频和视频文件 现需要使用电脑播放下载的视频 那么第一步就是更改视频和音频文件的后缀名 百
  • 防火墙总结

    一 什么是防火墙 防火墙分为软件防火墙和硬件防火墙 他们的优缺点 硬件防火墙 拥有经过特别设计的硬件及芯片 性能高 成本高 当然硬件防火墙也是有软件的 只不过有部分功能由硬件实现 所以硬件防火墙其实是硬件 软件的方式 软件防火墙 应用软件处
  • Failed to load module “canberra-gtk-module“ 或 Using GTK+ 2.x and GTK+ 3 in the same process is not

    项目场景 ubuntu安装matlab之后 运行时报错Failed to load module canberra gtk module 如下 原因分析 未安装Matlab运行所需要的依赖 执行如下命令 sudo apt get insta
  • 深入浅出UML类图(二)

    类与类之间的关系 1 在软件系统中 类并不是孤立存在的 类与类之间存在各种关系 对于不同类型的关系 UML提供了不同的表示方式 1 关联关系 关联 Association 关系是类与类之间最常用的一种关系 它是一种结构化关系 用于表示一类对
  • 树的四种遍历C/C++实现

    树的四种遍历C C 实现 树的四种遍历C C 实现 结构定义 先序创建树 先序遍历 中序遍历 后序遍历 层次遍历 总代码 给懒人下载运行用 运行示例 树的四种遍历C C 实现 备考期末 懂得都懂 手敲遍代码 比较懒 都是递归形式 结构定义
  • error LNK2019: 无法解析的外部符号 WSAStartup,该符号在函数 “public:

    error LNK2019 无法解析的外部符号 gethostname 该符号在函数 public static bool cdecl gdcm System GetHostName char const GetHostName Syste
  • Fragment 实现简易新闻界面(适配手机与Pad)

    一 前言 Android 在 Android 3 0 API 级别 11 中引入了 Fragment 主要目的是为大屏幕 如平板电脑 上更加动态和灵活的界面设计提供支持 由于平板电脑的屏幕尺寸远胜于手机屏幕尺寸 因而有更多空间可供组合和交换
  • 前端白屏检测方案

    早期因为浏览器 技术 兼容性等诸多问题 导致网页的显示效果非常的单一 基本都是静态页 后续随着Angular React Vue等前端框架的出现 采用SPA单页面应用的方案越来越多 用户和企业对于页面的稳定性 性能有了更高的诉求 根据Abe