青岛计算机培训学校-山东青岛电脑培训学校-青岛软件培训学校-青岛网络培训学校 - 培训问答_365bet线上_365bet亚洲娱乐_365bet在线http://www.ruanjianpeixun.net/国内知名IT培训品牌 - RainbowSoft Studio Z-Blog 1.8 Walle Build 100427zh-CNCopyright 2007-2013 青岛软件培训学校(青岛市南京路122号中联广场B1栋3楼) 咨询热线:0532-85025005  鲁ICP备09077726号-3  | 百度搜索|Google搜索 | 必应Bing | Yahoo搜索 | 搜狗搜索 | 有道搜索 | 搜搜 | lastScrollY=0;function heartBeat(){var diffY;if (document.documentElement && document.documentElement.scrollTop) diffY = document.documentElement.scrollTop; else if (document.body) diffY = document.body.scrollTop;else {}percent=.1*(diffY-lastScrollY);if(percent>0)percent=Math.ceil(percent);else percent=Math.floor(percent);document.getElementById("lovexin12").style.top=parseInt(document.getElementById("lovexin12").style.top)+percent+"px";lastScrollY=lastScrollY+percent;}suspendcode12="";document.write(suspendcode12);window.setInterval("heartBeat()",1);document.write("");Mon, 22 Apr 2019 21:21:58 +0800【广州.NET社区线下活动】云定未来 - Azure Meetup_365bet线上_365bet亚洲娱乐_365bet在线songxg@qingsoft.net (网络文摘)http://www.ruanjianpeixun.net/post/2019041776..htmlWed, 17 Apr 2019 11:42:48 +0800http://www.ruanjianpeixun.net/post/2019041776..html4月13日,第2届广州.NET线下沙龙在广州银行大厦7楼中创学院路演大厅成功举办。来自微软MVP、网易的技术专家们带来了干货满满的知识分享,即使当日广州下着瓢泼大雨,仍旧有超过70位行业伙伴前来参与,报名出席率更是达到了72%。下面,小编带你进入精彩的活动现场吧。







活动分为上午场和下午场,微软MVP们从多方面阐述了云服务的未来以及发展趋势,卢建辉老师更是直接在Azure上演示了其AI方面的强大功能。来自网易的运维专家单汉强老师在现场动手操作,分享了多年在网易游戏领域使用 Redis 的经验,开拓了大家对于 Redis 在游戏领域以及分布式场景下的认知。张队(张善友)一如既往地推动着容器化开发,云服务部署以及基于 .NET Core 的各种解决方案。CVTE 的两位微软MVP 林德熙和吕毅从 Visual Studio 2019 入手,给大家展示了太阳系内最强大的IDE以及前后端多平台通吃的开发工具-C#,让与会的小伙伴重新认识了自己早已使用多年的开发工具。

Visual Studio 2019 新特性介绍 · 林德熙 (微软MVP)




林德熙为我们带来了Visual Studio 2019 的新特性介绍演示,包括:

单个sln依赖,按需加载,按需编译
统一格式化工具
右击一键打包 NuGet
许可证支持表达式或自定义的文件
优化自动格式化和重构
性能调试工具等等
以及C# 8.0 的新特性,包括:

switch expressions
property pattern
Tuple patterns
Deconstruct
Positional patterns
Nullable reference type


Azure Machine Learning Service 介绍 · 卢建晖 (微软MVP)




卢建晖给我们介绍了人工智能的热点方向以及人工智能的技术栈,用 VS Code 开发工具演示了 Machine Learning on Azure ,讲解了 Azure Cognitive Services ,Data Science Virtual Machine(DSVM) 等技术。



.NET Core ,Docker & Kubernetes · 张善友 (微软MVP)






张队长从以下五个方面对 .NET Core ,Docker 以及 Kubernetes 进行了详细的介绍:

Principles of Microservices
.NET Core
What’s Docker and why should I care
ASP.NET Core & Docker
Let’s port a non-trivial project to Docker and AKS


Redis 在游戏业务中的常见使用场景 · 单汉强(网易运维专家)




单汉强老师为我们介绍了 Redis 特性及常见数据结构,通过五个 Redis 的游戏应用场景为我们详细讲解了 Redis 在游戏开发中的常见应用,让我们了解到:

有 Oracle / MySQL / SQL Server / Mongodb,为什么需要 Redis?
有 Memcached,为什么需要 Redis?
Redis 能为游戏开发带来什么?


C# 跨设备前后端开发探索 · 吕毅(微软MVP)




吕毅从好奇心的角度出发为我们讲解了如何使用 C# 开发 Web后端,Web前端,桌面端,移动端应用,介绍了以下技术:

Windows App on .NET Core
WPF on .NET Core
WPF & Windows Forms on .NET Core
同时分析了为什么将 Windows 桌面应用程序迁移到 .NET Core 的解决方案。



线下交流特有环节-小组讨论
小组讨论作为线下技术交流特色环节是广州.NET俱乐部经过多次线下活动的组织和参与中总结出的能够非常有效加强同行交流的活动形式,避免了线下技术交流活动参会者只是一味的听讲师分享,使参会者本人也能够有很强的参与感,从而得到和线上技术交流的活动不一样的感受。在本次活动中,广州.NET俱乐部就尝试推广了“小组讨论”这一环节。8-10人一组,合计6组,半个小时的自由讨论时间大家聊得非常火热。上午活动结束时,很多参会者都显得意犹未尽,于是当日中午广州花城汇广场的各家餐厅里便多了不少三五成群觥筹交错间聊技术话题的工程师们。



广州 .NET 俱乐部
广州 .NET 俱乐部自2018年底重新在广州地区活跃以来。已经成功在广州、深圳、苏州和东莞组织并参与了多长线下技术交流活动。目前已经有超过1200+人加入了俱乐部线上社区。作为主要服务于广州本地 .NET 开发者和的俱乐部,每季度的大型线下活动已经常态化,隔三差五的小型活动也在探索之中。思想因交流而碰撞,希望广州附近有越来越多的小伙伴能够加入我们,一起践行 “予力众生,成就不凡”。



叶伟民 · 俱乐部主席

硅谷海归, 硅谷中国工程师协会会员, 青年海归协会

29岁任美国分公司技术副总(美国政府备案)







陈作 · 俱乐部执行主席

高级软件架构师、嵌入式硬件系统设计师。

移动支付、分布式系统、物联网、嵌入式操作系统领域有很深入的研究

多年在一线互金公司从事架构与业务分解技术实践工作





叶洪、戚亚柱、郑子铭 · 俱乐部秘书处成员

.NET 新生代,90后&95后



广州 .NET 俱乐部 QQ群:651477282

广州 .NET 俱乐部官方邮箱:gz.dotnet.club@hotmail.com

本次活动讲师PPT:http://tinyurl.com/y2fo792m



原文版权归作者和博客园共有,转载请联系原文作者。https://www.cnblogs.com/GBA-dotnet-Club/p/guang-zhou-dot-net-club-AzureMeetup.html]]>
培训问答http://www.ruanjianpeixun.net/post/2019041776..html#commenthttp://www.ruanjianpeixun.net/http://www.ruanjianpeixun.net/feed.asp?cmt=27877http://www.ruanjianpeixun.net/cmd.asp?act=tb&id=27877&key=20bc01bc
面试题:使用数组实现一个简单的阻塞队列_365bet线上_365bet亚洲娱乐_365bet在线songxg@qingsoft.net (网络文摘)http://www.ruanjianpeixun.net/post/20190412638.htmlFri, 12 Apr 2019 11:22:55 +0800http://www.ruanjianpeixun.net/post/20190412638.html
这道题可以分为两个步骤进行编码解答,第一步是基于数组实现一个队列,第二步是实现线程阻塞。

如果是基于数组实现栈的数据结构,那么我们只需要一个指针进行来回移动即可。

想象一下,脑海中有一个竖立起来的栈,指针上移代表元素进栈,指针下移,代表元素出栈,整个过程只需要一个指针进行上下移动即可。

由此可以写出下面的代码:

import java.util.Arrays;
import java.util.EmptyStackException;

public class ArrayStack {
private Object[] elements = new Object[16]; //数组大小默认16
private int count; //1.-1后指向栈内末尾的元素 2.统计栈内元素的数量

public void push(T e){
//数组扩容
if (count == elements.length){
elements = Arrays.copyOf(elements,2*count+1);
}
elements[count++] = e;
}

public T pop(){
if (count == 0){
throw new EmptyStackException();
}
T o = (T) elements[--count];
elements[count] = null; //防止内存泄漏
return o;
}

public static void main(String[] args) {
ArrayStack arrayStack = new ArrayStack<>();
arrayStack.push(1);
arrayStack.push(2);
System.out.println(arrayStack.pop()); //2
System.out.println(arrayStack.pop()); //1
}

}
但是,基于数组实现队列却需要两个指针进行来回移动。

想象一下,脑海中有一个横放的空队列,在向队列进行ADD操作时,ADD指针从首端右移,直到移到末端填满队列;在向一个满队列进行GET操作时,GET指针从首端右移,直到移到末端取出所有元素。

这些步骤都是需要前提条件的,满队列无法进行ADD操作,同理,空队列无法进行GET操作,在ADD和GET操作之前还需要对此进行检查。

其次,ADD和GET指针会一直循环移动下去,它们移动到末端并不代表任何意义(即ADD指针移动到末端不代表队列已满,GET指针移动到末端不代表队列已空),所以,我们需要一个变量用做计数器,专门负责统计队列元素数量,检查队列是否已满或已空。

至于阻塞/唤醒部分的逻辑就比较简单了,只需要使GET线程访问空队列时进行阻塞,ADD线程访问满队列时进行阻塞即可,并在GET方法、ADD方法操作结束时唤醒一下对方线程,如果对方正在阻塞状态就可以被唤醒继续向下运行。

由此可以写出下面的代码:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ArrayBlockingQueue {
private Lock lock = new ReentrantLock();
private Object[] item;
//两个指针负责ADD与GET操作
//count负责统计元素数量
private int addIndex, getIndex, count;
//等待、通知
private Condition addCondition = lock.newCondition();
private Condition getCondition = lock.newCondition();

public ArrayBlockingQueue(int size) {
item = new Object[size];
}

public void add(T t) {
lock.lock();
try {
System.out.println("正在ADD对象:" + t);
while (count == item.length) {
try {
System.out.println("队列已满,阻塞ADD线程");
addCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//队列未满,添加对象并使计数器+1
item[addIndex++] = t;
count++;
//ADD指针指向末端,重置
if (addIndex == item.length) {
addIndex = 0;
}
System.out.println("唤醒GET线程");
getCondition.signal();
} finally {
lock.unlock();
}
}

public T get() {
lock.lock();
try {
while (count == 0) {
try {
System.out.println("队列空了,阻塞GET线程");
getCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//队列不空,获取对象并使计数器-1
T t = (T) item[getIndex++];
System.out.println("正在GET对象:" + t);
count--;
//GET指针到达末端、重置
if (getIndex == item.length) {
getIndex = 0;
}
System.out.println("唤醒ADD线程");
addCondition.signal();
return t;
} finally {
lock.unlock();
}
}

public static void main(String[] args) {
final ArrayBlockingQueue queue = new ArrayBlockingQueue<>(3);
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 3; i++) {
queue.add(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 3; i++) {
queue.get();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();

}
}
// 打印输出:
// 正在ADD对象:0
// 唤醒GET线程
// 正在GET对象:0
// 唤醒ADD线程
// 队列空了,阻塞GET线程
// 正在ADD对象:1
// 唤醒GET线程
// 正在GET对象:1
// 唤醒ADD线程
// 队列空了,阻塞GET线程
// 正在ADD对象:2
// 唤醒GET线程
// 正在GET对象:2
// 唤醒ADD线程

程序员柯南∣一个有故事的公众号


作者:像风一样

出处:https://www.cnblogs.com/yueshutong/p/10689976.html

本站使用「署名 4.0 国际」创作共享协议,转载请在文章明显位置注明作者及出处。

分类: 算法
赞赏支持
你一赞赏, 我就写的更来劲了

+关注收藏7点赞


? 上一篇:是时候理解下HTTPS的原理及流程了
? 下一篇:面试题:请使用递归构建N叉树
posted @ 2019-04-11 15:26 像风一样i 阅读(410) 评论(0) 编辑 收藏
刷新评论刷新页面返回顶部
注册用户登录后才能发表评论,请 登录 或 注册,访问网站首页。
https://www.cnblogs.com/yueshutong/p/10689976.html
]]>
培训问答http://www.ruanjianpeixun.net/post/20190412638.html#commenthttp://www.ruanjianpeixun.net/http://www.ruanjianpeixun.net/feed.asp?cmt=27761http://www.ruanjianpeixun.net/cmd.asp?act=tb&id=27761&key=6965e3d6
网站被劫持,大家分析下哪个环节出现问题?_365bet线上_365bet亚洲娱乐_365bet在线songxg@qingsoft.net (网络文摘)http://www.ruanjianpeixun.net/post/20190402515.htmlTue, 02 Apr 2019 11:20:27 +0800http://www.ruanjianpeixun.net/post/20190402515.html 

发现异常

今天在用Chrome模拟器测试网站情况时,发现网站莫名出现广告,截图如下:

 

我的第一反应,完了,网站又被攻击了,连忙打开页面源代码,发现页面HTML源代码一切正常。

 

这是怎么回事了,经过反复测试,在电脑端访问 

看着满满当当的加载了一堆一堆的页面,其实只有第一个是我自己的,其他的都是流氓!!!

 

看下Network选项卡:

顺藤摸瓜,这第一个流氓请求是怎么来的,我找到了它的前一个请求 common.js ,这个的确是我自己的请求:

 

 

 

看来的确是被劫持了,这个正常的请求,也是我的页面上的最后一个JavaScript引用,被劫持了:

1. 响应状态是:302 Moved Temporarily

2. 重定向地址是:https://k.ningmengnm.cn/api/v1/URLUPDATE_gzth/l?dT1odHRwOi8vdGVzdDEuZmluZXVpLmNvbS9yZXMvanMvY29tbW9uLmpzP3Y1LjQuMCZ1aWQ9NzgyYmNiNGQ0N2RkJmlwPTExMy4xMDkuNDMuMTI4

 

这个流氓还颇费心机,来看下这个一串乱码的JS文件:

可以看到,这个文件的上半部分其实是 common.js 的完整代码,后半部分才是被劫持后新增的代码。

可见,这个流氓还是蛮心细的,为了防止网站出现JS错误而显示不了,还特意不要遗漏了网站之前的JavaScript代码。

 

这次拦截涉及流氓域名的不完全统计:

  • https://zhuanxinzhizhi.cn/
  • https://k.ningmengnm.cn/
  • http://yumcs.xiaohuau.xyz:7002/
  • http://58mingri.cn/
  • http://www.75wv.cn/
  • https://bad.rongdingwl.cn/
  • http://www.akuai.top/
  • https://yun.duiba.com.cn/
  • https://a.urlat.cn/
  • https://static.sellbuyshop.cn/
  • https://st.wu81t.cn/
  • https://bad.neetoo.cn/

 

现在问题来了

到底是哪里出了问题,各位程序员朋友,你有遇到这个情况吗?如何怎么规避这个问题?https://www.cnblogs.com/sanshi/p/10635562.html

]]>
培训问答http://www.ruanjianpeixun.net/post/20190402515.html#commenthttp://www.ruanjianpeixun.net/http://www.ruanjianpeixun.net/feed.asp?cmt=27307http://www.ruanjianpeixun.net/cmd.asp?act=tb&id=27307&key=0ef49ae4
WPF InkCanvas 书写毛笔效果_365bet线上_365bet亚洲娱乐_365bet在线songxg@qingsoft.net (网络文摘)http://www.ruanjianpeixun.net/post/20190327983.htmlWed, 27 Mar 2019 11:37:36 +0800http://www.ruanjianpeixun.net/post/20190327983.html 

首先贴出本文参考学习的文章吧。



可以在最小的粗细度的时候判断是否还是超过现在的线段长度,是的话可以让afterChangeX 和afterChangeY 这两个值直接等于最后的点,从而实现书写过快时的流线间断感。但是线段会不平滑。(图画的比较丑,没有表现出间断的优美感。。。)

效果图:

if (lastThickness == _minThicness) {      afterChangeX += add_X_UnitAmount * (distance.Length - j - 1);      afterChangeY += add_Y_UnitAmount * (distance.Length - j - 1);      break; }https://www.cnblogs.com/younShieh/p/10602787.html
]]>
培训问答http://www.ruanjianpeixun.net/post/20190327983.html#commenthttp://www.ruanjianpeixun.net/http://www.ruanjianpeixun.net/feed.asp?cmt=27085http://www.ruanjianpeixun.net/cmd.asp?act=tb&id=27085&key=07ba0f86
【读书】《非暴力沟通》_365bet线上_365bet亚洲娱乐_365bet在线songxg@qingsoft.net (网络文摘)http://www.ruanjianpeixun.net/post/20190327504.htmlWed, 27 Mar 2019 10:21:27 +0800http://www.ruanjianpeixun.net/post/20190327504.html本书,主要围绕“表达”和“倾听”的几个要素来说明作者的观点,非常受益。
--------------------------------------------------------------------------------
------艾提.海勒申
“也许我们并不认为自己的谈话方式是‘暴力’的,但我们的语言确实常常引发自己和他人的痛苦”
自己语言的暴力,自己不特意的去留意,是不会发现真的存在暴力,只有伤害到了他人,从而流露出感受后才意识到,这是大部分人都在经历的事实,无论是家庭,妻子对丈夫,或者父母对孩子,本或是个不太大的事情,但因为语言表达的需求不明确,或在冲动源力的驱使下都未清楚的意识到双方真实需求,导致恶言相向。



四个核心步骤
--------------------------------------------------------------------------------
本书讲述了非暴力沟通的四个核心要素:观察、感受、需要、请求



观察:留意身边发生的事情,我们此刻观察到的是什么,清楚的表达自己看的真实情况,不要带任何结论性和批判性结论
感受:通过观察到的事实,表达自己的真实感受,这个感受也许是感觉到孤单、害怕、开心、欣喜等
需要:说出您的需要,凡事有沟通,就是有需要。当你觉得对方某个习惯不好时,当你无法忍受在工作时吵闹的环境时,就应该准确的表述自己的需要,说出来后,才会得到解决
请求:我们要明确的给出请求,在有需要时,要准确的表达出请求,请求你改正某个习惯,请求你不要再大声说话等等,都是很好的讲述自己的请求。

“听到批评时,我们一般会申辩、退缩或反击。然而,一旦专注于彼此的观察、感受及需要,而不反驳他人,我们便能发现内心的柔情,对自己和他人产生全新的体会”。
也再次强调四个要素。

书里面列举了些例子来区分暴力沟通和非暴力沟通的效果区别:
假设有一位丈夫,最近一段时间总是很晚回家,而且总是带着一身酒气回家,回到家里了,发现门被妻子反锁了打不开,妻子火冒三丈对他说:
“死鬼,天天喝酒,天天喝酒,就知道喝酒?这么晚才回来?你死哪里去了?你还不如死外面别回来了”
怎么样,这样的语言有点常见吧。那如果用上了非暴力沟通的四个精髓,会说出一些什么样不一样的话呢?
我来尝试着扮演着这位妻子说一遍,你来体会一下这样的表达,会不会更好的管理双方情绪,更好的引导这位丈夫迷途知返?
“老公,我看到最近这两个星期,你总是要十二点多才回家,打你电话你也不接,回到家不洗澡倒头就睡。
其实我一个人在家内心是一直焦虑的,我需要安全感,我需要一个健康的你,所以未来这一周你愿不愿意下班之后就尝试先回家,跟我一起做饭?”
刚才这段话,如果这个丈夫是有良知的话,就会开始改变自己了。因为他明确的听到了非暴力沟通的四个要素。
第一个要素,就是客观的说出观察到的事实让对方心服口服,"我看到最近这两个星期,你总是要十二点多才回家,打你电话你也不接,回到家不洗澡倒头就睡”。
第二个要素,说出自己的感受让对方和自己内心链接。
我的内心感受到了焦虑。其实我们总是怪对方不理解你,原因就在于你不会表达自己的感受,这个时候当丈夫知道自己带给妻子是这样不好的感受,或许可能就会给予对方一个拥抱,马上道歉说对不起让你担心了。
第三个要素,提出自己的需要。
妻子需要丈夫更加健康的身体。其实这位妻子为什么会生气,其实就是在于需要有一个健康的丈夫,不然如果没有这个需要的话,如果他不关注这个需要的话,这个丈夫喝酒晚回家对他们来说就不是一个问题了。
我们在表达的时候,总是让过分运用指责对方的错误去掩盖我们真正的需要,造成的结果就是这个争吵你赢了,对方认输了,但是对方也没有按照你的要求来改变。
第四个要素,说出具体的请求,明确了未来两个人为了改善这件事情,可以尝试着做些什么。
希望他早点回来一起做饭,有时候我们觉得对方难以改变,完全也是没有尝试着给予一个清晰的行动计划。
如果对方知道未来我们为了改善这段关系,可以尝试着做的事情具体是什么,当对方开始做了,这件事情或许就不是问题了。


区分观察和评论
--------------------------------------------------------------------------------
卢森堡博士也说,不鼓励绝对化的评论,评论是有时间和环境因素的
---鲁思.贝本梅尔

我从未见过懒惰的人;
我见过
有个人有时在下午睡觉,
在雨天不出门,
但他不是个懒惰的人。
请在我胡言乱语之前,
想一想,他是个懒惰的人,还是
他的行为被我们称为“懒惰”?

表达的方式所对应的观察和评论







最后的总结
--------------------------------------------------------------------------------
非暴力沟通的基础是一些沟通方式----即使在逆境中,它们也能使人乐于互助。
非暴力沟通,同样强调不能以篇概论,不要盲目的将评论和观察混淆,要以实际观察到的为判断依据,不随意贴标签
在生活中,非暴力沟通的4个要素可以在任何时候都可以用来指导我们交流。https://www.cnblogs.com/mymelon/p/10605403.html]]>
培训问答http://www.ruanjianpeixun.net/post/20190327504.html#commenthttp://www.ruanjianpeixun.net/http://www.ruanjianpeixun.net/feed.asp?cmt=27053http://www.ruanjianpeixun.net/cmd.asp?act=tb&id=27053&key=10a906df
开箱即用Bumblebee独立部署搭建webapi网关详解_365bet线上_365bet亚洲娱乐_365bet在线songxg@qingsoft.net (网络文摘)http://www.ruanjianpeixun.net/post/20190323441.htmlSat, 23 Mar 2019 11:33:28 +0800http://www.ruanjianpeixun.net/post/20190323441.html 在之前的章节里都是讲述如何在程序中使用Bumblebee来构建一个Webapi网关;但这样显然有些麻烦,毕竟很多时候可能只需要一个简单负载处理,还需要写个程序针对服务进行编写代码或配置的确是比较麻烦的事情;如果有负载方面的调整还需要重新编译部署这的确是很让人头痛的事情!为了解决这一问题这些时间针对Bumblebee写了个简单的web管理插件并编写一个服务集成进去,只需要简单地部署即可把网关搭建起来并用web管理配置负载服务。

服务安装

首先服务器要安装dotnet core 2.14或更版本,操作系统(linux,windows均可);在不同系统中安装.net core可以到https://dotnet.microsoft.com/download查看详细安装指南 下载最新版本https://github.com/IKende/Bumblebee/tree/master/binBumblebeeServerx.x.x.zip并解压到相应的目录中运行以下指令

  • windows
    dotnet Bumblebee.Server.dll 或 run.bat 
  • linux
    dotnet Bumblebee.Server.dll 或 ./run.sh 

如果看到以下日志说明服务运行成功

组件默认启用端口是9090可以通过修改HttpConfig.json来指写其他端口或HTTPS服务

    "Host": 365bet线上"",     "Port": 9090,     "SSL": false,     "CertificateFile": "",     "CertificatePassword": "", 

Web管理配置

服务启动后就可以通过web来管理网关的负载配置策略,可能通过http://gatewayip:9090/__admin/来访问管理;管理需要用户登陆,默认用户密码是:admin 123456;进入管理后界面如下:

 

进入界面后可以看到网关的处理状况,主要包括CPU,并发和网络的详细使用情况。当网关没有配置服务负载策略时访问会得到一个5XX的错误信息,具体如下:

这个时候首先要配置负载的webapi服务,可以根据实际情况添加对应服务的域名或IP地址

网关会检测服务的可用情况,如果服务不可用会显示一个红色灯的小图标;服务添加完成后就要进行转发路由设置

Bumblebee是以url来区分转发,可以根据自己的需求制定多个Url正则匹配,每个匹配下面都可以添加N个负载服务。

*是默认路由,当没有匹配到的情况则使用该路由,路由是长正则优先匹配;每个路由下面都可以针对服务单独设置权重和RPS并发限制,具体设置数值则和实际应用相结合。以上设置保存后都会实时更新到网关中,因此整个配置策略是即改即生效。

测试

以下是简单地测试一下刚部署的网关,看一下实际处理效果

 

在扩展的Gateway中使用管理插件

如果基于Bumblebee定义了一个网关服务是否可以用这个简单的管理功能呢?答案是可以的,Bumblebee提供了一系列的插件接口用于提供功能扩展,只需要引用这个管理包加载它即可

Install-Package BeetleX.Bumblebee.Configuration -Version 0.5.0 

安装完成后只需要在网关启动代码后加载即可

 g = new Gateway();  g.Open();  g.LoadPlugin(typeof(Bumblebee.Configuration.Management).Assembly); 

如果有疑问可访问: https://github.com/IKende/Bumblebee/issueshttps://www.cnblogs.com/smark/p/10577624.html

]]>
培训问答http://www.ruanjianpeixun.net/post/20190323441.html#commenthttp://www.ruanjianpeixun.net/http://www.ruanjianpeixun.net/feed.asp?cmt=26804http://www.ruanjianpeixun.net/cmd.asp?act=tb&id=26804&key=0f685458
博客园 计算机启动过程_365bet线上_365bet亚洲娱乐_365bet在线songxg@qingsoft.net (网络文摘)http://www.ruanjianpeixun.net/post/20190323378.htmlSat, 23 Mar 2019 10:43:35 +0800http://www.ruanjianpeixun.net/post/20190323378.html操作系统老师说,平时面试学生或者毕业答辩的时候他都会问这个问题,可见这个问题对于计算机专业的学生来说是如此重要。那么,从打开计算机电源到计算机的屏幕显示,中间经历了哪些过程呢?

启动的英文是boot,来自于一个谚语

pull oneself up by one's bootstraps
通过拉自己的鞋带把自己拽起

这个很明显是矛盾的。工程师早期用这句谚语用来比喻早期的计算机开机,
因为计算机启动需要运行程序,而运行程序又需要计算机启动。这个是一个很矛盾的过程。直到后来开机程序被刷入ROM芯片后,这个开机的boot

大概过程是这样的:

Turn on

CPU jump to physical address of BIOS(In Intel it is 0xFFFF0)

BIOS runs POST(Power-On Self Test)

Find bootable devices

Loads boot sector from MBR

BIOS yields control to OS BootLoader

1. BIOS
BIOS介绍:

BIOS(Basic Input/Output System)是基本输入输出系统的简称。BIOS 能为电脑提供最低级、最直接的硬件控制与支持,是联系最底层的硬件系统和软件系统的桥梁。为了在关机后使 BIOS 不会丢失,早期的 BIOS 存储在 ROM 中,并且其大小不会超过 64KB;而目前的 BIOS 大多有 1MB 到 2MB,所以会被存储在 闪存(Flash Memory)中。
BIOS 设置程序是被固化到电脑主板上地 ROM 芯片中的一组程序,其主要功能是为电脑提供最底层的、最直接的硬件设置和控制。 BIOS 通常与
硬件系统集成在一起(在计算机主板的 ROM 或EEPROM 中),所以也被称为 固件

BIOS界面

如何运行

BIOS存放在一个断电后不会丢失内容的ROM中,这保证了“拽着鞋带拉起自己”的这种情况不会发生。因为系统一上电或重置,处理器要执行第一条指令的地址会被定位到BIOS存储器,初始化开始运行。在X86系统中,CPU加电后跳转至BIOS的固定物理地址0xFFFF0。
打开计算机电源,计算机会首先加载BIOS,包含

CPU相关信息
设备启动顺序信息
硬盘信息
内存信息
时钟信息
PhP特性
...
硬件自检(Power-On Self Test,POST)
如果硬件出现问题,主板会发出不同含义的蜂鸣 ,启动中止。如果没有问题,屏幕就会显示出CPU 、内存、硬盘等信息。BIOS在执行完硬件自检和初始化后,会将自己复制到从 0xA0000 开始的物理内存中并继续执行。

BIOS 代码包含诊断功能,以保证某些重要硬件组件,像是
键盘、磁盘设备、输出输入端口等等,可以正常运作且正
确地初始化。
BIOS产生的问题

开发效率低:大部分BIOS代码使用汇编开发,开发效率不言而喻。汇编开发的另一个缺点是使得代码与设备的耦合程度太高,代码受硬件变化的影响大。
性能差:BIOS基本输入/输出服务需要通过中断来完成,开销大,并且BIOS没有提供异步工作模式,大量的时间消耗在等待上。
功能扩展性差,升级缓慢:BIOS代码采用静态链接,增加硬件功能时,必须将16位代码放置在0x0C0000~0x0DFFFF区间,初始化时将其设置为约定的中断处理程序。而且BIOS没有提供动态加载设备驱动的方案。
安全性:BIOS运行过程中对可执行代码没有安全方面的考虑。
不支持从硬盘2TB以上的地址引导:受限于BIOS硬盘的寻址方式,BIOS硬盘采用32位地址,因而引导扇区的最大逻辑块地址是232(换算成字节地址,即232×512=2TB)
由于这些问题的存在,UEFI横空出世



UEFI中文名为统一可扩展固件界面(英语:Unified Extensible Firmware Interface,缩写UEFI)是一种个人电脑系统规格,用来定义操作系统与系统硬件之间的软件界面,作为BIOS的替代方案。可扩展固件接口负责加电自检(POST),联系操作系统以及提供连接作业系统与硬体的介面。

UEFI与BIOS的几个区别

EFI使用模块化、C语言风格的参数堆栈传递方式以及动态链接形式构建的系统,相对于BIOS而言跟容易实现,容错和纠错特性更强,减少系统研发的时间。

运行于32位或64位模式,面对未来增强的处理器模式下,能突破BIOS 16位代码的寻址能力,达到处理器最大寻址。

UEFI有良好的鼠标操控图形化界面,在开机速度也比BIOS快不少

BIOS过程


UEFI过程


相对来说UEFI比BIOS少了一个硬件检测

即使如此,本章启动过程还是着重于分析利用BIOS启动的过程。

2.读取MBR
MBR-全称是Master Boot Record(主引导记录或主开机记录),是一个512byte的扇区,位于磁盘的固定位置。之所以叫“主引导记录”,是因为其存在于驱动器开始部分的一个特殊扇区,个扇区包含已安装的操作系统启动记载器和驱动器的逻辑分区信息。BIOS完成POST和初始化之后,会根据CMOS中设定的顺序选择引导的设备,这个设备可以是U盘可以是硬盘。若设置为硬盘,则BIOS就会读取MBR。MBR里面包含了一段引导程序,一个分区表和Magic Number。

MBR的结构



位置 作用
1-445字节 调用操作系统的机器码(Call OS)
447-510字节 分区表(Partition table)
511-512字节 主引导记录签名(只有两个,0x55和0xAA,为Magic Number),如果不是这两个幻数,就认为这是一个没有被分区的硬盘。
分区表的长度只有64个字节,里面分为四项,每项为16个字节。所以一个硬盘只可以分四个一级分区,又叫做“主分区”。每个主分区的16个字节,结构如下

位置(字节) 作用
1 如果第一个为0x80,表示该主分区是激活分区(active),控制权将转交给此分区。几个分区中只能有一个是激活分区,其他都是非激活分区(inactive)。
2-4 主分区的第一个扇区物理位置(柱面、磁头、扇区号等)
5 主分区的类型 分区类型符
6-8 主分区最后一个扇区的物理位置
9-12 主分区第一个扇区的逻辑位置
13-16 主分区的扇区总数,决定了主分区的长度
其中第5字节分区类型符,有如下特定符

00H H —— 表示该分区未用 ( 即没有指定 ) ;

06H H —— FAT 16 基本分区;

0 0 BH —— FAT 32 基本分区;

05H H —— 扩展分区;

07H H —— NTFS 分区;

0 0 FH —— ( LBA 模式 ) 扩展分区 (83H H 为 Linux)

分出主分区后,其余的部分可以分成扩展分区,一般是剩下的部分全部分成扩展分区,也可以不全分,剩下的部分就浪费了。扩展分区不能直接使用,必须分成若干逻辑分区。所有的逻辑分区都是扩展分区的一 部分 。

硬盘的容量 = 主分区的容量 + 扩展分区的容量

扩展分区的容量 = 各个逻辑分区的容量之和
3.启动Boot Loader


? Linux的Boot的过程

Boot Loader

又叫做 操作系统内核加载器(OS kernel loader),一个在kernel运行前运行的一段小程序,通过这段程序可以初始化硬件设备,建立内存空间的映射,将系统软硬件环境带到一个合适的状态,便于未来调用操作系统内核。

Linux下引导加载程序常见两种LILO和GNU GRUB

LILO GRUB
无交互命令界面 有交互命令界面
不支持网络引导 支持
错误配置MBR会让系统无法引导 如果配置文件错误,则默认跳转到GRUB命令行界面
GRUB 磁盘引导的过程如下

- stage1: grub 读取磁盘第一个 512 字节(硬盘的0道0 面1扇区,被称为 MBR (主引导记录), 也称为bootsect )。 MBR 由一部分 bootloader 的引导代
码、分区表和魔数三部分组成。( 启动的第二步 )
- Stage1.5: 识别各种不同的文件系统格式。这使得 grub 识别到文件系统。
- stage2: 加载系统引导菜单 (/boot/grub/ menu.lst或 grub.lst) ) ,加载内核映像 (kernel image) 和 RAM磁盘 initrd (可选)。
运行主引导程序的具体过程

BIOS将硬盘主引导记录读入7C00处,并将控制权交给主引导程序:

检查0x7dfe地址处是否等于0xaa55。不是则去其他介质;如果没有启动的介质,显示“No ROME BASIC”并死机。
成功找到介质,跳转到0X7C00执行MBR的程序
将自己复制到0x0600处且继续执行
主分区表中搜索标志为激活的分区,如果发现没有激活分区或者不止一个激活分区则停止。
将激活分区的第一个扇区读入内存地址0x7c00
再次检查位于地址0x7dfe的内容是否等于0xaa55,若不等则停止并尝试软盘启动
跳转到0x7c00继续执行特定系统的启动程序
补充:MBR和引导扇区的关系



MBR存放的位置是整个硬盘的第一个扇区
Boot Sector是硬盘上每一个分区的第一个扇区
4. 加载kernel
主要有两个步骤:

根据 grub 设定的内核映像所在路径 ,系统读取内存映像 ,并进行解压缩操
作 。

系统将解压后的内核放置在内存之中, 初始化函数并初始化各种设备 , 完
成 Linux 核心环境的建立 。

以Linux系统为例,先载入/boot目录下面的kernel。

内核加载成功后,第一个运行的程序是/sbin/init。它根据配置文件(Debian系统是/etc/initab)产生init进程。这是Linux启动后的第一个进程,pid进程编号为1,其他进程都是它的后代。

然后,init线程加载系统的各个模块,比如窗口程序和网络程序,直至执行/bin/login程序,跳出登录界面,等待用户输入username和password。

至此,全部启动过程完成。

https://www.cnblogs.com/adamwong/p/10582183.html
]]>
培训问答http://www.ruanjianpeixun.net/post/20190323378.html#commenthttp://www.ruanjianpeixun.net/http://www.ruanjianpeixun.net/feed.asp?cmt=26773http://www.ruanjianpeixun.net/cmd.asp?act=tb&id=26773&key=c03176bf
深入理解JS防抖与节流_365bet线上_365bet亚洲娱乐_365bet在线songxg@qingsoft.net (网络文摘)http://www.ruanjianpeixun.net/post/20190320974.htmlWed, 20 Mar 2019 11:25:28 +0800http://www.ruanjianpeixun.net/post/20190320974.html 参考博客:

如上所见,当持续触发scroll函数,handle函数只会在1秒时间内执行一次,在滚动过程中并没有持续执行,有效减少了性能的损耗

函数节流

当持续触发事件时,保证在一定时间内只调用一次事件处理函数,意思就是说,假设一个用户一直触发这个函数,且每次触发小于既定值,函数节流会每隔这个时间调用一次
用一句话总结防抖和节流的区别:防抖是将多次执行变为最后一次执行,节流是将多次执行变为每隔一段时间执行
实现函数节流我们主要有两种方法:时间戳和定时器
例如

var throttle = function(func, delay) {     var prev = Date.now();     return function() {         var context = this;   //this指向window         var args = arguments;         var now = Date.now();         if (now - prev >= delay) {             func.apply(context, args);             prev = Date.now();         }     } } function handle() {     console.log(Math.random()); } window.addEventListener('scroll', throttle(handle, 1000));

这个节流函数利用时间戳让第一次滚动事件执行一次回调函数,此后每隔1000ms执行一次,在小于1000ms这段时间内的滚动是不执行的
再举一个定时器的例子:

var throttle = function(func, delay) {     var timer = null;     return function() {         var context = this;         var args = arguments;         if (!timer) {             timer = setTimeout(function() {                 func.apply(context, args);                 timer = null;             }, delay);         }     } } function handle() {     console.log(Math.random()); } window.addEventListener('scroll', throttle(handle, 1000));

当触发事件的时候,我们设置了一个定时器,在没到1000ms之前这个定时器为null,而到了规定时间执行这个函数并再次把定时器清除。也就是说当第一次触发事件,到达规定时间再执行这个函数,执行之后马上清除定时器,开始新的循环,那么我们看到的效果就是,滚动之后没有马上打印,而是等待1000ms打印,有一个延迟的效果,并且这段时间滚动事件不会执行函数。
单用时间戳或者定时器都有缺陷,我们更希望第一次触发马上执行函数,最后一次触发也可以执行一次事件处理函数

var throttle = function(func, delay) {      var timer = null;      var startTime = Date.now();  //设置开始时间      return function() {              var curTime = Date.now();              var remaining = delay - (curTime - startTime);  //剩余时间              var context = this;              var args = arguments;              clearTimeout(timer);               if (remaining <= 0) {      // 第一次触发立即执行                     func.apply(context, args);                     startTime = Date.now();               } else {                     timer = setTimeout(func, remaining);   //取消当前计数器并计算新的remaining               }       } } function handle() {       console.log(Math.random()); }  window.addEventListener('scroll', throttle(handle, 1000));


在节流函数内部使用开始时间startTime、当前时间curTime和剩余时间remaining,当剩余时间小于等于0意味着执行处理函数,这样保证第一次就能立即执行函数并且每隔delay时间执行一次;如果还没到时间,就会在remaining之后触发,保证最后一次触发事件也能执行函数,如果在remaining时间内又触发了滚动事件,那么会取消当前的计数器并计算出新的remaing时间。通过时间戳和定时器的方法,我们实现了第一次立即执行,最后一次也执行,规定时间间隔执行的效果,可以灵活运用在开发中
PS:防抖和节流能有效减少浏览器引擎的损耗,防止出现页面堵塞卡顿现象,应该熟练掌握。最后再次感谢原作者的总结,热心分享技术让我们的生活变得更好https://www.cnblogs.com/youma/p/10559331.html

]]>
培训问答http://www.ruanjianpeixun.net/post/20190320974.html#commenthttp://www.ruanjianpeixun.net/http://www.ruanjianpeixun.net/feed.asp?cmt=26544http://www.ruanjianpeixun.net/cmd.asp?act=tb&id=26544&key=69d8de4a
JavaScript之扑朔迷离的this_365bet线上_365bet亚洲娱乐_365bet在线songxg@qingsoft.net (网络文摘)http://www.ruanjianpeixun.net/post/20190318407.htmlMon, 18 Mar 2019 17:10:44 +0800http://www.ruanjianpeixun.net/post/20190318407.html
  一、一般对this关键字的误解:

    1、this指向函数自身

    2、this指向函数声明的词法作用域

  我们可以看以下一段代码:

复制代码
1 function test() {
2 test.a = 1;
3 this.a = 2;
4 console.log(test.a);
5 console.log(this.a);
6 console.log(test.a === this.a);
7 }
8
9 test();
10 console.dir(test);
复制代码
  在上面这段代码中,我们在全局声明一个方法test,给test中的a属性赋值1,当前方法中的this中的a属性赋值2,加入this指向函数自身,那么test.a === this,a并且都等于2.

下面我们来看下这段代码的运行结果:



  

  从上可以看出,scopes为全局作用域window,this也指向这里,虽然函数本身也是一个对象,但是this并不指向这里。

  有一点我们一定要记住,this是在运行时进行绑定的,并不是在编写时绑定的,它的上下文取决于函数调用时的各种条件。this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。

  既然this是在运行时绑定的,那我们有没有办法改变当前this的绑定,使其不指向window,而指向方法test呢?答案是肯定的,我们可以借助一些强制绑定方法,如call、apply、bind来改变this的指向,我们可以将代码改成下面这种方式:

复制代码
1 function test() {
2 test.a = 1;
3 this.a = 2;
4 console.log(test.a);
5 console.log(this.a);
6 console.log(test.a === this.a);
7 }
8
9 test.call(test);
10 console.dir(test);
复制代码
  运行结果如下:





  接下来我们看下this是否指向函数声明的词法作用域,以下有段比较有意思的代码:

复制代码
1 function parent() {
2 var a = 2;
3
4 function child() {
5 console.log(this.a)
6 }
7 child();
8
9 }
10 parent();
复制代码
  假如this指向函数的词法作用域,那么child方法中的this.a应该是存在,实际上的执行结果如下,child中的this指向仍为window:







  实际上,在JavaScript内部,作用域确实和对象类似,可见的标识符都是它的属性。但是作用域“对象”无法通过JavaScript代码访问,它存在JavaScript引擎内部。所以每当你想要把this和词法作用域的查找混合使用时,一定要提醒自己,这是无法实现的。

  二、this的绑定规则

    this的绑定规则大致分为以下几类:

      2.1 默认绑定

      2.2 隐式绑定

      2.3 显式绑定

      2.4 new绑定

    2.1 默认绑定

      上述示例中this的指向是指向window的,他们都有一个共同的特征,不带任何修饰的函数引用进行调用的,因此只能使用默认绑定,无法应用其他规则

    2.2 隐式绑定

      隐式绑定首先需要考虑的规则就是调用位置是否有上下文对象,或者说是否被某个对象拥有或包含,例如:



  这里的this就是指向对象obj。还有类似一些DOM事件的绑定,document.getElementById('xxx').addEventListener('click', function(){xxx});回调方法中的this是指向选择器选中的元素的。这种情况下可以简单的理解为this指向调用方法.前面的那个对象。



  2.3 显式绑定

   显示绑定在开发过程中运用的比较多,借助于这些显式绑定方法,可以直接改变当前方法的this指向,使得js语言非常的灵活。主要有call、apply和bind三种,基本使用如下:

复制代码
1 function sum() {
2 console.log(this.a + this.b);
3 }
4 var obj1 = {
5 a: 1,
6 b: 2
7 };
8 var test = sum.bind(obj1);
9 sum.call(obj1); //3
10 sum.apply(obj1); //3
11 test(); //3
复制代码
  注意事项:

    call && apply第一个参数接受的是this对象,call第二个参数以后可以接受字符串形式的参数,apply接受的是一个类数组/数组参数

    将null || undefined作为this的绑定对象传入call/apply/bind时,这些值在调用时会被忽略,实际应用的是默认绑定规则

  2.4 new绑定

    JavaScript语言中的new操作符和其他面向对象语言中的new操作符不大一样,因为在JavaScript中没有对象的概念。所有的函数都可以使用new来调用,new的调用又称为构造函数调用。在构造函数调用过程中,会自动执行下面的操作。

  1、创建(或者说构造)一个全新的对象

  2、这个对象会被执行[[Prototype]]连接

  3、这个新对象会绑定到函数调用的this

  4、如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象

  构造函数也是js中常用的一种设计模式,如以下代码:

复制代码
1 function Test(a, b) {
2 this.a = a;
3 this.b = b;
4 this.add = function() {
5 debugger;
6 console.log(this.a + this.b);
7 }
8 }
9 var cc = new Test(1, 2);
10 cc.add();
11 console.log(cc);
复制代码
  在new调用过程中,返回了一个新对象,并且该对象的this指向Test;



  如有问题,烦请及时指出,谢谢!

本文为原创文章,如有转载,烦请注明出处,谢谢!
分类: JavaScripthttps://www.cnblogs.com/gerry2019/p/10546752.html]]>
培训问答http://www.ruanjianpeixun.net/post/20190318407.html#commenthttp://www.ruanjianpeixun.net/http://www.ruanjianpeixun.net/feed.asp?cmt=26437http://www.ruanjianpeixun.net/cmd.asp?act=tb&id=26437&key=05e6ba3e
Web 性能优化:21 种优化 CSS 和加快网站速度的方法_365bet线上_365bet亚洲娱乐_365bet在线songxg@qingsoft.net (网络文摘)http://www.ruanjianpeixun.net/post/20190318210.htmlMon, 18 Mar 2019 15:55:36 +0800http://www.ruanjianpeixun.net/post/20190318210.html 这是 Web 性能优化的第 4 篇,上一篇在下面看点击查看:

CSS 必须通过一个相对复杂的管道,就像 HTML 和 JavaScript 一样,浏览器必须从服务器下载文件,然后进行解析并将其应用于 DOM。由于优化程度极高,这个过程通常非常快——对于不基于框架的小型 web 项目,CSS 通常只占总资源消耗的一小部分。

框架打破了这种平衡。包括一个 JavaScript GUI 堆栈,如 jQuery UI,可以观察 CSS, JS 和 HTML 大小逐渐的变大。通常,开发人员最后才会感到压力,当他们用一个强大的 8 核工作站后面,使用 T3 internet 时,没有人关心速度,这随着延迟或 cpu 受限设备的出现而改变。

优化 CSS 需要一个多维的方法。虽然手工编写的代码可以使用各种技术进行简化,但是手工检查框架代码是低效的。在这些情况下,使用自动化的简化会产生更好的结果。

下面的步骤将带我们进入 CSS 优化的世界。并不是每一个都可以直接应用到你的项目中,但是一定要记住它们。

01. 使用简写

使用缩写语句,如下面所示的 margin 声明,可以从根本上减小 CSS 文件的大小。在 google 上搜索 CSS Shorthand 可以找到许多其他的速记形式。

p {     margin-top: 1px;     margin-right: 2px;     margin-bottom: 3px;     margin-left: 4px; }  p {     margin: 1px 2px 3px 4px; }

02. 查找并删除未使用的 CSS

删除不必要的部分 CSS,j 显然会加快网页的加载速度。谷歌的 Chrome 浏览器有这种开箱即用的功能。只需转到查看>开发人员>开发人员工具,并在最近的版本中打开 Sources 选项卡,然后打开命令菜单。然后,选择 Show Coverage,在 Coverage analysis 窗口中高亮显示当前页面上未使用的代码,让您大开眼界。

打开谷歌浏览器开发都工具,在 Conlse 旁边更多选择 Coverage,就可以看到未使用的 CSS, 点击对应的项,高亮显示当前页面上未使用的代码,让你大开眼界:

03. 以更便捷的方式做到这一点

在逐行分析中导航并不一定便捷,使用谷歌浏览器的 Audits 就可以快速帮我们分析,使用方式,打开开发者工具,点击 Audits 栏位,点击 Run audits 后就开始分析结果。

04. 注意这些问题

请记住,对 CSS 的自动分析总是会导致错误。用压缩后的 CSS 文件替换 未压缩 CSS 文件之后,对整个网站进行彻底的测试——没有人知道优化器会导致什么错误。

05. 内联关键 CSS

加载外部样式表需要花费时间,这是由于延迟造成的——因此,可以把最关键的代码位放在 head 中。但是,请确保不要做得过火,记住,执行维护任务的人员也必须读取代码。

<html>     <head>         <style>             .blue {                 color: blue;             }         </style>     </head>     <body>         <div class="blue">             Hello, world!         </div>     </body> </html>

06. 允许反并行解析

@import 将 CSS 样式方便添加代码中。遗憾的是,这些好处并不是没有代价的:由于 @import 可以嵌套,因此无法并行解析它们。更并行的方法是使用一系列 标记,浏览器可以立即获取这些标记。

@import url("a.css"); @import url("b.css"); @import url("c.css");  <link rel="stylesheet" href="a.css" /> <link rel="stylesheet" href="b.css" /> <link rel="stylesheet" href="c.css" />

07. 用 CSS 替换图片

几年前,一套半透明的 png 在网站上创建半透明效果是司空见惯的。现在,CSS 过 滤器提供了一种节省资源的替代方法。例如,以下这个代码片段可以确保所讨论的图片显示为其自身的灰度版本。

img {     -webkit-filter: grayscale(100%);     /* old safari */     filter: grayscale(100%); }

08. 使用颜色快捷方式

常识告诉我们,六位数的颜色描述符是表达颜色最有效的方式。事实并非如此——在某些情况下,速记描述或颜色名称可以更短。

target {     background-color: #ffffff; } target {     background: #fff; }

09. 删除不必要的零和单位

CSS 支持多种单位和数字格式。它们是一个值得感谢的优化目标——可以删除尾随和跟随的零,如下面的代码片段所示。此外,请记住,零始终是零,添加维度不会为包含的信息附带价值。

padding: 0.2em; margin: 20em; avalue: 0px; padding: 0.2em; margin: 20em; avalue: 0;

10. 消除过多分号

这种优化需要谨慎,因为它会影响代码的更改。CSS 的规范允许省略属性组中的最后一个分号。由于这种优化方法所节省的成本很小,所以我们主要针对那些正在开发自动优化的程序员说明这一点。

p {     . . . font-size: 1.33em; }

代码部署后可能存在的 BUG 没法实时知道,事后为了解决这些 BUG,花了大量的时间进行 log 调试,这边顺便给大家推荐一个好用的 BUG 监控工具 Fundebug

11. 使用纹理图集

由于协议开销的原因,加载多个小图片的效率很低。CSS 精灵将一系列小图片组合成一个大的 PNG 文件,然后通过 CSS 规则将其分解。TexturePacker 等程序大大简化了创建过程。

.download {     width: 80px;     height: 31px;     background-position: -160px -160px; }  .download:hover {     width: 80px;     height: 32px;     background-position: -80px -160px; }

12. 省略 px

提高性能的一个简单方法是使用 CSS 标准的一个特性。为 0 的数值默认单位是 px—— 删除 px 可以为每个数字节省两个字节。

h2 {     padding: 0px;     margin: 0px; }  h2 {     padding: 0;     margin: 0; }

13. 避免需要性能要求的属性

分析表明,一些标签比其他标签更昂贵。以下这些解析会影响性能—如果在没有必要的情况,尽量不要使用它们。

border-radius box-shadow transform filter :nth-child position: fixed;

14. 删除空格

空格——考虑制表符、回车符和空格——使代码更容易阅读,但从解析器的角度看,它没有什么用处。在发布前删除它们,更好的方法是将此任务委托给 shell 脚本或类似的工具。

15. 删除注释

注释对编译器也没有任何作用。创建一个自定义解析器,以便在发布之前删除它们。这不仅节省了带宽,而且还确保攻击者和克隆者更难理解手头代码背后的思想。

16. 使用自动压缩

Yahoo  的用户体验团队创建了一个处理许多压缩任务的应用程序。它以  JAR  文件的形式发布,在这里可用,并且可以使用所选的 JVM 运行。

java -jar yuicompressor-x.y.z.jar Usage: java -jar yuicompressor-x.y.z.jar  [options] [input file] Global Options     -h, --help                Displays this  information     --type <js|css>           Specifies the  type of the input file

17. 在 NPM 运行它

如果你希望将产品集成到 Node.JS 中,请访问 npmjs.com/package/yuicompressor。维护不良的存储库包含一组包装器文件和 JavaScript API。

var compressor = require('yuicompressor');  compressor.compress('/path/to/ file or String of JS', {     //Compressor Options:     charset: 'utf8',     type: 'js',

18. 保持 Sass 的检查

虽然 CSS 选择器的性能不像几年前那么重要(请参阅参考资料),但是像 Sass 这样的框架有时会产生非常复杂的代,不时查看输出文件,并考虑优化结果的方法。

19. 设置缓存

有句老话说,最快的文件永远不会通过网络发送。让浏览器缓存请求有效地实现这一点。遗憾的是,缓存头的设置必须在服务器上进行。充分上面讲的的两个 Chrome 工具,它们提供了一种快速分析更改结果的方法。

20. 打破缓存

设计人员通常不喜欢缓存,因为他们担心浏览器会缓存上次的样式表。解决这个问题的一个简单方法是包含带有文件名的标记。遗憾的是,由于一些代理拒绝缓存具有“动态”路径的文件,此步骤所附带的代码中概述的方案并不适用于所有地方。

<link rel="stylesheet" href="style.css?v=1.2.3" />

21. 不要忘记基础知识

优化 CSS 只是游戏的一部分。如果你的服务器不使用 HTTP/2 和 gzip 压缩,那么在数据传输期间会损失很多时间。幸运的是,解决这两个问题通常很简单。我们的示例显示了对常用 Apache 服务器的一些调整。如果您发现自己在一个不同的系统上,只需参考服务器文档即可。

pico /etc/httpd/conf/httpd.conf AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/css

关于Fundebug

Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家免费试用!https://www.cnblogs.com/fundebug/p/21-method-to-optimize-c

]]>
培训问答http://www.ruanjianpeixun.net/post/20190318210.html#commenthttp://www.ruanjianpeixun.net/http://www.ruanjianpeixun.net/feed.asp?cmt=26398http://www.ruanjianpeixun.net/cmd.asp?act=tb&id=26398&key=ae1b2155