• [技术干货] “结构体名”和“结构体名是个指针”的区别-转载
     经常看见下面这样的定义:  typedef struct {       int a;       double b;   }emp_i, *pemp_i;    //typedef 了两个新的数据类型(结构体),其中一个是指针方式的名字   int main(void)   {           char i = 'y';       emp_i  a1;    //emp_i 声明的a1是一个实体,声明了就已经有存储空间了       pemp_i  b1 = &a1;  //pemp_i 声明的b1是一个指针(但这里不用加*号,因为pemp_i已经被指定为指针),它可以指向一个struct a 的实体。        a1.a++;      //a1的元素访问方式  实体方式        b1->a++;   //b1的访问方式  指针方式   }  也就是说,用结构体名字去定义声明的变量是一个真正的变量,他在内存中分配有自己的存储空间;而是用指针去形式定义的变量是一个指针,使用的时候给他赋予一个结构体变量的地址。  访问方式不一样:结构体变量直接访问使用实体方式,用点;结构体变量使用指针方式,如上面例子所示。 ———————————————— 版权声明:本文为CSDN博主「微电子学与固体电子学-俞驰」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/appleyuchi/article/details/126641509 
  • [技术干货] UserAgent的使用方法
    1、UserAgent的简介      User Agent即用户代理,简称为UA,是一种特殊的字符串头,会使得服务器能够识别客户使用的操作系统、版本、CPU 类型、浏览器版本、浏览器渲染引擎、浏览器语言、浏览器插件等等,是不感觉很厉害的样子,通过这个串头,我们就可以进行获得很多的信息,从而进行相关业务的处理。      在server抓包的时候,会经常碰到直接使用wget或者curl被服务器拒绝的状况,这时候只需要通过增加一个user-agent串头进行模拟就可以通过了。2、查看User Agent的方法2.1 通过js获取      在浏览器地址栏中输入以下代码navigator.userAgent      或者window.navigator.userAgent      进行获取相关信息,获取后的信息会是这个样子的:'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/xxx (KHTML, like Gecko) Chrome/xxx Safari/xxx'2.2 通过Chrome开发者模式获取      打开chrome开发者模式(快捷键是F12),或者在网页上右键选择检查(快捷键是Ctrl+Shift+I),在Network栏中找到需要查询的请求,在Headers的最后可以看到User-Agent的相关信息了。这种方法可以通过模拟机型,在选择模拟的设备机型后,找到相应的请求就可以找到这类机型所对应的User-Agent信息了。3、User-Agent的应用3.1 User-Agent在js中的应用      其中判断是否是微信环境,通常我们会通过window.navigator.userAgent获取User-Agent串头后进行转小写,然后通过正则匹配/MicroMessenger/i是否为'micromessenger'来判断是否是微信内部浏览器从而判断是否是微信环境,这里如果不加window的话Android机可能会判断不了是否是微信,所以还是加上比较保险。function isWX() { var ua = window.navigator.userAgent.toLowerCase(); if (ua.match(/MicroMessenger/i) == 'micromessenger') { return true; } else { return false; }} 3.2 User-Agent在java中的应用       通常我们会通过reques请求中获取header中的user-Agent元素,然后进行转小写,在获取到信息之后,我们就可以通过这个User-Agent串头信息来进行环境判断了,其中包含micromessenger则为微信内部浏览器标识,即微信内部环境,在微信内部环境又包括小程序和企微,我们通过判断User-Agent串头信息是否包含wxwork元素来判断是否为企微环境,通过判断User-Agent串头信息是否包含miniprogram来判断是否为小程序环境下。String userAgent = request.getHeader("user-agent").toLowerCase();if (userAgent.indexOf("micromessenger") < 0) {// 非微信 return true;} else{ if (userAgent.indexOf("wxwork") > 0) { // 企业微信客户端 return true; }else if(userAgent.indexOf("miniprogram") > 0){//小程序下 return true; }}以上就是User-Agent的相关应用和总结。
  • [技术干货] 初识Webpack
    1. 摘要Webpack是一种前端资源构建工具,一个静态模块打包器。在Webpack看来,前端的所有资源文件(js/json/css/img/less/…)都会作为模块处理,当Webpack处理应用程序时,它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源。Webpack打包流程图如图1-1所示。图1-1 Webpack打包流程图2. Webpack五个核心概念2.1 Entry入口(Entry)指示Webpack以哪个文件作为入口起点分析构建内部依赖图并进行打包。2.2 Output输出(Output)指示Webpack打包后的资源bundles输出到哪里去,以及如何命名。2.3 LoaderLoader让Webpack能够去处理那些非JavaScript语言的文件,Webpack本身只能理解JavaScript。2.4 Plugins插件(Plugins)可以用于执行范围更广的任务,插件的范围包括从打包和压缩,一直到重新定义环境中的变量等。2.5 Mode模式(Mode)指示Webpack使用相应模式的配置。分为development和production两种模式,下面分别进行简述。development: 开发模式,能让代码本地运行的环境,会将process.env.NODE_ENV的值设为development,同时启用NamedChunksPlugin和NamedModulesPlugin插件;production: 生产模式,能让代码优化运行的环境,会将process.env.NODE_ENV的值设为production,同时启用FlagDependencyUsagePlugin、FlagIncludedChunksPlugin、ModuleConcatenationPlugin、NoEmitOnErrorsPlugin、OccurrenceOrderPlugin、SideEffectsFlagPlugin和UglifyJsPlugin插件。3. Wbepack配置3.1 webpack.config.js文件webpack.config.js是webpack的配置文件,用来指示webpack工作,运行webpack指令时,会加载里面的配置,所有构建工具都是基于nodejs平台运行的,默认采用commonjs模块化。webpack.config.js基础配置如图3-1所示。图3-1 webpack.config.js基础配置3.2 devServer配置开发服务器(devServer)用来实现自动化(自动编译、自动打开浏览器、自动刷新浏览器),只会在内存中编译打包,不会有任何文件输出,本地安装webpack-dev-server后,通过npx webpack-dev-server命令启动devServer,核心代码如图3-2所示。图3-2 devServer配置核心代码3.3 打包html/样式/图片/其它资源打包不同的资源会使用不同的loader和插件,打包html/样式/图片/其它资源的流程如下所述。3.3.1 打包html资源1.下载html-webpack-plugin插件;2.引入html-webpack-plugin插件;3.使用html-webpack-plugin插件,并进行相应配置。3.3.2 打包样式资源不同的样式文件需要配置不同的loader1.下载loader;2.配置loader,css样式文件使用css-loader和style-loader,less文件使用less-loader、css-loader和style-loader。其中css-loader的作用是将css文件变成commonjs模块加载到js文件中,style-loader的作用是创建style标签,将js中的样式资源插入进去,添加到head中生效。3.3.3 打包图片资源1.下载url-loader,file-loader2.配置loader3.3.4 打包其它资源1.下载file-loader2. 配置loader,配置该loader作用于不为html/css/less/js的其他文件3.4 提取css成单独文件/css兼容性处理/压缩css3.4.1  提取css成单独文件样式文件打包后会默认和js文件一起输出,可以通过插件将打包后的css文件单独输出,流程如下所述。1.下载mini-css-extract-plugin插件2.引用该插件3.配置3.4.2 css兼容性处理1.下载postcss-loader和postcss-preset-env2.在package.json中browsetslist属性中分别对开发环境和生产环境进行兼容性配置,设置支持样式的浏览器版本3.通过postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式。3.4.3 压缩css1.下载optimize-css-assets-webpack-plugin插件2.引用该插件3.使用该插件3.5 js语法检查eslint/js兼容性处理/js压缩3.5.1 js语法检查eslint1.下载eslint-loader和eslint2.在package.json中的eslintConfig中进行配置3.配置eslint-loader,其中只需检测js文件并要排除第三方库,只检测自己写的源代码,同时可在options配置中设置fix:true,自动修复eslint的错误。3.5.2 js兼容性处理    1.下载babel-loader、@babel/core、@babel/preset-env,通过@babel/preset-env做基本的js兼容性处理,然后通过corejs做前面无法实现的兼容性处理,并实现按需加载    2. 配置loaderjs兼容性处理核心代码如图3-3所示图3-3 js兼容性处理核心代码3.5.3 js压缩mode设置为production生产环境时会自动压缩js代码。4. webpack性能优化可以从开发环境和生产环境分别对webpack进行性能优化。其中开发环境主要考虑从打包构建速度和代码调试两个方面进行优化,生产环境主要考虑从打包构建速度和代码运行性能这两个方面进行优化。下面简单介绍下开发环境上通过HMR提升构建速度。4.1 HMR    HMR(热模块替换),作用是一个模块发生变化后,只会更新打包这一个模块而不是所有模块,通过在devServer中设置hot:true属性启动HMR功能。其中对于样式文件,可以使用HMR功能,因为style-loader内部实现了;对于js文件,默认不能使用HMR功能,解决方法:修改入口文件js代码,添加支持HMR功能的代码,另外HMR只能处理非入口js文件的其他文件,对入口文件并不能生效,因为一旦入口文件更新,入口文件引入的其他文件一定会被重新加载;对于html文件,默认不能使用HMR功能,同时会导致html文件不能热更新,解决方法:修改entry入口文件,将html文件引入,只能解决html文件不能热更新的问题。js文件支持HMR功能的核心代码如图4-1所示。图4-1 js文件支持HMR功能核心代码4.2  HMR效果在入口index.js文件中引入print.js文件,运行npx webpack-devserver后,页面如图4-2所示。4-2 初始页面修改print.js文件后,只会重新加载print.js文件,而不会重新加载index.js文件,HMR效果如图4-3所示。4-3 HMR效果图
  • [技术干货] 前端树结构优化
    ## 一、 场景和问题 树结构,多级嵌套(不确定几级),使用递归方式实现,数据量上万情况下,页面加载很慢。 数据结构:十个父级节点,每个父节点有10000个子节点,父子是嵌套关系 #### 代码: ![image.png](https://bbs-img-cbc-cn.obs.cn-north-1.myhuaweicloud.com/data/attachment/forum/202008/21/1015289541bgbfss4v8yqi.png) #### 页面加载: ![image.png](https://bbs-img-cbc-cn.obs.cn-north-1.myhuaweicloud.com/data/attachment/forum/202008/21/101559ltvf2s6kmuwa5w36.png) 此时页面渲染需要13.5s ## 二、问题解决 #### 2.1 树数据结构扁平化 ![image.png](https://bbs-img-cbc-cn.obs.cn-north-1.myhuaweicloud.com/data/attachment/forum/202008/21/101735nlhao6wsmnqgwpin.png) 从performance工具定位问题:调用栈createChildren被疯狂调用,在vue源码中,createChildren做的是创建Vue实例这件事。创建Vue实例包括依赖收集、响应式监听、数据事件绑定、编译模板等等。 如果能将数据结构扁平化,就只会有一个tree组件,createChildren只执行进行一次。 扁平化数据还有个好处就是: + 减少栈的读取,递归的本质是栈的读取,栈的读取是由解析器做的,扁平化可以减少V8引擎的开销。 + 扁平化数据可以减少dom 的数量。 ![image.png](https://bbs-img-cbc-cn.obs.cn-north-1.myhuaweicloud.com/data/attachment/forum/202008/21/101744sxwbkqtpgc9ccmou.png) 扁平化后优化到6.5s,我们觉得6.5s还是远远不够 #### 2.2 虚拟长列表 我们可以用懒加载解决海量数据一次性加载的问题,但是最终dom数量还是很大,容易造成页面卡顿。 所以我们使用虚拟长列表解决这个问题: ![image.png](https://bbs-img-cbc-cn.obs.cn-north-1.myhuaweicloud.com/data/attachment/forum/202008/21/101800h4an6sdtrumx9beu.png) 通过虚拟长列表,我们就控制住了DOM数量。 #### 2.3 其他优化思考 滚动事件加防抖,但要保证滚动的平滑度,使我们需要去权衡的。样式直接在数据中输出,不通过计算:树结构缩进padding距离不通过层级计算,而是在数据中直接给出样式,避免每个节点都计算一次样式的性能问题。
总条数:53 到第
上滑加载中