东哥IT笔记 Blog

0

使用node-csv来读写CSV文件

前言 我们经常遇到一个很常见的问题,就是从一个csv文件中读取数据。我们可以使用fs模块来得到文件的内容。在这之后,使用特定的库来做解析和进一步分析csv则会简单和方便得多。 现在有很多模块都提供了这个功能,比如neat-csv或者csv-parser。而本文要介绍的是node-csv这一个模块,让我们来看看它是如何使用的。 安装node-csv 这个模块是由csv-generate, csv-parse,csv-transform以及csv-stringify这几个包组成的。你可以按需安装,也可以把他们都一次性安装了。 首先我们来用默认设置来创建一个Node的项目: 下面我们来安装整个node-csv: 下面是csv文件的内容,你可以拷贝到一个csv文件中,我们用这个文件来做测试: 使用csv-parse来读取CSV文件 我们可以使用node-csv中的csv-parse来读取csv文件。Csv-parse包提供了很多种方法来解析csv文件–你可以使用callbask,也可以使用stream+callback或者sync的API,当然也支持async的api。本文就使用stream+callback api以及同步的sync api。 Stream+Callback API 我们先来创建一个文件index.js,并且创建parser: 这里,我们使用了fs和csv-parse模块,然后创建parser,这里第二个参数就是callback函数,我们可以在这个callback中访问records,或者就像例子中一样先把record打印出来。 这里我们使用的参数不是强制的,你可以使用下面这些参数: Delimiter: 默认是逗号,假如你的文件中使用的是别的分隔符,比如分号;,或者管道|你可以设置相关的选项。 cast:这个选项的默认值是false,这个是用来表示是否把字符串转换成本机的数据类型。比如,一个列的日期域可以转换成Date。 columns:这个选项是用来表示你是否使用object格式来产生record。默认值是false,也就是records是通过parser用arrays来产生的。假如设为true,parser就是从第一行的column来推测。 最后就是用fs打开文件,然后把它传入到parser中。下面我们来运行试试看: 结果如下所示: 有了这个结果,你就可以对这些内容来进行各种处理了。 使用同步API 下面我们来使用同步API来实现: 这里,我们和之前类似,也还是使用fs模块和csv-parse.这里我们创建了一个async的函数,在它里面我们使用readFile函数来读取内容个,然后使用await等待。 然后使用parser,第一个参数是文件的内容,第二个是一个object参数(这里我们把column设为true)。然后把它赋值给record,然后我们可以使用这个record。 使用csv Stringify来写csv文件 下面我们来看看如何把数据写到csv格式的文件中。这里,我们使用csv-stringify包。我们假设你已经得到一些JSON格式的数据,然后想把它写入到csv文件中。 Csv-stringify包也有一些API的选项,Callback API有很多简单的方式来把数据变成string。让我们来看看如何把上面的JSON数据变成string,然后写到文件中:...

Javascript中的逻辑赋值操作 0

Javascript中的逻辑赋值操作

逻辑赋值操作就是把逻辑操作和赋值操作合在一起: 所以当你些一个UpdateId的函数的时候,可以这样写: 你现在也可以使用??来实现了: 这个feature目前在stage-4中支持,我想你应该可以使用了。

0

Facebook是如何加速SQL查询

在PB级别的数据上进行查询是一件事,如何在Facebook这种级别的产品上使用则是另外一件事。今年早期时候,他们把Alluxio分布式文件系统集成到了他们的数据架构上,实现了存储和计算的分离,以此用来加速查询。 Facebook很早就使用Apache hadoop,并且到现在还可以在Facebook的架构中看到他。它们已经把数据存储从Hadoop clusters中移开了,但是仍然使用HDFS在Warm Storage中访问数据,这是一个由Facebook开发的定制的分布式文件系统,用来在分离Hadoop之后进行数据存储的。 Facebook内部使用了很多Presto来进行SQL查询,A/B testing以及服务一些关键的仪表,比如每日的活跃用户(DAU)或者每月的平均用户等等。作为一个没有存储模块的计算单元,Presto对计算和存储分离的架构非常友好。 为了让SQL查询的延时在一个可以工作的范围(比如在一秒左右),几年之前,Facebook实现了一个数据Caching的策略。Dubbed Raptor,这个系统要求用户在Presto cluster的SSD上创建ETL pipeline来cache数据。 Raptor加速了查询的速度,因为很多查询都再也不用通过网络了,但是同时也带来了很多别的问题。 开始的时候,把计算和存储放在一起,就限制了公司去把他们分开来扩展,这显然是不好的。它也导致了数据的碎片化,从而降低了用户的体验,这主要是因为查询有时会hit warm storage,有时会hit 本地SSD的cache。而且它也是的数据的安全和隐私保护更加复杂,因为你不仅仅要保护Warm Storage中的数据,还需要保护本地SSD的数据。 去年秋天,Facebook开发实现Raptor的替代方案。它是基于Alluxio,这个新的系统的查询性能和Raptor类似,但是不需要在SSD中cache数据。 Alluxio是一个虚拟的分布式文件系统,它连接了多个计算引擎和后端存储系统。它是由Haoyuan在UC伯克利 AMPLab开发的。Facebook基于Alluxio开发了一个新的版本,让它可以在Java上运行。 Facebook使用ORC文件格式来存储数据,并且通过HDFC接口来让Presto访问。Alluxio的实现可以在SSD上工作,并且把数据存储在本地,从而加速访问,但是本地的cache却不再需要了,而且Alluxio也可以在没有SSD的情况下使用Warm storage来加速访问。 当Alluxio在上百个Facebook数据中心的节点上安装之后,用户就可以体验到和之前Raptor类似的查询性能。它们可以使用很多Join的查询来查询PB级别的数据,没有Alluxio或者Raptor之前,这些查询可能需要超过10s才能返回。在一些能够hit oft-queried表格的查询,Alluxio可以相比Prestor负载提高了30%到50%,这显然是一个不错的提升。 根据James七月份的报告,相比于Raptor,Alluxio cache减少了57%从远端数据存储单元读取的操作。Alluxio cache的hit rate查过了90%。 Jain说,现在还有一个问题,就是当有很大的数据请求过来的时候,就很容易让cache的hit rate降低,它们现在正在想办法解决这个问题。 这个方案的另外一个优点是金钱和安全,因为Presto计算单元和数据存储是分开的,这样可以分开进行提升,而不会有浪费。在安全性方面,也不需要再担心SSD上数据的安全,而只需要关注warm storage上数据的安全即可。 当然Raptor也没有完全被取代,不过预计在未来六个月会被完全取代。

0

MySQL数据库服务介绍

MySQL团队现在把它引入到了Oracle Cloud架构上(OCI),这个服务是100%由MySQL服务开发,管理和支持的。 MySQL数据库服务和你所了解的MySQL几乎是一样的,只是说现在在云平台上支持了而已。它会自动执行很多耗时的任务,比如MySQL instance provisioning,补丁和升级,以及备份和恢复。用户可以很方便地扩展MySQL,检测云资源以及实现安全策略。用户的应用可以通过标准的MySQL protocol来访问MySQL数据库。典型的管理任务可以通过OCI web控制台,REST API, CLI或者DevOps工具进行自动化,集成操作。 MySQL数据库服务在多个OCI region中可以使用,这样可以很方便符合你所在地的政府和区域要求。当然更多的区域支持也正在实现中。 由MySQL开发团队创建 一个最大的优势就是MySQL数据库服务是由MySQL开发团队开发管理和支持的。我们来看看这为什么很重要: MySQL数据库服务是由MySQL社区和商业版同一个团队开发和维护的。 这个服务是一直最新的,包含最新的安全更新。 可以得到所有的最新的功能,包括使用最新的X-Protocol和X DevAPi实现的NoSQL Document Store。 MySQL数据库服务由MySQL专家配置的默认config。当然也支持用户来自定义化。 因为MySQL服务是在云上,你可以有最大的灵活性来使用你的部署策略。 用户可以使用MySQL本地replication和MySQL Shell来快速和方便地把workloads移到云上。 不像其他的云数据库服务,它们的服务支持都是有限的。MySQL数据库的服务支持是不需要额外花费的。 MySQL数据库服务是基于Oracle Cloud架构进行创建的,继承了所有Oracle cloud的特性,所以可以放心运行各种关键和核心的任务。 价格:只有Amazon RDS的三分之一不到 MySQL数据库服务大概是目前主流云提供商最便宜的选择了 — Amazon RDS, Microsoft...

MongoDB 4.4 最新特性介绍 0

MongoDB 4.4 最新特性介绍

MongoDB 4.4就要发布了,本文就来介绍一些这个版本的一些最新的功能。 MongoDB 4.4中改进的功能 对冲读取 MongoDB可以并行处理读请求,然后从最有效的节点来获取结果,从而可以减少应用的延时。 可定义的共享秘钥 在scale过程中修改数据分布的时候会在共享秘钥中加入后缀。 镜像读取 这个功能可以对副本的cache预先warm,从而可以减少计划的维护或者outage的时候主选举消耗。 聚合增强 聚合增强有了很多方面的改进,包括定义和汇总聚合表达式,从不同的mongo collection中组合数据到一个结果中,字符串处理以及数组处理的新操作。下面是一些加强: $out $out现在可以把输出collection的结果到不同的数据库,而早期的版本只能输出到同一个数据库中。 $indexStats $indexStats在新的版本中有了一些新的域,包括下面这些: Building 这是一个Boolean的flag,用来表示正在建立的索引 Spec 每一个索引的规格文档 Shard 分片的名字 $merge $merge可以在要升级的同一个collection中输出。另外,可以在一个collection中数据并显示在pipeline上,比如$lookup。 $planCacheStates的改变 $planCacheStates现在可以同时在mongod和mongos instance上运行。另外,$planCacheStats在运行的时候有一个新的域我们称之为host域。PlanCache.list()是$planCacheStats聚合阶段的包装。 $collStats改变 $collStats在扩充文档中已经可以接收查询统计信息。另外Collection扫描有下面这些域: 域名字 描述 nonTailble 一个64位整数,用来表示多个查询上的一个collection...

为什么HTTPS很重要 0

为什么HTTPS很重要

我们经常说,你应当让你所有的网页使用HTTPS,哪怕你的网页上并没有敏感的信息。HTTPS除了可以为你的网页和用户数据提供安全保护以及数据完整性之外,很多浏览器的新的特性都要求HTTPS,尤其在渐进性的web app中。 HTTPS保护了你的网页的完整性 HTTPS可以阻止入侵者修改网页和用户浏览器之间交流。这些入侵者包括故意的恶意入侵者,以及一些虽然合法但是很有侵入性的公司,比如ISP或者一些试图插入广告的酒店。 入侵者利用不受保护的通信来欺骗你的用户以骗取一些敏感信息或者安装一些木马,或者把他们自己的广告插入到你的网页中。比如,有些第三方的公司或把广告插入到你的网页从而破坏用户的体验。 入侵者会利用你网页和用户交流中所有不受保护的资源,比如图片,cookies,scripts,HTML等等。入侵行为可能会发生在网络中的任何点,包括用户的机器,WIFI的热点或者一个入侵的ISP。 HTTPS保护了你的用户的隐私和安全 HTTPS可以阻止侵入者被动地监听你和用户的交流。 一个常见的误解就是认为只有那些有敏感信息交流的网站才需要使能HTTPS,其实不然。因为每一个没有加密的请求都可能包含你用户的一些行为特征或者标志。也许单独的一次访问并不能让侵入者得到什么有用的信息,但是当他们把大量的这些数据整合起来的时候,就可能得到一些用户的行为状况。比如,一个员工可能阅读了未受保护的医学文章,从而让雇主从中知道这个员工可能由相关的医学症状。 HTTPS是WEB的未来 一些很好的平台特性都只支持HTTPS,比如使用getUserMedia()来拍照或者录视频,使用service worker来使能离线的的app体验,或者创建渐进性的app等等,这些都需要显式的权限。而HTTPS则是这些流程中获取权限的关键过程。

0

按钮和输入的垂直文本对齐

你曾经苦恼于文本的垂直对齐吗?我想很多的前端开发者都会遇到这样的烦恼吧,那么本文就来给你详细介绍一下如何利用line-height, padding以及flexbox实现相应的对齐功能。 基本的按钮和输入风格 一个按钮和输入的高度以及垂直对齐是由他的边框,padding,字体大小以及line-height决定的。 有了这个理解之后,我们来定义按钮以及输入的基本风格: 这里我们把按钮的display设置成了inline-flex,这样我们就可以使用justify-content以及align-items来做中间对齐。 我们对按钮和文本使用了同样的vertical padding, font-size, line-height以及border-width。 我们并不想给按钮加入特定的边框,所以这里设置成transparent. Line-height的值需要比1大一点点。假如使用1,输入的元素就会有问题,所以我们这里使用的是1.2,当然你也可以使用normal。 上面这样的基本风格设置可以保证按钮和输入元素有同样的高度,以及他们的内容是垂直对齐的。当然,你可以修改他们的font-size,或者设置不同的font-family,这些修改都不会影响对齐。 进一步优化 下面我们需要做的是为按钮和输入设置定制主题。 例外 也许你会遇到一些情况,我们需要设置固定高度的按钮和输入元素,而默认的line-height会破坏对齐。这种情况下,我们可以把垂直padding去除掉,并且设置line-height等于height的值。下面是一个例子:

0

登录界面的最佳实践

假如你的网页需要用户注册/登录,那么一个好的注册/登录界面就非常重要了,尤其是在用户的网络状况不佳,或者使用移动设备,亦或是心情不太好的时候。一个不佳的界面可能会让用户再也不想访问你的页面。 下面就是一个简单的登录界面,它展示了所有的最佳实践需要关注的地方: 那么一个登录/注册界面有哪些地方需要注意的呢?我们一一道来: 使用有意义的HTML 使用下面这些HTML的tag来创建这个界面:<form><label>以及<button>,这些浏览器内建的功能,可以极大的改进可访问性。 使用<form> 你可能会使用<div>,然后在里面使用javascript来控制input的提交。其实最好还是使用原来的<form>元素。这样你的网站对屏幕阅读器或者别的辅助装备就更加友好,而且对旧的浏览器兼容也会好很多,设置在js失败的情况下也能够使用。 使用<label> 使用<label>来label一个输入: 这样做有两个原因: 当点击lable的时候,它会自动聚焦到他的输入。把label和输入关联是使用它的‘for’属性,可以设置成管理输入的name或者id。 屏幕阅读器会阅读这个文本 不要在input label中使用占位符,人们很容易忘了他们输入的是什么,究竟是email的地址,电话号码还是一个用户id。最好把你的label放在输入的上面,这样在移动设备以及桌面的体验就一致了。而且label和输入都可以得到所有的宽度,你不需要调整label和输入的宽度,如下图所示: 使用<button> 对按钮来说,使用<button>元素。因为它提供了很多特性和内置的表格提交功能,而且可以有很多不同的风格。我们没有理由选择别的<div>等来实现类似的功能。 另外对提交按钮来说,确认它究竟是做什么,比如是创建account和登录,而不是提交或者开始等。 确保正确表格的提交 要协助密码管理理解一个提交的表格,有两种方法可以做这个: 跳转到一个不同的页面。 使用History.pushState()或者History.ReplaceState()来模拟跳转,当然同时移除密码表格 在使用XMLHttpRequest或者fetch请求之后,确保登录是成功的,就需要把这个登录界面从DOM中移除,这样就可以很成功地像用户显示操作的结果。 当用户点击了之后就禁用登录按钮,因为很多用户在完成点击后还是会点击很多次,哪怕你的网页反应很快。 而另外一个方面,不要在用户没有完成输入的时候就禁用登录按钮,比如说用户没有输入密码就不让它点登录按钮,因为有时候用户自己也不知道哪里没有输入,然后就不停地在尝试。或者最起码,你禁用按钮的同时告诉用户为什么会禁用。 不要重复输入 有些网站让用户输入email和密码两次,这有可能会减少错误,但是会增加大多数用户的输入负担。尤其是很多时候浏览器自动填充了这些信息,那么输入两次就更没有意义了。更好的方式就是让用户确认他们的邮箱(反正你也肯定需要这么做),然后提供一个很方面的重置密码的方式就行。 充分利用元素属性 浏览器有很多内置的特性可以使用各种元素的属性。 帮助用户更快地开始 加一个autofocus属性到你注册表格的第一个输入,这样可以让用户知道从哪里开始,至少在桌面应用我们可以这么做,这样用户不需要点击输入框,然后再开始输入。 保护密码–但是在用户想要看到的时候可以让他们看到 密码的输入需要使用type=”password”,这样就可以隐藏输入的密码,同时也让浏览器知道输入的是密码。同时,你也需要加入显示密码的图标,这样用户可以点击它来看到自己输入的密码是多少,当然同时也不要忘记加入一个“忘记密码”的链接,如下所示: 给移动用户一个正确的键盘 使用<input...

0

如何使用AVIF:下一代图形压缩格式

一个更加优化的图形格式 目前有一个新的图形格式,它就是AV1 (.avif)格式。总得来说,它是一个高度压缩的图形类型。很多公司已经开始考虑使用.avif来替代JPEG, PNG甚至最新的WebP的图形格式,毕竟他的压缩比真的很好。 这个格式是由Alliance for Open Media与Google,Cisco以及Xiph.org一起开发的。这个格式是开源的并且免版税的。 AVIF和JEPG以及WebP的比较 AVIF和JPEG以及WebP比起来有明显更加小。和JPEG比起来小了大概50%,和WebP比起来大概小了20%。 这个格式非常灵活,支持各种图形解码器,可以使用一个alpha通道,设置能保存一系列的动画帧。 也是第一个支持HDR颜色的图形格式,能够有更好的亮度,颜色深度以及色域。 在Web开发中使用AVIF 2020年八月25号,Chrome 85已经开始支持AVIF了,Firefox 80也可以通过配置来支持了。Fixfox中的配置,可以输入下面的about:config,然后搜索image.avif.enabled,并把这个参数设置为true。 通过Squoosh来创建AVIF Squoosh是一个图形压缩web app,我们可以使用它的一些高级的选项来设置各种图形压缩。 最近Chrome Lab团队把AVIF加入到了Squoosh web app中,这大概是目前最好的创建.avif文件的方式了。 假如你对命令行有兴趣的话,你可以使用官方的AOMedia库,libavif。假如你使用macOS,可以使用Homebrew。你可以通过下面的命令来快速安装: 渐进增强的AVIF 尽管AVIF目前还不是在所有的地方都支持,我们仍然可以利用原生HTML中的<picture>元素来使用这个格式。就是把avif的格式支持放在第一位,这样浏览器就会先看能不能支持,如果不能支持会选择下面的别的格式。 AVIF Content-Type Header + Netlify 我们之前在Netlify中使用这个图片的时候,发现一个问题,就是这个图形在FireFox中不显示,但是在Chrome中使用就没有问题,最后我们才发现,response header会返回Content-Type: application/octet-stream,然后这样一来Firefox就什么不会显示。我们在Netlify的配置文件中netlify.toml中加入了下面这个自定义的header:...

你意想不到的默认超时 0

你意想不到的默认超时

有时我们会发现很多应用它不会崩溃,但是很多时候它会hang住。而hang住的一个很重要的原因就是假设网络是可靠的。而事实上却不是。 所以,当你做一个网络调用而没有设置超时的,就意味着你100%确认这个调用会成功,真的可以这么自信吗?哈哈。 假如是一个同步的调用,如果这个调用永远不返回,则显然会永远卡住。不过实际上我们都是使用的异步调用,是的,一个异步调用的不返回是不会卡住主进程的。但是有一个新的问题,就是它会消耗socket。因为很多HTTP客户端的库都使用socket池,这样就不需要每次都创建连接(毕竟创建连接是需要时间的)。一般来说,这种socket池也是有大小限制的,这也就意味着每一次不返回的调用都会消耗socket池中的一个已有的连接。所以,但这种情况发生了比较多了之后,你的应用就会卡在等待连接的释放。 假如你的网络不可靠,我们为什么总是要创建一个不超时的API呢?很多API调用甚至每有一个很方便的设置tiemout的地方,尤其是初始化的时候,你要设置timeout就需要额外进行调用。尤其是这种API很多时候默认的timeout还是无限的。当然,一个好的API都有很方便的设置timeout的方法。 所以,第一个建议就是永远不用把默认的timeout设为无限。 我们下面来看一个例子: 我们经常会使用Javascript中的XMLHttpRequest这一个web API。它的默认timeout是0,也就是没有timeout: 现代web应用中可以使用fetch来取代XMLHttpRequest API,它使用的是promise。当它刚实现的时候,根本就没有方法来设置timeout,不过最近浏览器加入了一个Abort的API来设置timeout。 其实在Python方面也是类似的,request库也默认使用无限作为timeout的。 那Go怎么样呢?其实也是一样的,默认没有timeout 当然在Java和.NET的世界则会更加好一点,它们都有默认的timeout。比如.Net Core的HttpClient有100s的默认时间,虽然很难说这个值好不好,但总归比没有好。 总结 所以总的来说,不管默认的timeout是多少,我们最好都设置自己想要的timeout。