首页 文章 精选 留言 我的

精选列表

搜索[全栈管理],共10000篇文章
优秀的个人博客,低调大师

(全)(20)

call(),apply(),bind() 函数大家可能都有所了解,但是在平时搬砖过程中很可能或者基本没用过,学过但都淡忘了。 但是在大量第三方的框架(库),甚至js自己都在 源码中大量使用 call,apply 函数。所以今天和大家仔细讨论下它们在 开发中的应用场景 。 1 . 它们是啥意思1.1 作用他们的作用都是改变函数内部的this。这三个函数都是函数对象的方法,也就是说只有函数才可以直接调用这些方法。1.2 三者区别参数: 三个函数的第一个参数都是需要绑定的 this。call: 可以有n个参数,从第二个参数开始的所有参数都是原函数的参数。 `apply`:只有两个参数,并且第二个参数必须为数组,数组中的所有元素一一对应原函数的参数。 `bind`: 只有一个参数,即要绑定的this。 call 语法: foo.call(this, arg1,arg2, ... ,argn ); apply 语法: foo.apply(this, [ arg1,arg2, ... ,argn ] ); bind 语法: foo.bind(this); 调用:call,apply: 调用后立即执行原函数。 `bind`: 调用后返回已经绑定好this的函数。 小例子一枚: function foo(a,b){ console.log(a+b); } foo.call(null,'海洋','饼干'); // 海洋饼干 这里this指向不重要就写null了 foo.apply(null, ['海洋','饼干'] ); // 海洋饼干 var fun = foo.bind(null); fun('海洋','饼干'); // 海洋饼干 2 .它们能干啥事这是我们今天讨论的主题,这三个函数如何应用?什么情况下使用?能改变this指向又能咋滴? 2 .1 处理伪数组 (最常用)先考虑一个问题,如果你使用var arr = document.getElementsByTagName('li')获取了5个li元素,你现在需要获取其中的第2,3,4三个元素,你会怎么做? 这样arr.slice(1,4);? 啊哦,TypeError -- arr.slice is not a function(slice不是函数),数组操作在日常搬砖中非常常见,我见过最傻的解决这个问题的方式是使用循环,将需要的元素一个个添加到一个新数组里0.0,下面我介绍的方法完全可以在实战中使用,可以给你的代码加分哦,非常方便简洁(中高级前端程序员中,算是基本操作了)。 先要介绍一个概念( 伪数组 ),这也是为什么我们刚刚slice切割数组时出错的原因: (对新手来说算是干货了,知道的可以跳过) 什么是伪数组?( 字面的意思已经呼之欲出了 ) 有length属性能按索引存储数据能像遍历数组一样来遍历不能使用数组的push()、slice()等方法简单来说就是可以像数组一样操作的对象,但是没有数组的方法。 js中存在大量伪数组,如 : 1. function的arguments对象。 2. getElementsByName(),getElementsByTagName(),childNodes/children 等方法的返回值。 3. 还有比较常见的jquery,使用它获取的元素也是伪数组。 回到原来的问题,如何截取伪数组中的元素:伪数组没有这些方法,我们'借用'Array的slice不就行了 [].slice.call(arr,1,4); // 推荐写法 不想借用你可以直接给伪数组添加一个slice函数,如 arr.slice = [].slice; arr.slice(1,4); 当然,'借用' 更方便,直接添加会导致伪数组对象'污染'。 如果可以随意改变原对象,可以 直接将其转成真正的数组对象。 [].slice.call(arr); 2 .2 继承继承方式多种多样,我们现在讨论的这种是其中很重要的一种实现方式,用call实现 js 构造函数继承 。 单继承 function person(name){ this.name = name } function man(name){ this.age = '男'; person.call(this,name); // 继承 man } var me = new man('海洋饼干'); console.log(me.name,me.age); // '海洋饼干' '男' 多继承 function person(name){ this.name = name } function man(name){ this.age = '男'; } function manProgrammer(name){ this.girlfriend = null; person.call(this,name); // 继承 person man.call(this,name); // 继承 man } var me = new manProgrammer('海洋饼干'); console.log(me.name,me.age,me.girlfriend); // '海洋饼干' '男' null 2 .3 this 硬绑定 --- bind将一个对象强制且永久性绑定到函数的this上,使用call,apply或者其他的绑定方式都无法改变(除了new绑定,当然,可以手动撸一个new都无法改变的硬绑定) 直接看例子: var fun ; var obj = { a : 1, foo : function(){ var _this = this; //平时有没有过这种写法? 为了防止this指向问题 //将this赋值给一个变量,间接维持了this的安全性 fun = function(){ console.log(_this.a); } } } obj.foo(); fun(); // 1 var obj1 = { a : 2} obj.foo.call(obj1); // 直接修改_this所绑定的值,boom了 fun(); // 2 但是这种方法感觉上是在逃避问题,直接不使用this了 ? 这真的不是什么好的解决问题的态度。下面使用我们的bind来优化一下: var fun ; var obj = { a : 1, foo : function(){ // 不使用 _this, 避免无谓的变量声明 fun = function(){ console.log(this.a); }.bind(this); // 代码很简洁,很漂亮(b格) } } var obj1 = { a : 2} obj.foo(); fun(); // 1 fun.call(obj1); // 1 call ,apply等绑定 无法修改 // 这里和上面call的位置不同是因为this所处于不同的位置 这样替代 _this 很规(zhuang)范(b)呢 2 .4 取数组最大最小值Math.max和min方法,接收多个参数,比较出极值,这里用到apply的一个默认功能:展开数组,传入一个数组参数就可以默认将这个数组转成一个个参数的形式赋给原函数 var num = [6,9,-3,-5]; console.log(Math.max.apply(Math,num)); // 9 等价 console.log(Math.max(6,9,-3,-5)); console.log(Math.min.apply(Math,num)); // -5 等价 console.log(Math.min(6,9,-3,-5)); 2 .5 合并数组合并数组常见有三种方式,1.循环 2.Array的concat() 3. 使用apply()合并 这里是使用最简便的apply var a = [1,2,3]; var b = [4,5,6]; [].push.apply(a,b); // 借用数组的push方法 等价 a.push(4,5,6); console.log(a); // [1, 2, 3, 4, 5, 6]

优秀的个人博客,低调大师

Net和Java基于zipkin的全链路追踪

在各大厂分布式链路跟踪系统架构对比中已经介绍了几大框架的对比,如果想用免费的可以用zipkin和pinpoint还有一个忘了介绍:SkyWalking,具体介绍可参考:https://github.com/apache/incubator-skywalking/blob/master/README_ZH.md 由于追踪的要求是Net平台和Java平台都要支持,对于java平台各组件都是天生的支持的,但对于net的支持找了些开源组件,发现Pinpoint和SkyWalking给出的Demo都是基于NetCore(SkyWalking可以在github上搜skywalking-netcore,Pinpoint没有好的推荐),版本要求比较高,但不可能更改现有平台的FW框架,Zipkin有开源项目 Medidata.zipkinTracerModule 、zipkin.net、zipkin-csharp,网上依次推荐是从前到后,经过测试发现Medidata.zipkinTracerModule、zipkin.net也是用于Net Core的,在NuGet上安装报错。最后测试zipkin-csharp(https://github.com/openzipkin-attic/zipkin-csharp)可以成功,在NuGet中搜索Zipkin.Core,现在版本也只有一个,如下: 然后查看给出的demo中代码:zipkin-csharp/examples/ZipkinExample/Program.cs using System; using System.Net; using System.Threading; using Zipkin; using Zipkin.Tracer.Kafka; namespace ZipkinExample { class Program { static void Main(string[] args) { var random = new Random(); // make sure Zipkin with Scribe client is working //var collector = new HttpCollector(new Uri("http://localhost:9411/")); var collector = new KafkaCollector(KafkaSettings.Default); var traceId = new TraceHeader(traceId: (ulong)random.Next(), spanId: (ulong)random.Next()); var span = new Span(traceId, new IPEndPoint(IPAddress.Loopback, 9000), "test-service"); span.Record(Annotations.ClientSend(DateTime.UtcNow)); Thread.Sleep(100); span.Record(Annotations.ServerReceive(DateTime.UtcNow)); Thread.Sleep(100); span.Record(Annotations.ServerSend(DateTime.UtcNow)); Thread.Sleep(100); span.Record(Annotations.ClientReceive(DateTime.UtcNow)); collector.CollectAsync(span).Wait(); } } } 可以看出这里的traceId和spanId都是随机生成的,在这里推荐自己生成ID,注意是ulong型,这里毫秒数只格式化两位(数据库的位数20位,会超),也可以用更保险的其它方法。 /// <summary> /// 获得随机数 /// </summary> /// <returns></returns> private static ulong getRandom() { var random = new Random(); return ulong.Parse(DateTime.Now.ToString("yyyyMMddHHmmssff") + random.Next(100, 999)); } } collector这里使用Http来接收,注释kafka的,放开http的。去掉collector.CollectAsync(span).Wait(); 中的Wait。 Zipkin的几个基本概念Span:基本工作单元,一次链路调用(可以是RPC,DB等没有特定的限制)创建一个span,通过一个64位ID标识它, span通过还有其他的数据,例如描述信息,时间戳,key-value对的(Annotation)tag信息,parent-id等,其中parent-id 可以表示span调用链路来源,通俗的理解span就是一次请求信息Trace:类似于树结构的Span集合,表示一条调用链路,存在唯一标识,即TraceIdAnnotation:注解,用来记录请求特定事件相关信息(例如时间),通常包含四个注解信息cs - Client Start,表示客户端发起请求sr - Server Receive,表示服务端收到请求ss - Server Send,表示服务端完成处理,并将结果发送给客户端cr - Client Received,表示客户端获取到服务端返回信息BinaryAnnotation:提供一些额外信息,一般以key-value对出现 启动服务端测试 下载 https://github.com/openzipkin/zipkin/releases 最近的稳定版 release-2.7.1的jar包,这里采用mysql的型式保存记录,因此需要创建数据库zipkin,创建表: SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `zipkin_annotations` -- ---------------------------- DROP TABLE IF EXISTS `zipkin_annotations`; CREATE TABLE `zipkin_annotations` ( `trace_id_high` bigint(20) NOT NULL DEFAULT '0' COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit', `trace_id` bigint(20) NOT NULL COMMENT 'coincides with zipkin_spans.trace_id', `span_id` bigint(20) NOT NULL COMMENT 'coincides with zipkin_spans.id', `a_key` varchar(255) NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1', `a_value` blob COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB', `a_type` int(11) NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation', `a_timestamp` bigint(20) DEFAULT NULL COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp', `endpoint_ipv4` int(11) DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null', `endpoint_ipv6` binary(16) DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address', `endpoint_port` smallint(6) DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null', `endpoint_service_name` varchar(255) DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null', UNIQUE KEY `trace_id_high` (`trace_id_high`,`trace_id`,`span_id`,`a_key`,`a_timestamp`) COMMENT 'Ignore insert on duplicate', UNIQUE KEY `trace_id_high_4` (`trace_id_high`,`trace_id`,`span_id`,`a_key`,`a_timestamp`) COMMENT 'Ignore insert on duplicate', KEY `trace_id_high_2` (`trace_id_high`,`trace_id`,`span_id`) COMMENT 'for joining with zipkin_spans', KEY `trace_id_high_3` (`trace_id_high`,`trace_id`) COMMENT 'for getTraces/ByIds', KEY `endpoint_service_name` (`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames', KEY `a_type` (`a_type`) COMMENT 'for getTraces', KEY `a_key` (`a_key`) COMMENT 'for getTraces', KEY `trace_id` (`trace_id`,`span_id`,`a_key`) COMMENT 'for dependencies job', KEY `trace_id_high_5` (`trace_id_high`,`trace_id`,`span_id`) COMMENT 'for joining with zipkin_spans', KEY `trace_id_high_6` (`trace_id_high`,`trace_id`) COMMENT 'for getTraces/ByIds', KEY `endpoint_service_name_2` (`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames', KEY `a_type_2` (`a_type`) COMMENT 'for getTraces', KEY `a_key_2` (`a_key`) COMMENT 'for getTraces', KEY `trace_id_2` (`trace_id`,`span_id`,`a_key`) COMMENT 'for dependencies job' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED; -- ---------------------------- -- Records of zipkin_annotations -- ---------------------------- -- ---------------------------- -- Table structure for `zipkin_dependencies` -- ---------------------------- DROP TABLE IF EXISTS `zipkin_dependencies`; CREATE TABLE `zipkin_dependencies` ( `day` date NOT NULL, `parent` varchar(255) NOT NULL, `child` varchar(255) NOT NULL, `call_count` bigint(20) DEFAULT NULL, `error_count` bigint(20) DEFAULT NULL, UNIQUE KEY `day` (`day`,`parent`,`child`), UNIQUE KEY `day_2` (`day`,`parent`,`child`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED; -- ---------------------------- -- Records of zipkin_dependencies -- ---------------------------- -- ---------------------------- -- Table structure for `zipkin_spans` -- ---------------------------- DROP TABLE IF EXISTS `zipkin_spans`; CREATE TABLE `zipkin_spans` ( `trace_id_high` bigint(20) NOT NULL DEFAULT '0' COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit', `trace_id` bigint(20) NOT NULL, `id` bigint(20) NOT NULL, `name` varchar(255) NOT NULL, `parent_id` bigint(20) DEFAULT NULL, `debug` bit(1) DEFAULT NULL, `start_ts` bigint(20) DEFAULT NULL COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL', `duration` bigint(20) DEFAULT NULL COMMENT 'Span.duration(): micros used for minDuration and maxDuration query', UNIQUE KEY `trace_id_high` (`trace_id_high`,`trace_id`,`id`) COMMENT 'ignore insert on duplicate', UNIQUE KEY `trace_id_high_4` (`trace_id_high`,`trace_id`,`id`) COMMENT 'ignore insert on duplicate', KEY `trace_id_high_2` (`trace_id_high`,`trace_id`,`id`) COMMENT 'for joining with zipkin_annotations', KEY `trace_id_high_3` (`trace_id_high`,`trace_id`) COMMENT 'for getTracesByIds', KEY `name` (`name`) COMMENT 'for getTraces and getSpanNames', KEY `start_ts` (`start_ts`) COMMENT 'for getTraces ordering and range', KEY `trace_id_high_5` (`trace_id_high`,`trace_id`,`id`) COMMENT 'for joining with zipkin_annotations', KEY `trace_id_high_6` (`trace_id_high`,`trace_id`) COMMENT 'for getTracesByIds', KEY `name_2` (`name`) COMMENT 'for getTraces and getSpanNames', KEY `start_ts_2` (`start_ts`) COMMENT 'for getTraces ordering and range' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED; -- ---------------------------- -- Records of zipkin_spans -- ---------------------------- 启动 进入程序的当前目录启动,注意参数内容,如果想要保存到elasticsearch,需要按官方文档更改。 java -jar zipkin-server-2.7.1.jar --STORAGE_TYPE=mysql --MYSQL_DB=zipkin --MYSQL_USER=root --MYSQL_PASS=123456 --MYSQL_HOST=localhost --MYSQL_TCP_PORT=3306 启动后看到如下内容表明成功。 启动成功后浏览器访问http://localhost:9411/ 至此服务端和展示页面已经启动,不过功能还是很简单的,具体的使用可另行查询资料。 这里用来测试的服务采用网友提供的 源码:mircoservice分布式跟踪系统(zipkin+springboot)https://github.com/dreamerkr/mircoservice,文章可参考:微服务之分布式跟踪系统(springboot+zipkin)https://blog.csdn.net/qq_21387171/article/details/53787019 用默认配置分别运行4个客户端服务后运行效果: (1)分别启动每个服务,然后访问服务1,浏览器访问(http://localhost:8081/service1/test) (2)输入zipkin地址,每次trace的列表 点击其中的trace,可以看trace的树形结构,包括每个服务所消耗的时间: 点击每个span可以获取延迟信息: 同时可以查看服务之间的依赖关系: 测试Net平台程序 将demo代码改为: static void Main(string[] args) { var random = new Random(); // make sure Zipkin with Scribe client is working var collector = new HttpCollector(new Uri("http://localhost:9411/")); //var collector = new KafkaCollector(KafkaSettings.Default); var traceId = new TraceHeader(traceId: (ulong)random.Next(), spanId: (ulong)random.Next()); var span = new Span(traceId, new IPEndPoint(IPAddress.Loopback, 9000), "zipkinweb"); span.Record(Annotations.ClientSend(DateTime.UtcNow)); Thread.Sleep(100); span.Record(Annotations.ServerReceive(DateTime.UtcNow)); Thread.Sleep(100); span.Record(Annotations.ServerSend(DateTime.UtcNow)); Thread.Sleep(100); span.Record(Annotations.ClientReceive(DateTime.UtcNow)); collector.CollectAsync(span); } 然后运行一次再查看,会多出一条信息 点进去会看到请求的详细信息和备注信息: 右上角查看json 验证了NET平台下是可以成功调用的,而且可以看到zipkin服务前端展示是通过api请求的,前后台分开的,因此我们可以以此来做二次开发,我们知道了数据结构或者通过自己请求数据库内容做更复杂的业务前端。 这里强调一点的是net最好用framework4.5以上的版本,由net的demo来看其实封装性不高,所以灵活性能很高,需要自己进一步封装才能达到代码的侵入性更少,性能更高。后面考虑到性能和数据量可改用kafka接收和ES保存数据。

优秀的个人博客,低调大师

超全!基于Java的机器学习项目、环境、库...

你是一名希望开始或者正在学习机器学习的Java程序员吗? 利用机器学习编写程序是最佳的学习方式。你可以从头开始编写算法,但是利用现有的开源库,你可以取得更大的进步。 本文介绍了主要的平台和开放源码的机器学习库。你可以使用这些机器学习库。 环境 本节描述了用于机器学习的Java环境或工作域。它们提供了用于执行机器学习任务的图形用户界面,还提供了用于开发自己应用程序的Java API。 WEKA 怀卡托环境知识分析(Weka)( https:// www.cs.waikato.ac.nz/ml/weka/)是一个由新西兰怀卡托大学开发的机器学习平台。提供Java的图形用户接口,命令行接口和Java API接口。它可能是最流行的Java机器学习库,也是开始或练习机器学习的好地方。 KNIME 康斯坦茨信息挖掘(KNIME)(https://www.kn

优秀的个人博客,低调大师

上饶“智慧城市”生活:家居出行购物医疗全覆盖

出门前,利用手机“掌上公交”查查,公交“行踪”一目了然;通过挂号网提前预约就诊时间,避免在医院里无谓“奔波”及“等候”……这就是近年来作为城市发展趋势的“智慧城市”,带给饶城市民新的城市生活剪影。 预约自助挂号,市民看病不再难 近日,市民祝先生陪同母亲到市人民医院看病,通过自助机轻松地挂好了号,并在候诊室等待自动叫号。近年来,患者前往医院就诊,不需要排队挂号,而且可以通过“网上预约”,减少大量的精力和时间浪费,给患者带来就诊便利,避免了患者在医院里的无谓“奔波”及“等候”。“智慧医疗”打造健康档案区域医疗信息平台,利用最先进的物联网技术,实现患者与医务人员、医疗机构、医疗设备之间的互动,逐步达到信息化。不仅当地医院可以预约专家,市民们欣喜地发现,通过好大夫、挂号网等“远程医疗”网络,让患者无论身处何地,都能享受知名医院的优质医疗资源,一根网线拉近了大城市三甲医院和偏远山村的距离,好比搭建了一座跨地区医疗救援的超级“生命桥”。 外卖跑火,足不出户品美食 懒得跑出去吃饭,咋办呢?百度外卖、饿了么等网上订餐成为饶城上班族、宅男宅女的不二选择,这种时尚的就餐方式因为方便快捷、服务周到、味道不错、价钱实惠而备受热捧。只要居民身处饶城任何有网络覆盖的地方,均可以实时了解从田间到餐桌的食品,让那些“宅男宅女”足不出户就能品尝饶城众多美食。市民苏女士女儿生日,通过百度外卖订好比萨直接送到学校,而每到下午,苏女士也会和同事通过网上预约一些水果和糕点,省去了奔波之劳累。 实时掌握公交“行踪”,“滴滴”快捷出行 在市中心广场等站台,市民通过新式的电子站牌,不仅可以了解新闻资讯、体育赛事,政府部门发布的权威信息、天气资讯、公益广告、地方特色宣传,还可实时了解距离该站5站内的车次和该车次距离本站的站数。市民只需看一下,便能清楚知道公交车的“行踪”。“智慧交通”的建设实现人、车、路、环境的和谐,引导并吸引市民主动选择最优的交通出行方式。 “以前,加班晚了就没有车子回家,现在有了滴滴打车,再晚都不怕了。”在汪家园上班的李女士高兴地说,自从一款已在全国各大一线城市逐渐普及的“打车神器——滴滴出行”在我市悄然兴起,深受年轻一族的钟爱。李女士告诉记者,以前回上饶中学,出租车总是漫天要价,滴滴打车计程合理收费,省却了不少口舌之争。 智慧社区打造全新智能化服务模式 “只需要拨打居家养老服务电话12349,就有人上门为我们老年人提供急需的服务。在智慧社区,我们真是少跑了不少腿。”水南街道金山社区居民卢大爷高兴地说。目前,信州区积极打造“智慧社区”,在全国率先试点电子政务信息惠民工程进社区工作,家庭成员、年龄、职业……这些居民信息从“账本”挪到了“智能平台”,不仅解决了原先系统人口数据更新不及时、不能自主维护的问题,还实现了社区台账即查即看即印,具有信息发布、短信群发、协同工作等功能,建设全新的社区智能化服务模式,让居民体验到了在“互联网+”新时代便利的生活方式。 ====================================分割线================================ 本文转自d1net(转载)

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册