• 关于 文本框上的事件 的搜索结果

问题

如何解决移动端弹出虚拟键盘后的Fiexd元素不会跟随上去

小旋风柴进 2019-12-01 19:37:16 1015 浏览量 回答数 1

问题

ios开发 对购物车列表中物品数量的编辑

杨冬芳 2019-12-01 20:15:51 1179 浏览量 回答数 1

问题

【精品问答】前端实战100例之JavaScript篇

珍宝珠 2020-02-14 15:10:56 1456 浏览量 回答数 1

新用户福利专场,云服务器ECS低至96.9元/年

新用户福利专场,云服务器ECS低至96.9元/年

回答

1. Java事件处理三要素: 1) 事件源(Event Source):即事件发生的场所,就是指各个组件,如按钮等,点击按钮其实就是组件上发生的一个事件; 2) 事件(Event):事件封装了组件上发生的事情,比如按钮单击、按钮松开等等; 3) 事件监听器(Event Listener):负责监听事件源上发生的特定类型的事件,当事件到来时还必须负责处理相应的事件; 2. 事件处理的机制: 1) 首先事件是有不同的类别的,比如按钮单击、菜单项单击等事件就属于“动作事件”(Action Event),而关闭窗口、最小化窗口等事件就属于“窗口事件”(Window Event); 2) 不同类型的事件需要用不同类型的监听器监听; 3) 而监听器是一种类对象,这种类必须实现监听器接口(Listener),对于监听不同类型的事件AWT库准备了不同类型的监听器接口,比如要监听动作事件就必须实现ActionListener接口,监听窗口事件就必须实现WindowListener接口; !监听器中最重要的就是事件处理方法了,监听器必须在接受事件之后进行处理(响应); 4) 如何实现监听? i. 首先事件源(发生事件的组件)必须同意我身上发生的事件允许那些监听器监听; ii. 也就是说想监听它身上发生的事件的监听器必须到它这里注册,即组件必须调用方法addXxxListener将监听器注册到它的监听器列表中; iii. 当事件发生时就会将事件对象(Event)发送到所有注册过的监听器那里进行处理; 5) 事件源、事件、监听器的对应关系: i. 首先一个事件源可以产生多种类型的事件,比如窗口右上角的×按钮,当单击它时就会产生两种类型的事件,一个是按钮单击事件(属于Action Event),另一个是窗口关闭事件(属于Window Event); ii. 监听器接口是什么类型就发送什么类型的事件:如果注册的监听器实现的是ActionEvent的接口,那么上述×按钮就只发送按钮单击事件给它而不会发送窗口关闭事件,除非监听器同时实现了两种类型的接口,那么该监听器就会同时受到两种类型的事件; iii. 一个事件源可以注册多个监听器:一般符合逻辑的编程思想就是不同监听器监听、处理不同类型的事件,因此对于可以产生多种类型事件的事件源会注册多种类型的监听器,分别负责处理产生的多种事件; !!当然一个事件源也可以注册多个相同类型的监听器,即比对于同一个事件(按钮单击),事件源注册多个实现ActionListener接口的监听器,那么这些监听器都会受到该事件,可能会疑问,这不是多此一举吗?一种事件就给出一种处理不是很好吗?那是因为有些情况下可能需要一个事件触发多种动作,每个监听器负责实现一个动作; iv. 一个监听器可以监听多个事件源上的事件,即多个不同的组件用addXxxListener方法注册同一个监听器,那么当不同事件到来时监听器会调用其不同方法进行处理,或者在一个方法内部判断传进来的是什么事件,再进行特殊的处理; 3. 编写事件处理程序的基本流程: 1) 首先需要实现监听器类:自己编写一个类,至少要实现一种类型的监听器接口,并实现接口中所有的事件处理方法; 2) 创建组件,并对组件注册响应的监听器:首先需要创建监听器对象,将监听器对象作为参数传入组件的addXxxListener方法完成注册; 3) 全部工作完成,事件的处理完全自动进行; 4) 简单的示例:处理一个按钮的单击事件 [java] view plain copy public class AwtTest { Frame f = new Frame("Event Test"); TextField tf = new TextField(30); Button ok = new Button("OK"); class OkListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub System.out.println("OK button pushed!"); tf.setText("Hello!"); } } public void init() { f.add(tf); f.add(ok, BorderLayout.SOUTH); ok.addActionListener(new OkListener()); f.pack(); f.setVisible(true); } public static void main(String[] args) { new AwtTest().init(); } } !!完全按照讲述的顺序进行; !直接设置编辑框内文本的方法:void TextField.setText(String text); 4. 事件源-监听器多对多示例: [java] view plain copy public class AwtTest { Frame f = new Frame("Multiple Event Test"); TextArea ta = new TextArea(6, 40); Panel p = new Panel(); Button btn1 = new Button("button1"); Button btn2 = new Button("button2"); class Listener1 implements ActionListener { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub ta.append("Listener1 be activated! Event Source:" + e.getActionCommand() + "\n"); } } class Listener2 implements ActionListener { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub ta.append("Listener2 be activated! Event Source:" + e.getActionCommand() + "\n"); } } public void init() { f.add(ta); p.add(btn1); p.add(btn2); f.add(p, BorderLayout.SOUTH); Listener1 l1 = new Listener1(); Listener2 l2 = new Listener2(); btn1.addActionListener(l1); btn2.addActionListener(l1); btn2.addActionListener(l2); f.pack(); f.setVisible(true); } public static void main(String[] args) { new AwtTest().init(); } } !可以看到按钮2可以同时触发两个监听器,输出两条消息,而监听器1同时监听并处理了两个按钮的消息;

1668934001470375 2019-12-02 01:02:20 0 浏览量 回答数 0

问题

如何将CSV文件导入MySQL表?

保持可爱mmm 2020-05-10 17:23:09 1 浏览量 回答数 1

回答

场景描述 用户通过手机终端、Web应用、或者PC工具把各种文件包括图片、视频以及文本等上传到OSS(对象存储,下同)后,利用OSS的PutObject事件可以触发函数计算对上传后的文件进行处理。 典型场景 当用户把视频文件上传到OSS后,触发函数计算把对象的Meta信息获取并传输给核心算法库,核心算法库根据算法把相应的视频文件推送CDN源站,达到特定视频热加载的处理。另外一个场景,视频文件上传到OSS后也同时触发函数计算同步做多转码率的处理,并把处理后的视频文件存储到OSS中,完成轻量的数据处理。 在多媒体的处理场景中,经常会碰到海量文件上传到OSS后,还需要对文件进行进一步的加工,例如加水印、转码率、获取文件属性等操作,这个场景中,用户在处理的时候会遇到以下需要解决的技术难点: 如何接收文件上传后的动作事件,通常的做法是定制消息通道来接收OSS事件通知,搭建一个运行环境,并编写相关的代码来处理事件通知。 如何高效的处理完海量上传的文件。 如何无缝的把多个云产品连接起来。 通过函数计算能比较方便解决以上几个技术难点: 函数计算可以设置OSS的触发器来接收事件通知,在函数计算中编写业务代码来处理文件,并通过内网把文件传输到OSS中,整个流程简单易用可扩展。 可以把核心代码部署到函数计算中,通过函数计算来并发处理事件通知。 函数计算目前打通了多款产品的内部交互,通过控制台简单配置就可以高效的解决产品间连接问题。 事件触发场景常规做法: 设置消息通道接收事件,并编写业务代码。 购买服务器资源做后端数据处理。 设计一套多并发框架完成业务上传文件峰值的处理。 开通多个产品,并调用SDK代码来完成业务交互。 函数计算解法: 在控制台上配置事件源通知,编写业务代码。 代码写到函数计算里,不需要管理软硬件环境。 业务高峰期函数计算会动态伸缩,无需管理。 内置打通多款产品,简单配置就可以无缝对接。

游客pklijor6gytpx 2019-12-02 03:24:00 0 浏览量 回答数 0

问题

前端小白入门JQuery基础【新手百问合集】

游客886 2019-12-01 20:09:03 1237 浏览量 回答数 1

问题

前端小白入门JQuery基础 【新手百问合集】

马铭芳 2019-12-01 20:09:05 6738 浏览量 回答数 5

回答

import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; public class Calculation extends JFrame implements ActionListener{ private JTextField txfResult;//显示操作结果的文本框 JTextField txfM;//显示记忆的索引值的文本框 Double dM=0d;//存储数据 public Calculation() { super("swing 计算器实例"); /*设置用于显示的文本框*/ txfResult =new JTextField("0",30);//初始文本显示0 最大列数30 txfResult.setBackground(Color.WHITE); txfResult.setHorizontalAlignment(JTextField.RIGHT);//数字在文本框中靠右显示 txfResult.setEditable(false);//文本框不可编辑 即为readOnly只读属性 JPanel ResultTextPanel=new JPanel();//放操作结果文本框的面板 ResultTextPanel.add(txfResult); /*设置用于控制数字的键与显示记忆索引值的文本框*/ txfM=new JTextField(2);//最长2列 JButton b1=new JButton("Backspace");//退格键 JButton b2=new JButton("CE");//重置键 JButton b3=new JButton("C");//清0键 JPanel ControlPanel=new JPanel(); ControlPanel.setLayout(new GridLayout(1, 4, 2, 2));//1行4列 水平间距2 垂直间距2 ControlPanel.add(txfM); ControlPanel.add(b1); ControlPanel.add(b2); ControlPanel.add(b3); b1.addActionListener(this); b2.addActionListener(this); b3.addActionListener(this); /*数字和运算符键*/ String dcKey[]= {"MC","7","8","9","/","sqrt","MR","4","5","6","*","%","MS","1","2","3","-","1/x" ,"M+","0","+/-",".","+","="}; JPanel dcKeyPanel =new JPanel();//数字和运算符的面板 dcKeyPanel.setLayout(new GridLayout(4, 6,2,2)); //一个 循环放好所有数字和运算符组件 for(int i=0;i<24;i++) { JButton b=new JButton(dcKey[i]); dcKeyPanel.add(b); b.addActionListener(this); } Container ct=this.getContentPane();//窗体内容面板对象 ct.setLayout(new BorderLayout()); ct.add(ResultTextPanel,BorderLayout.NORTH); ct.add(ControlPanel,BorderLayout.CENTER); ct.add(dcKeyPanel,BorderLayout.SOUTH); pack(); setVisible(true); setResizable(false);//禁止最大化 setLocationRelativeTo(null);//居中显示 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { new Calculation(); } //////////////////////////////////////////////////////数字键和功能键的实现///////////////////////////////////////////////////////// private boolean newDigital=true;//类内全局boolean变量 用于表示是否是输入数的标志 private String operation="";//表示运算符的字符串 private double d1;//二元运算前操数 private double d2;//二元运算后操作数 private int optionValue;//区别加减乘除运算符的变量 /*监听方法*/ @Override public void actionPerformed(ActionEvent e) { String s=(e.getActionCommand());//返回与此动作相关的命令字符串 就是button上显示的字 String str=txfResult.getText(); /*后退键*/ if(s.equals("Backspace")) { if(str.equals("0")||str.equals("")) {//已经是清0状态下 不可再清0了 return; } String s1=txfResult.getText(); txfResult.setText(s1.substring(0, s1.length()-1));//截掉最后一个数字 } /*重置键*/ if(s.equals("CE")) { txfResult.setText("0"); newDigital=true;//是否是新输入的数的标志设置为true } /*清0键*/ if(s.equals("C")) { txfResult.setText("0"); optionValue=0;//表示运算符的变量设置为0 newDigital=true;//表示是否新输入的数的标志设置为true } /*数字键*/ if(s.length()==1&&s.charAt(0)>='0'&&s.charAt(0)<='9') { if(!newDigital) { txfResult.setText(str+s);//不是新输入的数 }else { txfResult.setText(s); newDigital=false;//表示是否新输入的数的标志设置为false } return; } /*小数点*/ if(s.equals(".")) { if(txfResult.getText().indexOf(".")==-1) {//若之前尚不存在小数点 /*判断数字是否0打头*/ if(txfResult.getText().trim().startsWith("0")) {//强大的API txfResult.setText("0."); newDigital=false; }else { txfResult.setText(str+".");//str事件刚开始就得到的txfResult.getText() } } return; } /* 表示数字正负符号+/- */ if(s.equals("+/-")) { double d=Double.parseDouble(str.trim());//获取输入的数字 txfResult.setText(String.valueOf(-d));//取得获取输入数字的相反数 return; } //////////////////////////////////////////////////////加减乘除运算的实现///////////////////////////////////////////////////////// if(s.equals("+")) { d1=Double.parseDouble(txfResult.getText());//立刻获取前操作数的值 txfResult.setText(""); optionValue=1;//设置运算符标志 } if(s.equals("-")) { d1=Double.parseDouble(txfResult.getText()); optionValue=2; } if(s.equals("*")) { d1=Double.parseDouble(txfResult.getText()); optionValue=3; } if(s.equals("/")) { d1=Double.parseDouble(txfResult.getText()); optionValue=4; } if(s.equals("=")) { d2=Double.parseDouble(txfResult.getText());//获取后操作数的值 /*根据运算符标志的不同值确定计算结果*/ switch(optionValue) { case 1: txfResult.setText(String.valueOf(d1+d2)); break; case 2: txfResult.setText(String.valueOf(d1-d2)); break; case 3: txfResult.setText(String.valueOf(d1*d2)); break; case 4: if(d2!=0) { txfResult.setText(String.valueOf(d1/d2)); }else { txfResult.setText("除数不能为0"); return; } break; } operation="";//运算结束 清空运算符 } ////////////////////////////////求平方根 倒数 百分比运算///////////////////////////////// if(s.equals("sqrt")) { double d=Double.parseDouble(txfResult.getText().trim());//获取操作数的值 if(d>0) { txfResult.setText(String.valueOf(Math.sqrt(d)));//计算该值的平方根 }else { txfResult.setText("负数不能计算平方根"); } }else if(s.equals("1/x")) { double d=Double.parseDouble(txfResult.getText().trim());//计算倒数 if(str.equals("0")) { txfResult.setText("除数不能为0"); }else { txfResult.setText(String.valueOf(1/d)); } }else if(s.equals("%")) { txfResult.setText((String.valueOf(Double.parseDouble(str)/100))); } ///////////////////////////////////////////实现数据的记忆功能/////////////////////////////////// if(s.equals("MC")) {//清空存储数据 txfResult.setText(""); dM=0d; newDigital=true; } if(s.equals("MR")) { if(txfM.getText().trim()!="") { txfResult.setText(""+dM);//显示存储数字当前值 } } if(s.equals("MS")) { dM=Double.parseDouble(txfResult.getText().trim()); txfM.setText("M");//存储区显示M } if(s.equals("M+")) { dM=dM+Double.parseDouble(txfResult.getText().trim());//将显示的数字与已经存储的数据相加 即更新存储数据 } } }

DM。 2020-05-27 13:40:29 0 浏览量 回答数 0

回答

可以用springboot+netty来开发即时通讯。下面是百度的netty的简单介绍:Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。 也就是说,Netty 是一个基于NIO的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务开发。 “快速”和“简单”并不用产生维护性或性能上的问题。Netty 是一个吸收了多种协议(包括FTP、SMTP、HTTP等各种二进制文本协议)的实现经验,并经过相当精心设计的项目。最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。

日你dady哟 2019-12-02 03:08:15 0 浏览量 回答数 0

回答

HTML5究竟是什么? (注:目前网上介绍HTML5的文章都是千篇一律,譬如某个时间段发布某个版本,这种对于初学者或者从实用性角度来看,没有太多甚至完全不具备学习价值,只能说了解到它的出现时间,但是具体作用是什么呢?基本都是没有详细阐述,不少读者看完估计还是一头雾水的,因此笔者会用更加通俗易懂的话语,让各位能够知道HTML5究竟是什么) 首先HTML是定义了网页的结构,那么HTML5则是其不断更新的一部分。它目前有两个版本, 第一个是万维网联盟的5.2推荐标准(w3c) ,是为网页内容开发者设计的;第二个是浏览器开发者的 HTML 生活标准(HTML Living Standard) ,由微软网页超文本技术工作小组公司(WHATWG)维护。 HTML5引入了一些新的元素和属性,同时也是一个 W3C推荐标准。Web 应用程序以这些 HTML 元素为基础运行,同时包含了 HTML4和 XHTML,但是向后兼容以前的版本。另外,它与 PHP 更加兼容,新的 api 包括拖放、网络消息和网络存储、协议处理程序注册、微数据、画布、文本轨道和定时媒体播放,还有一个标准化的服务器发送事件自动更新和更好的浏览器支持,这些新的 api 为网页设计者提供了更好的控制。对于生活标准版本,新的 API 还包括地理定位、web 音频(Javascript 音频应用程序)、web RTC 和 web 加密 API。 这些元素和属性反映了现代网站的典型用法,其中包括超文本标记语言和对文档对象模型(DOM)脚本的新兴趣。HTML5语法还允许在文档内部使用 MathML,而 indexeddb将存储扩展到本地存储之外。并且从 HTML 4.01中删除了一些不推荐的元素,包括像 font 和 center 这样的纯表示元素,这些元素的效果早已被更强大的层叠样式表所取代。此外,DOM 脚本在 Web 行为中的重要性也得到了重新强调。 HTML5知识点有哪些? 经过前面的一些讲解,相信各位对HTML5已经有初步的认识,那么接下来我们将会正式探讨下,究竟有哪些知识点需要我们学习掌握的呢?(注:由于HTML5涵盖知识点较多,且本文属于入门级别的知识指南,不适宜进行全面深入地讲解,因此笔者筛选出了必须掌握的知识点,希望能够让初学者迅速入门) 知识点一:HTML5主体结构 <!doctype> 声明必须位于 HTML5 文档中首行,声明此为HTML5文档 标签限定了文档的开始点和结束点,内部包含文档头部和主体 标签用于定义文档的头部,内部的元素可以引用脚本或者样式表、提供元信息等等,并且描述了文档的各种属性和信息,包括文档的标题、在 Web 中的位置以及和其他文档的关系等,绝大多数文档头部包含的数据都不会真正作为内容显示给读者。 标签声明使用utf-8编码 标签定义文档标题 定义文档的主体,内部包含文档的所有内容,比如文本、超链接、图像、表格和列表等等,均可展示给用户浏览器显示出来(注释除外) 以上就是HTML5主体结构的讲解,可能有细心地读者就会发现,有的标签是一个的,有的又是两个对称的,那么这是何解呢? 这里就引入一个知识点,通常情况下绝大多数标签都是双标签,也就是需要写成格式,但是也有的单标签也称为自闭合标签是不需要结束符的,如 等,那么这些标签具体用法又是如何呢?下面我们将会进行常用标签的讲解! 知识点二:HTML5常用标签 众所周知,HTML5简单点说就是由一个个标签组成的文档,既然如此我们就需要学习,每一个标签究竟代表着什么含义如何使用呢?(因为标签实在太多,倘若全部阐释一遍,怕初学者们嫌弃篇幅太长感到枯燥,或者是知识点太多很难吸收掌握,因此笔者精选出一些较为常用的标签进行讲解,对于标签可能有多个属性可以选择,笔者同样会挑选出较为常用属性进行讲解) 注:以下标签,笔者没有截效果图,建议初学者自主尝试 注释标签:在我们日常编写代码时候,为了日后方便自己查看或者是别人查阅,我们通常会在某些地方写上注释标签,里面内容不会展示给浏览器用户看到 阿里云开发者社区 链接标签:超链接跳转,把需要跳转的网址写到标签的href里面,然后在开始标签和结束标签之间可以写内容展示出去,当用户点击内容将会发生跳转 换行标签:换行作用,有的小伙伴可能看到这里会说,为什么我写也是有效果的呢?这种写法不能说错误只能说是老版本的规范,按照HTML4.0规范都需要按照XHTML的写法,也就是对于单标签都是采用加斜杠的写法(下同) 按钮 按钮标签:按钮上需要展示什么文字,可在开始标签和结束标签之间写入,现阶段若写静态网站用得较少,后期学JS制作动态网站或者做交互时候比较常用 内容 块级标签:标签本身没有特殊含义,那么在其里面可以写文本内容,或者是加入其它标签均可,凡是加入其内部所有东西都会被其所包裹,形成一个独立的块级区域并且独自占用一行(css可格式化) 标题 标题标签:用于定义标题,从h1至h6均可根据自身需求选择 分隔符标签:起到装饰分隔作用,默认显示为一条黑色的水平线 图片标签:展示图片,src里面放置图片的链接,然后有时候可能出现各种原因导致图片未能加载,那么系统会自动展示alt里面的文字内容 输入框标签:默认是输入框,当然其有多个属性可以选择,然后较为常用的是type属性,该属性又有多个值可供选择,如: password 用户输入任何文本内容均会显示为小圆点 checkbox 选择框 Button按钮 列表 列表标签:通常用于展示一列数据,而且数据所采用的css样式均相同,譬如导航栏、当然还有 有序列表不过较为少用 段落 段落标签:写在内部的一段文字将会被定义为一个段落 脚本标签:现阶段不会用到,等学习到js需要用到,初学者可在标签内部写js代码,随着学习深入可以采用外部写好js文件后导入 文字 脚本标签:通常需要搭配css样式进行使用,对部分内容进行样式修改 样式标签:现阶段不会用到,等学习到css需要用到,样式需要写在标签内部 HTML5入门知识指南 经过前面的一系列学习,相信各位已经初步掌握HTML5的使用,能够制作一些简单的界面了,当然对于学习能力较强或者有一定基础的同学,可以自主深入学习HTML5深层次的知识点,当能够熟练敲出你想要的界面时候,那建议开始学习CSS让界面变得更加美丽,笔者下期将会给各位带来CSS入门知识指南,欢迎大家踊跃参与学习,当然如果有童鞋看完本文,对于某些知识点还是不太明白,或者是对下一期学习有什么建议,欢迎各位在下方评论区留言哦,如果觉得笔者文章写得不错,那么也可以分享给朋友一起学习,咱们下期再见啦!

剑曼红尘 2020-03-03 17:56:06 0 浏览量 回答数 0

回答

表单是直接提交还是这么提交的?好像是表单提交没有file域吧?回复<aclass='referer'target='_blank'>@腾讯公告:嗯嗯,我另一个food就是这样做的,现在这个music我在页面上不作文件上传,就单单是修改他musicname,但是得到的却是null回复<aclass='referer'target='_blank'>@流离影风:还有,你的file一定要有文件提交,否则你后台要做一个判断是否有文件。我用js只是为了判断文本框是否有value的,单submit提交也是不能成功的回复<aclass='referer'target='_blank'>@流离影风:建议先不要用js,直接submit按钮提交表单过去更心塞的是通过在页面写js,触发点击事件,可以获得text属性页面上输入的值,但是后台还是死活得不到,就只是这个得不到,我写的另一个food用的还是这种方式却可以得到。。。。 接收到的请求不是一个multipart请求 印象中,就算你<spanstyle="font-family:'MicrosoftYaHei',Verdana,sans-serif,宋体;font-size:14px;line-height:22px;background-color:#FFFFFF;"> <spanstyle="font-family:'MicrosoftYaHei',Verdana,sans-serif,宋体;font-size:14px;line-height:22px;background-color:#FFFFFF;color:#E53333;">enctype="multipart/form-data<spanstyle="font-family:'MicrosoftYaHei',Verdana,sans-serif,宋体;font-size:14px;line-height:22px;background-color:#FFFFFF;">",然后表单没有提交文件,在SpringMVC里是用不了MultipartHttpServletRequest的可以对这个文件是否存在做个判读,我另一个food也有个上传图片,就是在MultipartHttpServletReqeust下做的,。通过判断完成上传

爱吃鱼的程序员 2020-06-10 10:02:52 0 浏览量 回答数 0

回答

简介 如果您听说过 Node,或者阅读过一些文章,宣称 Node 是多么多么的棒,那么您可能会想:“Node 究竟是什么东西?”尽管不是针对所有人的,但 Node 可能是某些人的正确选择。 为试图解释什么是 Node.js,本文探究了它能解决的问题,它如何工作,如何运行一个简单应用程序,最后,Node 何时是和何时不是一个好的解决方案。本文不涉及如何编写一个复杂的 Node 应用程序,也不是一份全面的 Node 教程。阅读本文应该有助于您决定是否应该学习 Node,以便将其用于您的业务。 Node 旨在解决什么问题? Node 公开宣称的目标是 “旨在提供一种简单的构建可伸缩网络程序的方法”。当前的服务器程序有什么问题?我们来做个数学题。在 Java™ 和 PHP 这类语言中,每个连接都会生成一个新线程,每个新线程可能需要 2 MB 配套内存。在一个拥有 8 GB RAM 的系统上,理论上最大的并发连接数量是 4,000 个用户。随着您的客户端基础的增长,您希望您的 web 应用程序支持更多用户,这样,您必须添加更多服务器。当然,这会增加业务成本,尤其是服务器成本、运输成本和人工成本。除这些成本上升外,还有一个技术问题:用户可能针对每个请求使用不同的服务器,因此,任何共享资源都必须在所有服务器之间共享。例如,在 Java 中,静态变量和缓存需要在每个服务器上的 JVMs 之间共享。这就是整个 web 应用程序架构中的瓶颈:一个服务器能够处理的并发连接的最大数量。 Node 解决这个问题的方法是:更改连接连接到服务器的方式。每个连接都创建一个进程,该进程不需要配套内存块,而不是为每个连接生成一个新的 OS 线程(并向其分配一些配套内存)。Node 声称它绝不会死锁,因为它根本不允许使用锁,它不会直接阻塞 I/O 调用。Node 还宣称,运行它的服务器能支持数万个并发连接。事实上,Node 通过将整个系统中的瓶颈从最大连接数量更改到单个系统的流量来改变服务器面貌。 现在您有了一个能处理数万条并发连接的程序,那么您能通过 Node 实际构建什么呢?如果您有一个 web 应用程序需要处理这么多连接,那将是一件很 “恐怖” 的事!那是一种 “如果您有这个问题,那么它根本不是问题” 的问题。在回答上面的问题之前,我们先看看 Node 如何工作以及它被设计的如何运行。 Node 肯定不是什么 没错,Node 是一个服务器程序。但是,它肯定不 像 Apache 或 Tomcat。那些服务器是独立服务器产品,可以立即安装并部署应用程序。通过这些产品,您可以在一分钟内启动并运行一个服务器。Node 肯定不是这种产品。Apache 能添加一个 PHP 模块来允许开发人员创建动态 web 页,使用 Tomcat 的程序员能部署 JSPs 来创建动态 web 页。Node 肯定不是这种类型。 在 Node 的早期阶段(当前是 version 0.4.6),它还不是一个 “运行就绪” 的服务器程序,您还不能安装它,向其中放置文件,拥有一个功能齐全的 web 服务器。即使是要实现 web 服务器在安装完成后启动并运行这个基本功能,也还需要做大量工作。 Node 如何工作 Node 本身运行 V8 JavaScript。等等,服务器上的 JavaScript?没错,您没有看错。服务器端 JavaScript 是一个相对较新的概念,这个概念是大约两年前在 developerWorks 上讨论 Aptana Jaxer 产品时提到的(参见 参考资料)。尽管 Jaxer 一直没有真正流行,但这个理念本身并不是遥不可及的 — 为何不能在服务器上使用客户机上使用的编程语言? 什么使 V8?V8 JavaScript 引擎是 Google 用于他们的 Chrome 浏览器的底层 JavaScript 引擎。很少有人考虑 JavaScript 在客户机上实际做了些什么?实际上,JavaScript 引擎负责解释并执行代码。使用 V8,Google 创建了一个以 C++ 编写的超快解释器,该解释器拥有另一个独特特征;您可以下载该引擎并将其嵌入任何 应用程序。它不仅限于在一个浏览器中运行。因此,Node 实际上使用 Google 编写的 V8 JavaScript 引擎并将其重建为在服务器上使用。太完美了!既然已经有一个不错的解决方案可用,为何还要创建一种新语言呢? 事件驱动编程 许多程序员接受的教育使他们认为,面向对象编程是完美的编程设计,而对其他编程方法不屑一顾。Node 使用一个所谓的事件驱动编程模型。 清单 1. 客户端上使用 jQuery 的事件驱动编程 复制代码 代码如下: // jQuery code on the client-side showing how Event-Driven programming works // When a button is pressed, an Event occurs - deal with it // directly right here in an anonymous function, where all the // necessary variables are present and can be referenced directly $("#myButton").click(function(){ if ($("#myTextField").val() != $(this).val()) alert("Field must match button text"); }); 实际上,服务器端和客户端没有任何区别。没错,这没有按钮点击操作,也没有向文本字段键入的操作,但在一个更高的层面上,事件正在 发生。一个连接被建立 — 事件!数据通过连接接收 — 事件!数据通过连接停止 — 事件! 为什么这种设置类型对 Node 很理想?JavaScript 是一种很棒的事件驱动编程语言,因为它允许匿名函数和闭包,更重要的是,任何写过代码的人都熟悉它的语法。事件发生时调用的回调函数可以在捕获事件处编写。这样,代码容易编写和维护,没有复杂的面向对象框架,没有接口,没有在上面架构任何内容的潜能。只需监听事件,编写一个回调函数,然后,事件驱动编程将照管好一切! 示例 Node 应用程序 最后,我们来看一些代码!让我们将讨论过的所有内容综合起来,创建我们的第一个 Node 应用程序。由于我们已经知道,Node 对于处理高流量应用程序很理想,我们就来创建一个非常简单的 web 应用程序 — 一个为实现最大速度而构建的应用程序。下面是 “老板” 交代的关于我们的样例应用程序的具体要求:创建一个随机数字生成器 RESTful API。这个应用程序应该接受一个输入:一个名为 “number” 的参数。然后,应用程序返回一个介于 0 和该参数之间的随机数字,并将生成的数字返回调用者。由于 “老板” 希望它成为一个广泛流行的应用程序,因此它应该能处理 50,000 个并发用户。我们来看看代码: 清单 2. Node 随机数字生成器 复制代码 代码如下: // these modules need to be imported in order to use them. // Node has several modules. They are like any #include // or import statement in other languages var http = require("http"); var url = require("url"); // The most important line in any Node file. This function // does the actual process of creating the server. Technically, // Node tells the underlying operating system that whenever a // connection is made, this particular callback function should be // executed. Since we're creating a web service with REST API, // we want an HTTP server, which requires the http variable // we created in the lines above. // Finally, you can see that the callback method receives a 'request' // and 'response' object automatically. This should be familiar // to any PHP or Java programmer. http.createServer(function(request, response) { // The response needs to handle all the headers, and the return codes // These types of things are handled automatically in server programs // like Apache and Tomcat, but Node requires everything to be done yourself response.writeHead(200, {"Content-Type": "text/plain"}); // Here is some unique-looking code. This is how Node retrives // parameters passed in from client requests. The url module // handles all these functions. The parse function // deconstructs the URL, and places the query key-values in the // query object. We can find the value for the "number" key // by referencing it directly - the beauty of JavaScript. var params = url.parse(request.url, true).query; var input = params.number; // These are the generic JavaScript methods that will create // our random number that gets passed back to the caller var numInput = new Number(input); var numOutput = new Number(Math.random() * numInput).toFixed(0); // Write the random number to response response.write(numOutput); // Node requires us to explicitly end this connection. This is because // Node allows you to keep a connection open and pass data back and forth, // though that advanced topic isn't discussed in this article. response.end(); // When we create the server, we have to explicitly connect the HTTP server to // a port. Standard HTTP port is 80, so we'll connect it to that one. }).listen(80); // Output a String to the console once the server starts up, letting us know everything // starts up correctly console.log("Random Number Generator Running..."); 将上面的代码放到一个名为 “random.js” 的文件中。现在,要启动这个应用程序并运行它(进而创建 HTTP 服务器并监听端口 80 上的连接),只需在您的命令提示中输入以下命令:% node random.js。下面是服务器已经启动并运行时它看起来的样子: 复制代码 代码如下: root@ubuntu:/home/moila/ws/mike# node random.js Random Number Generator Running... 访问应用程序 应用程序已经启动并运行。Node 正在监听任何连接,我们来测试一下。由于我们创建了一个简单的 RESTful API,我们可以使用我们的 web 浏览器来访问这个应用程序。键入以下地址(确保您完成了上面的步骤):localhost/?number=27。 您的浏览器窗口将更改到一个介于 0 到 27 之间的随机数字。单击浏览器上的 “重新载入” 按钮,将得到另一个随机数字。就是这样,这就是您的第一个 Node 应用程序! Node 对什么有好处? 到此为止,应该能够回答 “Node 是什么” 这个问题了,但您可能还不清楚什么时候应该使用它。这是一个需要提出的重要问题,因为 Node 对有一些东西有好处,但相反,对另一些东西而言,目前 Node 可能不是一个好的解决方案。您需要小心决定何时使用 Node,因为在错误的情况下使用它可能会导致一个多余编码的 LOT。 它对什么有好处? 正如您此前所看到的,Node 非常适合以下情况:您预计可能有很高的流量,而在响应客户端之前服务器端逻辑和处理所需不一定是巨大的。Node 表现出众的典型示例包括: 1.RESTful API 提供 RESTful API 的 web 服务接收几个参数,解析它们,组合一个响应,并返回一个响应(通常是较少的文本)给用户。这是适合 Node 的理想情况,因为您可以构建它来处理数万条连接。它还不需要大量逻辑;它只是从一个数据库查找一些值并组合一个响应。由于响应是少量文本,入站请求时少量文本,因此流量不高,一台机器甚至也可以处理最繁忙的公司的 API 需求。 2.Twitter 队列 想像一下像 Twitter 这样的公司,它必须接收 tweets 并将其写入一个数据库。实际上,每秒几乎有数千条 tweets 达到,数据库不可能及时处理高峰时段需要的写入数量。Node 成为这个问题的解决方案的重要一环。如您所见,Node 能处理数万条入站 tweets。它能迅速轻松地将它们写入一个内存排队机制(例如 memcached),另一个单独进程可以从那里将它们写入数据库。Node 在这里的角色是迅速收集 tweet 并将这个信息传递给另一个负责写入的进程。想象一下另一种设计 — 一个常规 PHP 服务器自己试图处理对数据库的写入 — 每个 tweet 将在写入数据库时导致一个短暂的延迟,这是因为数据库调用正在阻塞通道。由于数据库延迟,一台这样设计的机器每秒可能只能处理 2000 条入站 tweets。每秒 100 万条 tweets 需要 500 个服务器。相反,Node 能处理每个连接而不会阻塞通道,从而能捕获尽可能多的 tweets。一个能处理 50,000 条 tweets 的 Node 机器只需要 20 个服务器。 3.映像文件服务器 一个拥有大型分布式网站的公司(比如 Facebook 或 Flickr)可能会决定将所有机器只用于服务映像。Node 将是这个问题的一个不错的解决方案,因为该公司能使用它编写一个简单的文件检索器,然后处理数万条连接。Node 将查找映像文件,返回文件或一个 404 错误,然后什么也不用做。这种设置将允许这类分布式网站减少它们服务映像、.js 和 .css 文件等静态文件所需的服务器数量。 它对什么有坏处? 当然,在某些情况下,Node 并非理想选择。下面是 Node 不擅长的领域: 1.动态创建的页 目前,Node 没有提供一种默认方法来创建动态页。例如,使用 JavaServer Pages (JSP) 技术时,可以创建一个在这样的 JSP 代码段中包含循环的 index.jsp 页。Node 不支持这类动态的、HTML 驱动的页面。同样,Node 不太适合作为 Apache 和 Tomcat 这样的网页服务器。因此,如果您想在 Node 中提供这样一个服务器端解决方案,必须自己编写整个解决方案。PHP 程序员不想在每次部署 web 应用程序时都编写一个针对 Apache 的 PHP 转换器,当目前为止,这正是 Node 要求您做的。 2. 关系数据库重型应用程序 Node 的目的是快速、异步和非阻塞。数据库并不一定分享这些目标。它们是同步和阻塞的,因为读写时对数据库的调用在结果生成之前将一直阻塞通道。因此,一个每个请求都需要大量数据库调用、大量读取、大量写入的 web 应用程序非常不适合 Node,这是因为关系数据库本身就能抵销 Node 的众多优势。(新的 NoSQL 数据库更适合 Node,不过那完全是另一个主题了。) 结束语 问题是 “什么是 Node.js?” 应该已经得到解答。阅读本文之后,您应该能通过几个清晰简洁的句子回答这个问题。如果这样,那么您已经走到了许多编码员和程序员的前面。我和许多人都谈论过 Node,但它们对 Node 究竟是什么一直很迷惑。可以理解,他们具有的是 Apache 的思维方式 — 服务器是一个应用程序,将 HTML 文件放入其中,一切就会正常运转。而 Node 是目的驱动的。它是一个软件程序,使用 JavaScript 来允许程序员轻松快速地创建快速、可伸缩的 web 服务器。Apache 是运行就绪的,而 Node 是编码就绪的。 Node 完成了它提供高度可伸缩服务器的目标。它并不分配一个 “每个连接一个线程” 模型,而是使用一个 “每个连接一个流程” 模型,只创建每个连接需要的内存。它使用 Google 的一个非常快速的 JavaScript 引擎:V8 引擎。它使用一个事件驱动设计来保持代码最小且易于阅读。所有这些因素促成了 Node 的理想目标 — 编写一个高度可伸缩的解决方案变得比较容易。 与理解 Node 是 什么同样重要的是,理解它不是 什么。Node 并不是 Apache 的一个替代品,后者旨在使 PHP web 应用程序更容易伸缩。事实确实如此。在 Node 的这个初始阶段,大量程序员使用它的可能性不大,但在它能发挥作用的场景中,它的表现非常好。 将来应该期望从 Node 得到什么呢?这也许是本文引出的最重要的问题。既然您知道了它现在的作用,您应该会想知道它下一步将做什么。在接下来的一年中,我期待着 Node 提供与现有的第三方支持库更好地集成。现在,许多第三方程序员已经研发了用于 Node 的插件,包括添加文件服务器支持和 MySQL 支持。希望 Node 开始将它们集成到其核心功能中。最后,我还希望 Node 支持某种动态页面模块,这样,您就可以在 HTML 文件中执行在 PHP 和 JSP(也许是一个 NSP,一个 Node 服务器页)中所做的操作。最后,希望有一天会出现一个 “部署就绪” 的 Node 服务器,可以下载和安装,只需将您的 HTML 文件放到其中,就像使用 Apache 或 Tomcat 那样。Node 现在还处于初始阶段,但它发展得很快,可能不久就会出现在您的视野中。 答案来源于网络

养狐狸的猫 2019-12-02 02:17:03 0 浏览量 回答数 0

问题

左右数字加减(范围为0-9),用jQuery写的正常,为什么用zepto就会一直加会超过9,一直减会出现负数。

杨冬芳 2019-12-01 19:54:40 1303 浏览量 回答数 1

问题

UI自动化体系建设的创新实践

云效平台 2019-12-01 20:57:08 2984 浏览量 回答数 0

问题

比较Apache Hadoop生态系统中不同的文件格式和存储引擎的性能

anrui2016 2019-12-01 22:03:39 2706 浏览量 回答数 0

回答

一、spring 中的概念 ##beanFactory容器1、容器是spring框架的核心,容器使用ioc依赖注入来管理所有组成应用系统的组件。 2、spring中的两种容器: beanFactory 这个容器提供了基础的依赖注入支持,而且是延迟加载的,而 applicationcontext是对beanFactory 这个容器的扩展, 3、beanFactory :beanFactory就是一个Bean工厂,使用了工厂模式,但bean工厂不像一般的工厂,只提供特定类的bean而是一个通用的工厂,可以创建和分发各种类型的bean,beanFactory不仅仅只是创建和分发bean因为我们知道,这个bean工厂知道应用中的很多对象,在创建这些对象的时候,创建出了这些对象之间的关联关系,bean工厂还管理这些对象的生命周期。4、beanFactory 接口的实现类有很多,我们这里就举一个常用的类: XMLBeanFactory, XMLBeanFactory构造方法的参数是一个inputStream对象,而传递进来的就是我们定义bean的xml文件 5、实例:BeanFactory beanfactory = new XMLBeanFactory(newFileInputStream(bean.xml)); 这样beanFactory就获取了配置文件中bean的信息,但是bean是延迟实例化的所以现在只是加载进来了,但还是没有创建实例,只有在使用的时候尽心创建 6、 User user=(User)beanfactory.getBean("user"); 当我们调用getBean()时工厂会实例化并且会依赖注入设置相关属性值。 ApplicationContext 容器 1、applicationcontext和beanFactory看来都是一样的,都是加载bean的信息,配置bean和分发bean,但是application context作为beanFactory的扩展有一些额外的功能:(1)文本信息解析工具,包括对国际化的支持(2)应用上下文提供了载入文件资源的通用方法(3)应用上下文可以向注册为监听器的bean发送事件,因为application context的额外功能所以在应用中大都使用application context而beanFactory在资源较少的移动设备上使用 2、ApplicationContext的实现:ClassPathXmlApplicationContext()类路劲中的xml文件中载入上下文信息,FileSystemXmlApplicationContext()文件系统xml获取上下文信息 XmlWebApplicationContext()从网络获取上下文信息。3、我们知道 ApplicationContext是对beanFactory的扩展所以我们同样可以使用 .getBean("User")来获取对象,但是这里有点不同,那就是在beanFactory中使用的就是懒加载,在调用getBean()的时候才会创建实例而ApplicationContext () 在上下文预加载的时候就创建了实例,在使用的时候不用等待创建而是直接使用。 Spring中bean的周期 1、容器寻找bean的定义信息,并且实例化bean2、使用依赖注入,spring按照bean定义信息配置bean的所有属性3、如果bean实现了BeanNameAware接口则工厂调用bean的setBeanName() 方法传递bean的Id4、如果bean实现了beanFacgtoryAware 接口则工厂调用 setBeanFactory()方法传入工厂本身。5、如果有BeanPostProcess和bean关联那么他们的PostProcessBeforeInitialzation()方法将被调用6、如果bean指定了init-method 方法则将被调用7、如果有BeanPostProcess和bean关联那么他们的PostProcessAfterInitialzation()方法将被调用 到这里bean就可以在系统中被使用了,并将一直保存在BeanFactory 中直到他不在使用。8、删除: spring 中有两种方式:(1)、如果bean实现了Disposable接口则destory方法将会被调用(2)、自己定义定义了销毁方法则执行他 destroy-method 依赖注入 1、所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象地说,即由容器动态地将某种依赖关系注入到组件之中。装配在spring容器内拼凑bean叫做装配,装配bean的时候你是在告诉容器需要哪些bean,以及容器如何使用依赖注入将他们配合在一起。 实例化1、在使用spring容器进行bean类的管理的时候,我们获取bean类有两种类型,一种就是在spring中使用了单例模式,获取的都是第一次加载的时候创建的那个bean实例,第二种就是在spring中没有定义单例模式,每获取一次就会产生一个新的bean实例。 区别这两种的配置: <beanid="user" class="com.inspur.User" singleton=off> </bean> // singleton(单一的 唯一的) 这里关闭了单例模式,所以每次获取的bean对象都是新的,而在spring中singleton默认是开着的,因为像数据库连接池,网络资源等创建新对象很浪费资源,所以还是使用单例模式比较好,如果没有特别需求还是使用单例模式比较好!

小旋风柴进 2019-12-02 01:58:02 0 浏览量 回答数 0

回答

推荐工具 1、Linx: Linx 是一款低代码的 IDE 和服务器。IT 专业人员使用 Linx 可以快速创建自定义的自动化业务流程、集成应用程序、公开 Web 服务,并有效地处理高工作负载。 易用使用的拖放式界面。 超过 100 种预建功能和服务,可实现快速开发。 直接从 IDE 一键部署到任何本地或远程 Linx 服务器。 输入和输出包括几乎所有的 SQL 和 NoSQL 数据库、大量文件格式(文本和二进制)或 REST 和 SOAP Web 服务。 使用分步逻辑进行现场调试。 通过计时器、目录事件或消息队列将后端流程自动化,或者公开 Web 服务,并通过 HTTP 请求调用 API。 下载链接:https://linx.software/lowcode-application-designer/?utm=99 2、Buddy Buddy 是一款面向 Web 开发人员的智能 CI/CD 工具,旨在降低 DevOps 的入门门槛。它使用交付管道来构建、测试和部署软件。这些管道由 100 多个随时可用的动作创建的,这些动作可以以任何方式进行安排,就像你用砖头建造房子一样。 15 分钟的配置,清晰易懂的用户界面 / 用户体验。 基于变更集的快速部署。 构建在具有缓存依赖项的独立容器中运行。 支持所有流行语言、框架和任务管理器。 Docker/Kubernetes 动作专用名册。 与 AWS、Google、DigitalOcean、Azure、Shopify、WordPress 等集成。 支持并行和 YAML 配置。 下载链接:https://buddy.works/ IDE (集成开发环境) 3、NetBeans NetBeans 是一款流行的免费开源 IDE。它可以用来开发桌面、移动和 Web 应用程序。 支持快速和智能代码编辑。 简单高效的项目管理流程。 快速用户界面开发。 帮助编写无 Bug 代码。 NetBeans IDE 为 C/C++ 和 PHP 开发人员提供了卓越的支持。 它可以安装在任何支持 Java 的操作系统上,从 Windows 到 Linux,再到 Mac OSX 系统。 下载链接:https://netbeans.org/downloads/index.html 4、Cloud9 IDE Cloud9 IDE 是一款在线集成软件开发环境。它支持许多编程语言,如 C、C++、PHP、Ruby、Perl、Python、JavaScript 和 Node.js。 允许克隆整个开发环境。 命令行想到的内置终端。 代码完成建议的功能可以帮助软件开发人员更快地编写代码并避免输入错误。 调试器可帮助开发人员设置断点,并检查任何 JS/Node.js 应用的变量。 只需拖动任何文件或终端即可创建多个拆分视图。 开发人员可以选择广泛的默认运行程序来执行应用程序,如 Ruby、Pythn、PHP/Apache。 下载链接:https://c9.io/pricing

有只黑白猫 2020-01-08 17:49:54 0 浏览量 回答数 0

回答

推荐工具 1、Linx: Linx 是一款低代码的 IDE 和服务器。IT 专业人员使用 Linx 可以快速创建自定义的自动化业务流程、集成应用程序、公开 Web 服务,并有效地处理高工作负载。 易用使用的拖放式界面。 超过 100 种预建功能和服务,可实现快速开发。 直接从 IDE 一键部署到任何本地或远程 Linx 服务器。 输入和输出包括几乎所有的 SQL 和 NoSQL 数据库、大量文件格式(文本和二进制)或 REST 和 SOAP Web 服务。 使用分步逻辑进行现场调试。 通过计时器、目录事件或消息队列将后端流程自动化,或者公开 Web 服务,并通过 HTTP 请求调用 API。 下载链接:https://linx.software/lowcode-application-designer/?utm=99 2、Buddy Buddy 是一款面向 Web 开发人员的智能 CI/CD 工具,旨在降低 DevOps 的入门门槛。它使用交付管道来构建、测试和部署软件。这些管道由 100 多个随时可用的动作创建的,这些动作可以以任何方式进行安排,就像你用砖头建造房子一样。 15 分钟的配置,清晰易懂的用户界面 / 用户体验。 基于变更集的快速部署。 构建在具有缓存依赖项的独立容器中运行。 支持所有流行语言、框架和任务管理器。 Docker/Kubernetes 动作专用名册。 与 AWS、Google、DigitalOcean、Azure、Shopify、WordPress 等集成。 支持并行和 YAML 配置。 下载链接:https://buddy.works/ IDE (集成开发环境) 3、NetBeans NetBeans 是一款流行的免费开源 IDE。它可以用来开发桌面、移动和 Web 应用程序。 支持快速和智能代码编辑。 简单高效的项目管理流程。 快速用户界面开发。 帮助编写无 Bug 代码。 NetBeans IDE 为 C/C++ 和 PHP 开发人员提供了卓越的支持。 它可以安装在任何支持 Java 的操作系统上,从 Windows 到 Linux,再到 Mac OSX 系统。 下载链接:https://netbeans.org/downloads/index.html 4、Cloud9 IDE Cloud9 IDE 是一款在线集成软件开发环境。它支持许多编程语言,如 C、C++、PHP、Ruby、Perl、Python、JavaScript 和 Node.js。 允许克隆整个开发环境。 命令行想到的内置终端。 代码完成建议的功能可以帮助软件开发人员更快地编写代码并避免输入错误。 调试器可帮助开发人员设置断点,并检查任何 JS/Node.js 应用的变量。 只需拖动任何文件或终端即可创建多个拆分视图。 开发人员可以选择广泛的默认运行程序来执行应用程序,如 Ruby、Pythn、PHP/Apache。 下载链接:https://c9.io/pricing

有只黑白猫 2020-01-20 17:21:34 0 浏览量 回答数 0

问题

Nginx性能为什么如此吊

小柒2012 2019-12-01 21:20:47 15038 浏览量 回答数 3

回答

adb介绍: Android Debug Bridge(安卓调试桥) tools。它就是一个命令行窗口,用于通过电脑端与模拟器或者是设备之间的交互。 ADB是一个C/S架构的应用程序,由三部分组成: 运行在pc端的adb client: 命令行程序”adb”用于从shell或脚本中运行adb命令。首先,“adb”程序尝试定位主机上的ADB服务器,如果找不到ADB服务器,“adb”程序自动启动一个ADB服务器。接下来,当设备的adbd和pc端的adb server建立连接后,adb client就可以向ADB servcer发送服务请求; 运行在pc端的adb server: ADB Server是运行在主机上的一个后台进程。它的作用在于检测USB端口感知设备的连接和拔除,以及模拟器实例的启动或停止,ADB Server还需要将adb client的请求通过usb或者tcp的方式发送到对应的adbd上; 运行在设备端的常驻进程adb demon (adbd): 程序“adbd”作为一个后台进程在Android设备或模拟器系统中运行。它的作用是连接ADB服务器,并且为运行在主机上的客户端提供一些服务。 adb下载及安装: 一共有两种方法: 首先第一种就是最简单的方法,只下载adb压缩包去解压即可:链接:https://pan.baidu.com/s/1SKu24yyShwg16lyIupO5VA 提取码:ih0i (备注:如果下载放入到D盘去解压,打开dos窗口那么就要进入到D盘,然后再去执行adb命令,输入adb查看它是否安装成功) 第二种方法前提是已安装了Android Studio,它本身带有adb命令,如果配置好的Android Studio 一般都是可以直接调用adb命令的;如果不行,找到adb在SDK里的绝对路径,放入环境变量path中(绝对路径不带入adb.exe) 然后输入adb version 查看版本 可以看出是否安装成功,如下就已经成功了。 启动 adb server 命令:adb start-server 停止 adb server 命令:adb kill-server 查询已连接设备/模拟器:adb devices 该命令经常出现以下问题: offline —— 表示设备未连接成功或无响应; device —— 设备已连接; no device —— 没有设备/模拟器连接; List of devices attached 设备/模拟器未连接到 adb 或无响应 USB连接: 在手机“设置”-“关于手机”连续点击“版本号”7 次,可以进入到开发者模式;然后可以到“设置”-“开发者选项”-“调试”里打开USB调试以及允许ADB的一些权限;连接时手机会弹出“允许HiSuite通过HDB连接设备”点击允许/接受即可; 驱动也是必须安装的,可以用豌豆荚,或者是手机商家提供的手机助手,点进去驱动器安装即可(部分电脑双击无法直接进入到驱动器里,可以使用右键找到进入点击即可) 再次输入adb devices验证是否连接成功,连接成功即如下图: 也可以进行无线连接,其中非root权限也需借助USB线进行操作,完成后即可断开USB线;root用户可以进行无线连接,具体步骤可以参考网上资源。 **查看是否有root权限:**输入adb shell,然后输入su KaTeX parse error: Expected 'EOF', got '#' at position 5: 如果变为#̲则成功,如果仍为则未有root权限;恢复命令:adb unroot 查看应用列表: 查看所有应用列表:adb shell pm list packages 查看系统应用列表:adb shell pm list packages -s 查看第三方应用列表:adb shell pm list packages -3: 安装apk:adb install “-lrtsdg” “path_to_apk” “-lrtsdg”: -l:将应用安装到保护目录 /mnt/asec; -r:允许覆盖安装; -t:允许安装 AndroidManifest.xml 里 application 指定 android:testOnly=“true” 的应用; -s:将应用安装到 sdcard; -d:允许降级覆盖安装; -g:授予所有运行时权限; path_to_apk:apk的绝对路径。 示例安装淘宝apk:adb install -l /data/local/tmp/taobao.apk 卸载apk:adb uninstall -k “packagename” “packagename”:表示应用的包名,以下相同; -k 参数可选,表示卸载应用但保留数据和缓存目录。 示例卸载 手机淘宝:adb uninstall com.taobao.taobao 清除应用数据与缓存命令:adb shell pm clear “packagename” 相当于在设置里的应用信息界面点击「清除缓存」和「清除数据」。 示例:adb shell pm clear com.taobao.taobao 表示清除 手机淘宝数据和缓存。 Android四大组件有Activity,Service服务,Content Provider内容提供,BroadcastReceiver广播接收器,具体不做多讲,常用的有以下: 查看前台 Activity命令:adb shell dumpsys activity activities | grep mFocusedActivity 查看正在运行的 Services命令:adb shell dumpsys activity services “packagename” 其中参数不是必须的,指定 “packagename” 表示查看与某个包名相关的 Services,不指定表示查看所有 Services。 查看应用详细信息命令:adb shell dumpsys package “packagename” 调起 Activity命令格式:adb shell am start [options] 例如:adb shell am start -n com.tencent.mm/.ui.LauncherUI表示调起微信主界面 调起 Service命令格式:adb shell am startservice [options] 例如:adb shell am startservice -n com.tencent.mm/.plugin.accountsync.model.AccountAuthenticatorService 表示调起微信的某 Service。 强制停止应用命令:adb shell am force-stop “packagename” 例如强制停止淘宝:adb shell am force-stop com.taobao.taobao 模拟按键/输入:adb shell input keyevent keycode 不同的 keycode有不同的功能: keycode 含义 3 HOME 键 4 返回键 5 打开拨号应用 6 挂断电话 26 电源键 27 拍照(需要在相机应用里) 61 Tab键 64 打开浏览器 67 退格键 80 拍照对焦键 82 菜单键 85 播放/暂停 86 停止播放 92 向上翻页键 93 向下翻页键 111 ESC键 112 删除键 122 移动光标到行首或列表顶部 123 移动光标到行末或列表底部 124 插入键 164 静音 176 打开系统设置 207 打开联系人 208 打开日历 209 打开音乐 220 降低屏幕亮度 221 提高屏幕亮度 223 系统休眠 224 点亮屏幕 224 点亮屏幕 224 点亮屏幕 231 打开语音助手 276 如果没有 wakelock 则让系统休眠 滑动解锁:如果锁屏没有密码,是通过滑动手势解锁,那么可以通过 input swipe 来解锁。 命令:adb shell input swipe 300 1000 300 500 (其中参数 300 1000 300 500 分别表示起始点x坐标 起始点y坐标 结束点x坐标 结束点y坐标。) 输入文本:在焦点处于某文本框时,可以通过 input 命令来输入文本。 命令:adb shell input text *** (***即为输入内容) 打印日志: Android 的日志分为如下几个优先级(priority): V —— Verbose(最低,输出得最多) D —— Debug I —— Info W —— Warning E —— Error F—— Fatal S —— Silent(最高,啥也不输出) 按某级别过滤日志则会将该级别及以上的日志输出。 比如,命令:adb logcat *:W 会将 Warning、Error、Fatal 和 Silent 日志输出。 (注: 在 macOS 下需要给 :W 这样以 作为 tag 的参数加双引号,如 adb logcat “:W”,不然会报错 no matches found: :W。) adb logcat 打印当前设备上所有日志 adb logcat :W 过滤打印严重级别W及以上的日志 adb logcat l findstr ***> F:\log.txt 把仅含的日志保存到F盘的log.txt文件中 adb logcat -c 清除屏幕上的日志记录 adb logcat -c && adb logcat -s ActivityManager l grep "Displayed” 客户端程序启动时间获取日志 adb logcat > F:\log.txt 打印当前设备上所有日志保存到F盘的log.txt文件中 adb logcat l findstr *** 打印过滤仅含的日志 adb logcat l findstr ***> F:\log.txt 把仅含**的日志保存到F盘的log.txt文件中 按 tag 和级别过滤日志:命令:adb logcat ActivityManager:I MyApp:D *:S 表示输出 tag ActivityManager 的 Info 以上级别日志,输出 tag MyApp 的 Debug 以上级别日志,及其它 tag 的 Silent 级别日志(即屏蔽其它 tag 日志)。 日志格式可以用:adb logcat -v 选项指定日志输出格式。 日志支持按以下几种 :默认格式brief、process、tag、raw、time、long 指定格式可与上面的过滤同时使用。比如:adb logcat -v long ActivityManager:I *:S 清空日志:adb logcat -c 内核日志:adb shell dmesg 查看设备情况: 查看设备信息型号命令:adb shell getprop ro.product.model 电池状况命令:adb shell dumpsys battery 屏幕分辨率命令:adb shell wm size 如果使用命令修改过,那输出可能是: Physical size: 1080x1920 Override size: 480x1024 表明设备的屏幕分辨率原本是 1080px * 1920px,当前被修改为 480px * 1024px。 屏幕密度命令:adb shell wm density 如果使用命令修改过,那输出可能是: Physical density: 480 Override density: 160 表明设备的屏幕密度原来是 480dpi,当前被修改为 160dpi。 显示屏参数:adb shell dumpsys window displays 输出示例: WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays) Display: mDisplayId=0 init=1080x1920 420dpi cur=1080x1920 app=1080x1794 rng=1080x1017-1810x1731 deferred=false layoutNeeded=false 其中 mDisplayId 为 显示屏编号,init 是初始分辨率和屏幕密度,app 的高度比 init 里的要小,表示屏幕底部有虚拟按键,高度为 1920 - 1794 = 126px 合 42dp。 android_id查看命令:adb shell settings get secure android_id 查看Android 系统版本:adb shell getprop ro.build.version.release 查看设备ip地址:adb shell ifconfig | grep Mask或者adb shell netcfg 查看CPU 信息命令:adb shell cat /proc/cpuinfo 查看内存信息命令:adb shell cat /proc/meminfo 更多硬件与系统属性: 设备的更多硬件与系统属性可以通过如下命令查看:adb shell cat /system/build.prop 单独查看某一硬件或系统属性:adb shell getprop <属性名> 属性名 含义 ro.build.version.sdk SDK 版本 ro.build.version.release Android 系统版本 ro.product.model 型号 ro.product.brand 品牌 ro.product.name 设备名 ro.product.board 处理器型号 persist.sys.isUsbOtgEnabled 是否支持 OTG dalvik.vm.heapsize 每个应用程序的内存上限 ro.sf.lcd_density 屏幕密度 rro.build.version.security_patch Android 安全补丁程序级别 修改设置: 修改设置之后,运行恢复命令有可能显示仍然不太正常,可以运行 adb reboot 重启设备,或手动重启。 修改设置的原理主要是通过 settings 命令修改 /data/data/com.android.providers.settings/databases/settings.db 里存放的设置值。 修改分辨率命令:adb shell wm size 480x1024 恢复原分辨率命令:adb shell wm size reset 修改屏幕密度命令:adb shell wm density 160 表示将屏幕密度修改为 160dpi;恢复原屏幕密度命令:adb shell wm density reset 修改显示区域命令:adb shell wm overscan 0,0,0,200 四个数字分别表示距离左、上、右、下边缘的留白像素,以上命令表示将屏幕底部 200px 留白。恢复原显示区域命令:adb shell wm overscan reset 关闭 USB 调试模式命令:adb shell settings put global adb_enabled 0 需要手动恢复:「设置」-「开发者选项」-「Android 调试」 状态栏和导航栏的显示隐藏:adb shell settings put global policy_control 可由如下几种键及其对应的值组成,格式为 =:=。 key 含义 immersive.full 同时隐藏 immersive.status 隐藏状态栏 immersive.navigation 隐藏导航栏 immersive.preconfirms ? 这些键对应的值可则如下值用逗号组合: value 含义 apps 所有应用 * 所有界面 packagename 指定应用 -packagename 排除指定应用 举例:adb shell settings put global policy_control immersive.full=* 表示设置在所有界面下都同时隐藏状态栏和导航栏。 举例:adb shell settings put global policy_control immersive.status=com.package1,com.package2:immersive.navigation=apps,-com.package3 表示设置在包名为 com.package1 和 com.package2 的应用里隐藏状态栏,在除了包名为 com.package3 的所有应用里隐藏导航栏。 恢复正常模式:adb shell settings put global policy_control null 实用功能: 截图保存到电脑:adb exec-out screencap -p > sc.png 然后将 png 文件导出到电脑:adb pull /sdcard/sc.png 录制屏幕:录制屏幕以 mp4 格式保存到 /sdcard:adb shell screenrecord /sdcard/filename.mp4 需要停止时按 Ctrl-C,默认录制时间和最长录制时间都是 180 秒。 如果需要导出到电脑:adb pull /sdcard/filename.mp4 挂载、查看连接过的 WiFi 密码、开启/关闭 WiFi、设置系统日期和时间都需要root权限,不做多说。 使用 Monkey 进行压力测试:Monkey 可以生成伪随机用户事件来模拟单击、触摸、手势等操作,可以对正在开发中的程序进行随机压力测试。 简单用法:adb shell monkey -p < packagename > -v 500 表示向 指定的应用程序发送 500 个伪随机事件。 查看进程:adb shell ps 查看实时资源占用情况:adb shell top 查看进程 UID:adb shell dumpsys package | grep userId=

问问小秘 2020-04-29 15:55:55 0 浏览量 回答数 0

问题

Android 最火的快速开发框架XUtils? 400 报错

爱吃鱼的程序员 2020-05-30 23:44:57 0 浏览量 回答数 1

回答

  开发者们都知道在高端智能手机系统中有两种应用程序:一种是基于本地(操作系统)运行的APP;一种是基于高端机的浏览器运行的WebApp,本文将主要讲解后者。   WebApp与Native App有何区别呢?   Native App:   1、开发成本非常大。   一般使用的开发语言为JAVA、C++、Objective-C。   2、更新体验较差、同时也比较麻烦   每一次发布新的版本,都需要做版本打包,且需要用户手动更新(有些应用程序即使不需要用户手动更新,但是也需要有一个恶心的提示)。   3、非常酷   因为native app可以调用IOS中的UI控件以UI方法,它可以实现WebApp无法实现的一些非常酷的交互效果   4、Native app是被Apple认可的   Native app可以被Apple认可为一款可信任的独立软件,可以放在Apple Stroe出售,但是Web app却不行。   Web App:   1、开发成本较低   使用web开发技术就可以轻松的完成web app的开发   2、升级较简单   升级不需要通知用户,在服务端更新文件即可,用户完全没有感觉   3、维护比较轻松   和一般的web一样,维护比较简单,它其实就是一个站点   Webapp说白了就是一个针对Iphone、Android优化后的web站点,它使用的技术无非就是HTML或HTML5、CSS3、JavaScript,服务端技术JAVA、PHP、ASP。   当然,因为这些高端智能手机(Iphone、Android)的内置浏览器都是基于webkit内核的,所以在开发WEBAPP时,多数都是使用HTML5和CSS3技术做UI布局。当使用HTML5和CSS3l做UI时,若还是遵循着一般web开发中使用HTML4和CSS2那样的开发方式的话,这也就失去了WEBAPP的本质意义了,且有些效果也无法实现的,所以在此又回到了我们的主题–webapp的布局方式和技术。   哥在此说明一下,在此所说的移动平台前端开发是指针对高端智能手机(如Iphone、Android)做站点适配也就是WebApp,并非是针对普通手机开发Wap 2.0,所以在阅读本篇文章以前,你需要对webkit内核的浏览器有一定的了解,你需要对HTML5和CSS3有一定的了解。如果你已经对此有所了解,那现在就开始往下阅读吧……   1、首先我们来看看webkit内核中的一些私有的meta标签,这些meta标签在开发webapp时起到非常重要的作用   1   <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport" />   2   <meta content="yes" name="apple-mobile-web-app-capable" />   3   <meta content="black" name="apple-mobile-web-app-status-bar-style" />   4   <meta content="telephone=no" name="format-detection" />      第一个meta标签表示:强制让文档的宽度与设备的宽度保持1:1,并且文档最大的宽度比例是1.0,且不允许用户点击屏幕放大浏览;   第二个meta标签是iphone设备中的safari私有meta标签,它表示:允许全屏模式浏览;   第三个meta标签也是iphone的私有标签,它指定的iphone中safari顶端的状态条的样式;   第四个meta标签表示:告诉设备忽略将页面中的数字识别为电话号码   2、HTML5标签的使用   在开始编写webapp时,哥建议前端工程师使用HTML5,而放弃HTML4,因为HTML5可以实现一些HTML4中无法实现的丰富的WEB应用程序的体验,可以减少开发者很多的工作量,当然了你决定使用HTML5前,一定要对此非常熟悉,要知道HTML5的新标签的作用。比如定义一块内容或文章区域可使用section标签,定义导航条或选项卡可以直接使用nav标签等等。   3、放弃CSS float属性   在项目开发过程中可以会遇到内容排列排列显示的布局(见下图),假如你遇见这样的视觉稿,哥建议你放弃float,可以直接使用display:block;   4、利用CSS3边框背景属性   这个按钮有圆角效果,有内发光效果还有高光效果,这样的按钮使用CSS3写是无法写出来的,当然圆角可以使用CSS3来写,但高光和内发光却无法使用CSS3编写,   这个时候你不妨使用-webkit-border-image来定义这个按钮的样式。   -webkit-border-image就个很复杂的样式属性。   5、块级化a标签   请保证将每条数据都放在一个a标签中,为何这样做?因为在触控手机上,为提升用户体验,尽可能的保证用户的可点击区域较大。   6、自适应布局模式   在编写CSS时,我不建议前端工程师把容器(不管是外层容器还是内层)的宽度定死。为达到适配各种手持设备,我建议前端工程师使用自适应布局模式(支付宝采用了自适应布局模式),因为这样做可以让你的页面在ipad、itouch、ipod、iphone、android、web safarik、chrome都能够正常的显示,你无需再次考虑设备的分辨率。      7、学会使用webkit-box   上一节,我们说过自适应布局模式,有些同学可能会问:如何在移动设备上做到完全自适应呢?很感谢webkit为display属性提供了一个webkit-box的值,它可以帮助前端工程师做到盒子模型灵活控制。   8、如何去除Android平台中对邮箱地址的识别   看过iOS webapp API的同学都知道iOS提供了一个meta标签:用于禁用iOS对页面中电话号码的自动识别。在iOS中是不自动识别邮件地址的,但在Android平台,它会自动检测邮件地址,当用户touch到这个邮件地址时,Android会弹出一个框提示用户发送邮件,如果你不想Android自动识别页面中的邮件地址,你不妨加上这样一句meta标签在head中   1   <meta content="email=no" name="format-detection" />      9、如何去除iOS和Android中的输入URL的控件条   你的老板或者PD或者交互设计师可能会要求你:能否让我们的webapp更加像nativeapp,我不想让用户看见那个输入url的控件条?   答案是可以做到的。我们可以利用一句简单的javascript代码来实现这个效果   1   setTimeout(scrollTo,0,0,0);      请注意,这句代码必须放在window.onload里才能够正常的工作,而且你的当前文档的内容高度必须是高于窗口的高度时,这句代码才能有效的执行。   10、如何禁止用户旋转设备   我曾经也想禁止用户旋转设备,也想实现像某些客户端那样:只能在肖像模式或景观模式下才能正常运行。但现在我可以很负责任的告诉你:别想了!在移动版的webkit中做不到!   至少Apple webapp API已经说到了:我们为了让用户在safari中正常的浏览网页,我们必须保证用户的设备处于任何一个方位时,safari都能够正常的显示网页内容(也就是自适应),所以我们禁止开发者阻止浏览器的orientationchange事件,看来苹果公司的出发点是正确的,苹果确实不是一般的苹果。   iOS已经禁止开发者阻止orientationchange事件,那Android呢?对不起,我没有找到任何资料说Android禁止开发者阻止浏览器orientationchange事件,但是在Android平台,确实也是阻止不了的。   11、如何检测用户是通过主屏启动你的webapp   看过Apple webapp API的同学都知道iOS为safari提供了一个将当前页面添加主屏的功能,按下iphoneipodipod touch底部工具中的小加号,或者ipad顶部左侧的小加号,就可以将当前的页面添加到设备的主屏,在设备的主屏会自动增加一个当前页面的启动图标,点击该启动图标就可以快速、便捷的启动你的webapp。从主屏启动的webapp和浏览器访问你的webapp最大的区别是它清除了浏览器上方和下方的工具条,这样你的webapp就更加像是nativeapp了,还有一个区别是window对像中的navigator子对象的一个standalone属性。iOS中浏览器直接访问站点时,navigator.standalone为false,从主屏启动webapp时,navigator.standalone为true, 我们可以通过navigator.standalone这个属性获知用户当前是否是从主屏访问我们的webapp的。   在Android中从来没有添加到主屏这回事!   12、如何关闭iOS中键盘自动大写   我们知道在iOS中,当虚拟键盘弹出时,默认情况下键盘是开启首字母大写的功能的,根据某些业务场景,可能我们需要关闭这个功能,移动版本webkit为input元素提供了autocapitalize属性,通过指定autocapitalize=”off”来关闭键盘默认首字母大写。      13、iOS中如何彻底禁止用户在新窗口打开页面   有时我们可能需要禁止用户在新窗口打开页面,我们可以使用a标签的target=”_self“来指定用户在新窗口打开,或者target属性保持空,但是你会发现iOS的用户在这个链接的上方长按3秒钟后,iOS会弹出一个列表按钮,用户通过这些按钮仍然可以在新窗口打开页面,这样的话,开发者指定的target属性就失效了,但是可以通过指定当前元素的-webkit-touch-callout样式属性为none来禁止iOS弹出这些按钮。这个技巧仅适用iOS对于Android平台则无效。   14、iOS中如何禁止用户保存图片\复制图片   我们在第13条技巧中提到元素的-webkit-touch-callout属性,同样为一个img标签指定-webkit-touch-callout为none也会禁止设备弹出列表按钮,这样用户就无法保存\复制你的图片了。   15、iOS中如何禁止用户选中文字   我们通过指定文字标签的-webkit-user-select属性为none便可以禁止iOS用户选中文字。   16、iOS中如何获取滚动条的值   桌面浏览器中想要获取滚动条的值是通过document.scrollTop和document.scrollLeft得到的,但在iOS中你会发现这两个属性是未定义的,为什么呢?因为在iOS中没有滚动条的概念,在Android中通过这两个属性可以正常获取到滚动条的值,那么在iOS中我们该如何获取滚动条的值呢?   通过window.scrollY和window.scrollX我们可以得到当前窗口的y轴和x轴滚动条的值。   17、如何解决盒子边框溢出   当你指定了一个块级元素时,并且为其定义了边框,设置了其宽度为100%。在移动设备开发过程中我们通常会对文本框定义为宽度100%,将其定义为块级元素以实现全屏自适应的样式,但此时你会发现,该元素的边框(左右)各1个像素会溢了文档,导致出现横向滚动条,为解决这一问题,我们可以为其添加一个特殊的样式-webkit-box-sizing:border-box;用来指定该盒子的大小包括边框的宽度。   18、如何解决Android 2.0以下平台中圆角的问题   如果大家够细心的话,在做wap站点开发时,大家应该会发现android 2.0以下的平台中问题特别的多,比如说边框圆角这个问题吧。   在对一个元素定义圆角时,为完全兼容android 2.0以下的平台,我们必须要按照以下技巧来定义边框圆角:   1\-webkit这个前缀必须要加上(在iOS中,你可以不加,但android中一定要加);   2\如果对针对边框做样式定义,比如border:1px solid #000;那么-webkit-border-radius这属性必须要出现在border属性后。   3\假如我们有这样的视觉元素,左上角和右上角是圆角时,我们必须要先定义全局的(4个角的圆角值)-webkit-border-radius:5px;然后再依次的覆盖左下角和右下角,-webkit-border-bottom-left-radius:0;-webkit-border-bottom-right-border:0;否则在android 2.0以下的平台中将全部显示直角,还有记住!-webkit这个前缀一定要加上!   19、如何解决android平台中页面无法自适应   虽然你的html和css都是完全自适应的,但有一天如果你发现你的页面在android中显示的并不是自适应的时候,首先请你确认你的head标签中是否包含以下meta标签:   1   <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0;" />      如果有的话,那请你再仔细的看清楚有没有这个属性的值width=device-width,如果没有请立即加上吧!   20、如何解决iOS 4.3版本中safari对页面中5位数字的自动识别和自动添加样式   新的iOS系统也就是4.3版本,升级后对safari造成了一个bug:即使你添加了如下的meta标签,safari仍然会对页面中的5位连续的数字进行自动识别,并且将其重新渲染样式,也就是说你的css对该标签是无效的。   1   <meta name="format-detection" content="telphone=no" />      我们可以用一个比较龌龊的办法来解决。比如说支付宝wap站点中显示金额的标签,我们都做了如下改写:   1   <button class="t-balance"style="background:none;padding:0;border:0;">95009.00</button>元    “答案来源于网络,供您参考” 希望以上信息可以帮到您!

牧明 2019-12-02 02:17:31 0 浏览量 回答数 0

回答

一 系统介绍 Android 是Google开发的基于Linux平台的、开源的、智能手机操作系统。Android包括操作系统、中间件和应用程序,由于源代码开放,Android可以被移植到不同的硬件平台上。 围绕在Google的Android系统中,形成了移植开发和上层应用程序开发两个不同的开发方面。手机厂商从事移植开发工作,上层的应用程序开发可以由任何单位和个人完成,开发的过程可以基于真实的硬件系统,还可以基于仿真器环境。 作为一个手机平台,Android在技术上的优势主要有以下几点: - 全开放智能手机平台 - 多硬件平台的支持 - 使用众多的标准化技术 - 核心技术完整,统一 - 完善的SDK和文档 - 完善的辅助开发工具 Android的开发者可以在完备的开发环境中进行开发,Android的官方网站也提供了丰富的文档、资料。这样有利于Android系统的开发和运行在一个良好的生态环境中。 https://developer.android.com/about安卓开发者官方网站 从宏观的角度来看,Android是一个开放的软件系统,它包含了众多的源代码。从下至上,Android系统分成4个层次: 第1层次:Linux操作系统及驱动; 第2层次:本地代码(C/C++)框架; 第3层次:Java框架; 第4层次:Java应用程序。 Android系统的架构如图所示: 由于Android系统需要支持Java代码的运行,这部分内容是Android的运行环境(Runtime),由虚拟机和Java基本类组成。 对于Android应用程序的开发,主要关注第3层次和第4层次之间的接口。 二 学习路线 基础学习——JavaSE: 基础学习扩展——JavaEE: 基础学习扩展——Linux基础: Android开发学习——基础理论:系统架构分析: Android系统从底向上一共分了4层,每一层都把底层实现封装,并暴露调用接口给上一层。 Linux内核(Linux Kernel) Android运行在linux kernel 2.6之上,但是把linux内受GNU协议约束的部分做了取代,这样在Android的程序可以用于商业目的。 Linux 内核是硬件和软件层之间的抽象层。 中间件 中间件包括两部分: 核心库和运行时(libraries & Android runtime) 核心库包括,SurfaceManager 显示系统管理库,负责把2D或3D内容显示到屏幕;Media Framework 媒体库,负责支持图像,支持多种视频和音频的录制和回放;SQlite 数据库,一个功能强大的轻量级嵌入式关系数据库;WebKit 浏览器引擎等。 Dalvik虚拟机: 区别于Java虚拟机的是,每一个Android 应用程序都在它自己的进程中运行,都有一个属于自己的Dalvik 虚拟机,这一点可以让系统在运行时可以达到优化,程序间的影响大大降低。Dalvik虚拟机并非运行Java字节码,而是运行自己的字节码。 应用程序框架(Application Framework) 丰富而又可扩展性的视图(Views),可以用来构建应用程序, 它包括列表(lists),网格(grids), 文本框(text boxes),按钮( buttons), 可嵌入的web 浏览器。内容提供者(Content Providers)使得应用程序可以访问另一个应用程序的数据(如联系人数据库), 或者共享它们自己的数据。资源管理器(Resource Manager)提供非代码资源的访问,如本地字符串,图形,和布局文件( layoutfiles )。通知管理器(Notification Manager) 使得应用程序可以在状态栏中显示自定义的提示信息。活动管理器( Activity Manager) 用来管理应用程序生命周期并提供常用的导航回退功能。 三 基础知识 掌握java部分之后,可以使用开发工具进入android世界 您可以使用 Kotlin、Java 和 C++ 语言编写 Android 应用。Android SDK 工具会将您的代码连同任何数据和资源文件编译成一个 APK(Android 软件包),即带有 .apk 后缀的归档文件。一个 APK 文件包含 Android 应用的所有内容,它也是 Android 设备用来安装应用的文件。 每个 Android 应用都处于各自的安全沙盒中,并受以下 Android 安全功能的保护: • Android 操作系统是一种多用户 Linux 系统,其中的每个应用都是一个不同的用户; • 默认情况下,系统会为每个应用分配一个唯一的 Linux 用户 ID(该 ID 仅由系统使用,应用并不知晓)。系统会为应用中的所有文件设置权限,使得只有分配给该应用的用户 ID 才能访问这些文件; • 每个进程都拥有自己的虚拟机 (VM),因此应用代码独立于其他应用而运行。 • 默认情况下,每个应用都在其自己的 Linux 进程内运行。Android 系统会在需要执行任何应用组件时启动该进程,然后当不再需要该进程或系统必须为其他应用恢复内存时,其便会关闭该进程。 Android 系统实现了最小权限原则。换言之,默认情况下,每个应用只能访问执行其工作所需的组件,而不能访问其他组件。这样便能创建非常安全的环境,在此环境中,应用无法访问其未获得权限的系统部分。不过,应用仍可通过一些途径与其他应用共享数据以及访问系统服务: • 可以安排两个应用共享同一 Linux 用户 ID,在此情况下,二者便能访问彼此的文件。为节省系统资源,也可安排拥有相同用户 ID 的应用在同一 Linux 进程中运行,并共享同一 VM。应用还必须使用相同的证书进行签名。 • 应用可以请求访问设备数据(如用户的联系人、短信消息、可装载存储装置(SD 卡)、相机、蓝牙等)的权限。用户必须明确授予这些权限。如需了解详细信息,请参阅使用系统权限。 本文档的其余部分将介绍以下概念: • 用于定义应用的核心框架组件 • 用来声明组件和应用必需设备功能的清单文件。 • 与应用代码分离并允许应用针对各种设备配置适当优化其行为的资源。 应用组件 应用组件是 Android 应用的基本构建块。每个组件都是一个入口点,系统或用户可通过该入口点进入您的应用。有些组件会依赖于其他组件。 共有四种不同的应用组件类型: • Activity • 服务 • 广播接收器 • 内容提供程序 每种类型都有不同的用途和生命周期,后者会定义如何创建和销毁组件。以下部分将介绍应用组件的四种类型。 Activity Activity 是与用户交互的入口点。它表示拥有界面的单个屏幕。例如,电子邮件应用可能有一个显示新电子邮件列表的 Activity、一个用于撰写电子邮件的 Activity 以及一个用于阅读电子邮件的 Activity。尽管这些 Activity 通过协作在电子邮件应用中形成一种紧密结合的用户体验,但每个 Activity 都独立于其他 Activity 而存在。因此,其他应用可以启动其中任何一个 Activity(如果电子邮件应用允许)。例如,相机应用可以启动电子邮件应用内用于撰写新电子邮件的 Activity,以便用户共享图片。Activity 有助于完成系统和应用程序之间的以下重要交互: • 追踪用户当前关心的内容(屏幕上显示的内容),以确保系统继续运行托管 Activity 的进程。 • 了解先前使用的进程包含用户可能返回的内容(已停止的 Activity),从而更优先保留这些进程。 • 帮助应用处理终止其进程的情况,以便用户可以返回已恢复其先前状态的 Activity。 • 提供一种途径,让应用实现彼此之间的用户流,并让系统协调这些用户流。(此处最经典的示例是共享。) 您需将 Activity 作为 Activity 类的子类来实现。如需了解有关 Activity 类的更多信息,请参阅 Activity 开发者指南。 服务 服务是一个通用入口点,用于因各种原因使应用在后台保持运行状态。它是一种在后台运行的组件,用于执行长时间运行的操作或为远程进程执行作业。服务不提供界面。例如,当用户使用其他应用时,服务可能会在后台播放音乐或通过网络获取数据,但这不会阻断用户与 Activity 的交互。诸如 Activity 等其他组件可以启动服务,使该服务运行或绑定到该服务,以便与其进行交互。事实上,有两种截然不同的语义服务可以告知系统如何管理应用:已启动服务会告知系统使其运行至工作完毕。此类工作可以是在后台同步一些数据,或者在用户离开应用后继续播放音乐。在后台同步数据或播放音乐也代表了两种不同类型的已启动服务,而这些服务可以修改系统处理它们的方式: • 音乐播放是用户可直接感知的服务,因此,应用会向用户发送通知,表明其希望成为前台,从而告诉系统此消息;在此情况下,系统明白它应尽全力维持该服务进程运行,因为进程消失会令用户感到不快。 • 通常,用户不会意识到常规后台服务正处于运行状态,因此系统可以更自由地管理其进程。如果系统需要使用 RAM 来处理用户更迫切关注的内容,则其可能允许终止服务(然后在稍后的某个时刻重启服务)。 绑定服务之所以能运行,原因是某些其他应用(或系统)已表示希望使用该服务。从根本上讲,这是为另一个进程提供 API 的服务。因此,系统会知晓这些进程之间存在依赖关系,所以如果进程 A 绑定到进程 B 中的服务,系统便知道自己需使进程 B(及其服务)为进程 A 保持运行状态。此外,如果进程 A 是用户关心的内容,系统随即也知道将进程 B 视为用户关心的内容。由于存在灵活性(无论好坏),服务已成为非常有用的构建块,并且可实现各种高级系统概念。动态壁纸、通知侦听器、屏幕保护程序、输入方法、无障碍功能服务以及众多其他核心系统功能均可构建为在其运行时由应用实现、系统绑定的服务。 您需将服务作为 Service 的子类来实现。如需了解有关 Service 类的更多信息,请参阅服务开发者指南。 注意:如果您的应用面向 Android 5.0(API 级别 21)或更高版本,请使用 JobScheduler 类来调度操作。JobScheduler 的优势在于,它能通过优化作业调度来降低功耗,以及使用 Doze API,从而达到省电目的。如需了解有关使用此类的更多信息,请参阅 JobScheduler 参考文档。 广播接收器 借助广播接收器组件,系统能够在常规用户流之外向应用传递事件,从而允许应用响应系统范围内的广播通知。由于广播接收器是另一个明确定义的应用入口,因此系统甚至可以向当前未运行的应用传递广播。例如,应用可通过调度提醒来发布通知,以告知用户即将发生的事件。而且,通过将该提醒传递给应用的广播接收器,应用在提醒响起之前即无需继续运行。 许多广播均由系统发起,例如,通知屏幕已关闭、电池电量不足或已拍摄照片的广播。应用也可发起广播,例如,通知其他应用某些数据已下载至设备,并且可供其使用。尽管广播接收器不会显示界面,但其可以创建状态栏通知,在发生广播事件时提醒用户。但广播接收器更常见的用途只是作为通向其他组件的通道,旨在执行极少量的工作。例如,它可能会根据带 JobScheduler 的事件调度 JobService 来执行某项工作 广播接收器作为 BroadcastReceiver 的子类实现,并且每条广播都作为 Intent 对象进行传递。如需了解详细信息,请参阅 BroadcastReceiver 类。 内容提供程序 内容提供程序管理一组共享的应用数据,您可以将这些数据存储在文件系统、SQLite 数据库、网络中或者您的应用可访问的任何其他持久化存储位置。其他应用可通过内容提供程序查询或修改数据(如果内容提供程序允许)。例如,Android 系统可提供管理用户联系人信息的内容提供程序。 因此,任何拥有适当权限的应用均可查询内容提供程序(如 ContactsContract.Data),以读取和写入特定人员的相关信息。我们很容易将内容提供程序看作数据库上的抽象,因为其内置的大量 API 和支持时常适用于这一情况。但从系统设计的角度看,二者的核心目的不同。对系统而言,内容提供程序是应用的入口点,用于发布由 URI 架构识别的已命名数据项。因此,应用可以决定如何将其包含的数据映射到 URI 命名空间,进而将这些 URI 分发给其他实体。反之,这些实体也可使用分发的 URI 来访问数据。在管理应用的过程中,系统可以执行以下特殊操作: • 分配 URI 无需应用保持运行状态,因此 URI 可在其所属的应用退出后继续保留。当系统必须从相应的 URI 检索应用数据时,系统只需确保所属应用仍处于运行状态。 • 这些 URI 还会提供重要的细粒度安全模型。例如,应用可将其所拥有图像的 URI 放到剪贴板上,但将其内容提供程序锁定,以便其他应用程序无法随意访问它。当第二个应用尝试访问剪贴板上的 URI 时,系统可允许该应用通过临时的 URI 授权来访问数据,这样便只能访问 URI 后面的数据,而非第二个应用中的其他任何内容。 内容提供程序也适用于读取和写入您的应用不共享的私有数据。 内容提供程序作为 ContentProvider 的子类实现,并且其必须实现一组标准 API,以便其他应用能够执行事务。如需了解详细信息,请参阅内容提供程序开发者指南。 Android 系统设计的独特之处在于,任何应用都可启动其他应用的组件。例如,当您想让用户使用设备相机拍摄照片时,另一个应用可能也可执行该操作,因而您的应用便可使用该应用,而非自行产生一个 Activity 来拍摄照片。您无需加入甚至链接到该相机应用的代码。只需启动拍摄照片的相机应用中的 Activity 即可。完成拍摄时,系统甚至会将照片返回您的应用,以便您使用。对用户而言,这就如同相机是您应用的一部分。 当系统启动某个组件时,它会启动该应用的进程(如果尚未运行),并实例化该组件所需的类。例如,如果您的应用启动相机应用中拍摄照片的 Activity,则该 Activity 会在属于相机应用的进程(而非您的应用进程)中运行。因此,与大多数其他系统上的应用不同,Android 应用并没有单个入口点(即没有 main() 函数)。 由于系统在单独的进程中运行每个应用,且其文件权限会限制对其他应用的访问,因此您的应用无法直接启动其他应用中的组件,但 Android 系统可以。如要启动其他应用中的组件,请向系统传递一条消息,说明启动特定组件的 Intent。系统随后便会为您启动该组件。 启动组件 在四种组件类型中,有三种(Activity、服务和广播接收器)均通过异步消息 Intent 进行启动。Intent 会在运行时对各个组件进行互相绑定。您可以将 Intent 视为从其他组件(无论该组件是属于您的应用还是其他应用)请求操作的信使。 您需使用 Intent 对象创建 Intent,该对象通过定义消息来启动特定组件(显式 Intent)或特定的组件类型(隐式 Intent)。 对于 Activity 和服务,Intent 会定义要执行的操作(例如,查看或发送某内容),并且可指定待操作数据的 URI,以及正在启动的组件可能需要了解的信息。例如,Intent 可能会传达对 Activity 的请求,以便显示图像或打开网页。在某些情况下,您可以通过启动 Activity 来接收结果,这样 Activity 还会返回 Intent 中的结果。例如,您可以发出一个 Intent,让用户选取某位联系人并将其返回给您。返回 Intent 包含指向所选联系人的 URI。 对于广播接收器,Intent 只会定义待广播的通知。例如,指示设备电池电量不足的广播只包含指示“电池电量不足”的已知操作字符串。 与 Activity、服务和广播接收器不同,内容提供程序并非由 Intent 启动。相反,它们会在成为 ContentResolver 的请求目标时启动。内容解析程序会通过内容提供程序处理所有直接事务,因此通过提供程序执行事务的组件便无需执行事务,而是改为在 ContentResolver 对象上调用方法。这会在内容提供程序与请求信息的组件之间留出一个抽象层(以确保安全)。 每种组件都有不同的启动方法: • 如要启动 Activity,您可以向 startActivity() 或 startActivityForResult() 传递 Intent(当您想让 Activity 返回结果时),或者为其安排新任务。 • 在 Android 5.0(API 级别 21)及更高版本中,您可以使用 JobScheduler 类来调度操作。对于早期 Android 版本,您可以通过向 startService() 传递 Intent 来启动服务(或对执行中的服务下达新指令)。您也可通过向将 bindService() 传递 Intent 来绑定到该服务。 • 您可以通过向 sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast() 等方法传递 Intent 来发起广播。 • 您可以通过在 ContentResolver 上调用 query(),对内容提供程序执行查询。 如需了解有关 Intent 用法的详细信息,请参阅 Intent 和 Intent 过滤器文档。以下文档将为您详细介绍如何启动特定组件:Activity、服务、BroadcastReceiver 和内容提供程序。

问问小秘 2020-03-03 09:47:38 0 浏览量 回答数 0

问题

【javascript学习全家桶】934道javascript热门问题,阿里百位技术专家答疑解惑

管理贝贝 2019-12-01 20:07:22 6202 浏览量 回答数 1

回答

HTML + CSS 前端的入门门槛极低,体现在HTML和CSS上。运行环境就是浏览器,推荐Chrome。你需要的只是一个文本编辑器,推荐Sublime Text 3,有不少好插件比如Emmet,谷歌搜一下很容易了解到的。当然你非要用记事本的话,也不是不行的。刚入门查阅资料可以用 w3school 或者 MDN 。 HTML和CSS不是编程语言,前者只是结构标签,后者则是样式配置,入门是非常简单的。网上资料也有很多,推荐慕课网 HTML+CSS基础课程。 我当时是看了一本书 Head First HTML and CSS,讲得浅显易懂,不过价格比较感人,也是只翻一遍的书,没有必要买了。 迅速刷一遍慕课网,对HTML和CSS有个大致印象就好。想巩固HTML标签可以去看看16年的task1-1。 HTML5的API可以先放一放,回头再看。 接下来就是深入学习CSS了。推荐: 《CSS权威指南(第3版)》。很枯燥的一本书,但我确实不知道哪本书更适合了。花两三天硬啃下来就好了。属性细节不必记忆,以后用到肯定要再查的。着重点放在大局上,比如盒模型,浮动和定位这些,抓住重点快速过一遍。 《CSS3 专业网页开发指南》。CSS3也是需要掌握的内容。但这里还是以了解为主,知道CSS3有什么内容就好,记忆属性是枯燥且毫无意义的。 以上内容用时5天左右,下面是实践。 学了几天HTML和CSS了,应该也有点成果了。打开IFE2015 task1,写个静态页面吧。 我X,完全写不出来。 这是正常的。去看下别人的代码吧,看一小部分就开窍了。忘掉的属性就查书或者w3c,多尝试,不断踩坑才有进步。 画完第一张图后,别着急往下写。你的代码肯定会有如下问题 胡乱的代码缩进毫无章法的属性顺序 满页的div 不停地写id和class重写吧,是的。重写之前先看一份代码规范 GitHub - ecomfe/spec: This repository contains the specifications.。当然代码规范不是唯一的,我最早看的是这一份,所以代码风格也一直维持到现在。 再去看一下别人提交的代码,多看几份。当然自己也要判断,不能听风就是雨啊,人家写得不好你再去重写一次,等于你也有责任对不对。 开始重写了,会发现功力大增,写代码速度也快了很多的。 写到第三张页面的时候,应该比较熟练了。如果看到布局就大概知道应该怎么写了,那就可以进入JavaScript的学习了。 以上内容用时10天左右。 进阶部分可以回头再看: 掌握预处理工具Sass,自动化工具Gulp。 阅读Bootstrap源码。 《CSS揭秘》,极其惊艳的一本书,涵盖了CSS3的很多奇技淫巧,虽说有些地方不太实用,但让人眼前一亮,很值得看。JavaScript 这是至关重要的阶段。 强烈推荐《JavaScript高级程序设计(第3版)》,俗称红宝书。前七章是重中之重,必须反复阅读,直至完全理解,期间可配合其他书一起读。DOM,事件流,表单,JSON,Ajax与最后几章也相当重要。其余章节可以略读或跳过(比如浏览器嗅探,XML以及那些列举大量API的章节,完全可以用到再查) 推荐《JavaScript语言精粹》,俗称蝴蝶书。超薄的一本,半天就可以看完。JavaScript是一门有很多坑的语言,我个人是喜欢把这些坑点全部搞清楚的,但这本书却避而不谈了,剩下的也就是所谓的“精粹”了。但清晰地过一遍知识点总是好的。 强烈推荐《你不知道的JS》。精彩至极的一本书,将JavaScript的坑一网打尽。之前搞不懂的问题,比如闭包,this之类的都可以在这里找到答案。 ES6也是必学的内容,推荐阮一峰老师的《ES6 标准入门》。但这本书以API居多,所以还是留个大概印象,以后写到类似的地方,查一查有没有ES6更简洁的写法就好,不必死记硬背。以及需要学会Webpack的使用,Babel和模块化就靠Webpack了。 不太推荐《JavaScript权威指南》,也就是犀牛书。那就是一本字典…… 进阶: 《JavaScript设计模式与开发实践》,设计模式是必须了解的内容,这本是写得不错的。 《高性能JavaScript》,红宝书作者的另一力作,讲了一些优化技巧与性能瓶颈问题,值得一读。 以上内容用时1个月左右,中途可穿插IFE2015 task2的题,比2016年的要简单。 这些书全部刷完的话,应该可以跟人谈笑风生了。 开始实践,IFE2016阶段二的题,想怎么刷就怎么刷吧。如果有编程经验的话,应该没什么压力了。JavaScript框架 这部分就比较自由了,每个人点的技能树都不一样的。前端的发展是爆炸式的,换工具比翻书还快,所以还是以看文档为主了。 目前主流框架经常被提及的是React,Angular,Vue。知乎搜一搜就有相当多的优秀答案了。不过这个答案也有时效性,说不定过两年这些框架全都被淘汰了呢【逃 学习至少一种框架,把IFE2016刷通关吧。耗时1个半月左右。 进阶:看各种源代码。这也是我最近打算做的事情,但是好像期末考要到了TAT 最后补充一下,计算机基础知识是很重要的。由于本人有OI的经验所以稍微占点优势。再推荐几本书,抽空还是要看看的: 《深入理解计算机系统》,CSAPP,也是我们专业这学期的课程(但是我的专业明明是EE啊)。 《计算机网络 自顶向下方法》,看名字就知道必读了吧。 操作系统好书挺多的,推荐一本 Operating Systems: Three Easy Pieces ,英文不够好就《现代操作系统》吧。 算法和数据结构,推荐两本:《算法导论》《数据结构与算法分析》。似乎算法和数据结构与前端关系不大,但作为一个码农,不要求你写红黑树,至少快速排序和二分查找这种要会写的吧。

1359302247831492 2019-12-02 00:16:32 0 浏览量 回答数 0

回答

前言 前两天在 echarts 上寻找灵感的时候,看到了很多有关地图类似的例子,地图定位等等,但是好像就是没有地铁线路图,就自己花了一些时间捣鼓出来了这个交互式地铁线路图的 Demo,地铁线路上的点是在网上随便下载了一个,这篇文章记录自己的一些收获(毕竟我还是个菜鸟)以及代码的实现,希望能够帮到一些朋友。当然,如果有什么意见的可以直接跟我说,大家一起交流才会进步。 效果图 地图稍微内容有点多,要全部展示,字显得有点小了,但是没关系,可以按照需求放大缩小,字体和绘制的内容并不会失真,毕竟都是用矢量绘制的~ 界面生成 底层的 div 是通过 ht.graph.GraphView 组件生成的,然后就可以利用 HT for Web 提供好的方法,调用 canvas 画笔随便绘制就好,先来看看怎么生成底层 div: var dm = new ht.DataModel();//数据容器 var gv = new ht.graph.GraphView(dm);//拓扑组件 gv.addToDOM();//将拓扑图组件添加进body中 addToDOM 函数声明如下: addToDOM = function(){ var self = this, view = self.getView(), style = view.style; document.body.appendChild(view); //将组件底层div添加到body中 style.left = '0';//默认组件是绝对定位,所以要设置位置 style.right = '0'; style.top = '0'; style.bottom = '0'; window.addEventListener('resize', function () { self.iv(); }, false); //窗口变化事件 } 现在我就可以在这个 div 上乱涂乱画了~首先我获取下载好的地铁线路图上的点,我将它们放在 subway.js 中,这个 js 文件全部都是下载的内容,我没有做其他的改动,主要是将这些点根据线路来分分配添加到数组中,比如: mark_Point13 = [];//线路 数组内包含线路的起点和终点坐标以及这条线路的名称 t_Point13 = [];//换成站点 数组内包含线路中的换乘站点坐标以及换成站点名称 n_Point13 = [];//小站点 数组内包含线路中的小站点坐标以及小站点名称 mark_Point13.push({ name: '十三号线', value: [113.4973,23.1095]}); mark_Point13.push({ name: '十三号线', value: [113.4155,23.1080]}); t_Point13.push({ name: '鱼珠', value: [113.41548,23.10547]}); n_Point13.push({ name: '裕丰围', value: [113.41548,23.10004]}); 接下来来描绘地铁线路,我声明了一个数组 lineNum,用来装 js 中所有的地铁线路的编号,以及一个 color 数组,用来装所有的地铁线的颜色,这些颜色的 index 与 lineNum 中地铁线编号的 index 是一一对应的: var lineNum = ['1', '2', '3', '30', '4', '5', '6', '7', '8', '9', '13', '14', '32', '18', '21', '22', '60', '68']; var color = ['#f1cd44', '#0060a1', '#ed9b4f', '#ed9b4f', '#007e3a', '#cb0447', '#7a1a57', '#18472c', '#008193', '#83c39e', '#8a8c29', '#82352b', '#82352b', '#09a1e0', '#8a8c29', '#82352b', '#b6d300', '#09a1e0']; 接着遍历 lineNum,将 lineNum 中的元素和颜色传到 createLine 函数中,根据这两个参数来绘制地铁线路以及配色,毕竟 js 文件中的命名方式也是有规律的,哪一条线路,则命名后面一定会加上对应的数字,所以我们只需要将字符串与这个编号结合即可获得 js 中对应的数组了: let lineName = 'Line' + num; let line = window[lineName]; createLine 的定义也非常简单,我的代码设置了不少的样式,所以看起来有点多。创建一个 ht.Polyline 管线,我们可以通过 polyline.addPoint() 函数向这个变量中添加具体的点,通过 setSegments 可以设置点的连接方式。 function createLine(num, color) {//绘制地图线 var polyline = new ht.Polyline();//多边形 管线 polyline.setTag(num);//设置节点tag标签,作为唯一标示 if(num === '68') polyline.setToolTip('A P M');//设置提示信息 else if(num === '60') polyline.setToolTip('G F'); else polyline.setToolTip('Line' + num); if(color) { polyline.s({//s 为 setStyle 的简写,设置样式 'shape.border.width': 0.4,//设置多边形的边框宽度 'shape.border.color': color,//设置多边形的边框颜色 'select.width': 0.2,//设置选中节点的边框宽度 'select.color': color//设置选中节点的边框颜色 }); } let lineName = 'Line' + num; let line = window[lineName]; for(let i = 0; i < line.length; i++) { for(let j = 0; j < line[i].coords.length; j++) { polyline.addPoint({x: line[i].coords[j][0]*300, y: -line[i].coords[j][1]*300}); if(num === '68'){//APM线(有两条,但是点是在同一个数组中的) if(i === 0 && j === 0) { polyline.setSegments([1]); } else if(i === 1 && j === 0) { polyline.getSegments().push(1); } else { polyline.getSegments().push(2); } } } } polyline.setLayer('0');//将线设置在下层,点设置在上层“top” dm.add(polyline);//将管线添加进数据容器中储存,不然这个管线属于“游离”状态,是不会显示在拓扑图上的 return polyline; } 上面代码中添加地铁线上的点有分为几种情况,是因为 js 中设置线的时候 Line68 有一个“跳跃”点的现象,所以我们必须“跳跃”过去,篇幅有限 Line68 数组具体的声明自行看 subway.js。 这里说明一点,如果用的是 addPoint 函数,不设置 segments 时,默认将添加进的点用直线连接,segments 的定义如下: 1: moveTo,占用 1 个点信息,代表一个新路径的起点 2: lineTo,占用 1 个点信息,代表从上次最后点连接到该点 3: quadraticCurveTo,占用 2 个点信息,第一个点作为曲线控制点,第二个点作为曲线结束点 4: bezierCurveTo,占用 3 个点信息,第一和第二个点作为曲线控制点,第三个点作为曲线结束点 5: closePath,不占用点信息,代表本次路径绘制结束,并闭合到路径的起始点 所以我们要做“跳跃”的行为设置 segments 为 1 即可。 最后绘制这些地铁线上的点,这个部分 subway.js 中也分离出来了,命名以“mark_Point”、“t_Point”以及“n_Point”开头,我在前面 js 的展示部分有对这些数组进行解释,大家动动中指划上去看看。 我们在这些点的位置添加 ht.Node 节点,当节点一添加进 dm 数据容器中时,就会在拓扑图上显示,当然,前提是这个拓扑图组件 gv 设置的数据容器是这个 dm。篇幅有限,添加地铁线上的点的代码部分我只展示添加“换乘站点”的点: var tName = 't_Point' + num; var tP = window[tName];//大站点 if(tP) {//有些线路没有“换乘站点” for(let i = 0; i < tP.length; i++) { let node = createNode(tP[i].name, tP[i].value, color[index]);//在获取的线路上的点的坐标位置添加节点 node.s({//设置节点的样式style 'label.scale': 0.05,//文本缩放,可以避免浏览器限制的最小字号问题 'label.font': 'bold 12px arial, sans-serif'//设置文本的font }); node.setSize(0.6, 0.6);//设置节点大小。由于js中每个点之间的偏移量太小,所以我不得不把节点设置小一些 node.setImage('images/旋转箭头.json');//设置节点的图片 node.a('alarmColor1', 'rgb(150, 150, 150)');//attr属性,可以在这里面设置任何的东西,alarmColor1是在上面设置的image的json中绑定的属性,具体参看 HT for Web 矢量手册(http://www.hightopo.com/guide/guide/core/vector/ht-vector-guide.html#ref_binding) node.a('alarmColor2', 'rgb(150, 150, 150)');//同上 node.a('tpNode', true);//这个属性设置只是为了用来区分“换乘站点”和“小站点”的,后面会用上 } }

问问小秘 2020-01-07 11:16:33 0 浏览量 回答数 0

回答

能干的多了去了看下面弹性计算云服务器ECS:可弹性扩展、安全、稳定、易用的计算服务块存储:可弹性扩展、高性能、高可靠的块级随机存储专有网络 VPC:帮您轻松构建逻辑隔离的专有网络负载均衡:对多台云服务器进行流量分发的负载均衡服务弹性伸缩:自动调整弹性计算资源的管理服务资源编排:批量创建、管理、配置云计算资源容器服务:应用全生命周期管理的Docker服务高性能计算HPC:加速深度学习、渲染和科学计算的GPU物理机批量计算:简单易用的大规模并行批处理计算服务E-MapReduce:基于Hadoop/Spark的大数据处理分析服务数据库云数据库RDS:完全兼容MySQL,SQLServer,PostgreSQL云数据库MongoDB版:三节点副本集保证高可用云数据库Redis版:兼容开源Redis协议的Key-Value类型云数据库Memcache版:在线缓存服务,为热点数据的访问提供高速响应PB级云数据库PetaData:支持PB级海量数据存储的分布式关系型数据库云数据库HybridDB:基于Greenplum Database的MPP数据仓库云数据库OceanBase:金融级高可靠、高性能、分布式自研数据库数据传输:比GoldenGate更易用,阿里异地多活基础架构数据管理:比phpMyadmin更强大,比Navicat更易用存储对象存储OSS:海量、安全和高可靠的云存储服务文件存储:无限扩展、多共享、标准文件协议的文件存储服务归档存储:海量数据的长期归档、备份服务块存储:可弹性扩展、高性能、高可靠的块级随机存储表格存储:高并发、低延时、无限容量的Nosql数据存储服务网络CDN:跨运营商、跨地域全网覆盖的网络加速服务专有网络 VPC:帮您轻松构建逻辑隔离的专有网络高速通道:高速稳定的VPC互联和专线接入服务NAT网关:支持NAT转发、共享带宽的VPC网关大数据(数加)MaxCompute:原名ODPS,是一种快速、完全托管的TB/PB级数据仓库解决方案大数据开发套件:提供可视化开发界面、离线任务调度运维、快速数据集成、多人协同工作等功能,拥有强大的Open API为数据应用开发者提供良好的再创作生态DataV数据可视化:专精于业务数据与地理信息融合的大数据可视化,通过图形界面轻松搭建专业的可视化应用, 满足您日常业务监控、调度、会展演示等多场景使用需求关系网络分析:基于关系网络的大数据可视化分析平台,针对数据情报侦察场景赋能,如打击虚假交易,审理保险骗赔,案件还原研判等推荐引擎:推荐服务框架,用于实时预测用户对物品偏好,支持 A/B Test 效果对比公众趋势分析:利用语义分析、情感算法和机器学习,分析公众对品牌形象、热点事件和公共政策的认知趋势企业图谱:提供企业多维度信息查询,方便企业构建基于企业画像及企业关系网络的风险控制、市场监测等企业级服务数据集成:稳定高效、弹性伸缩的数据同步平台,为阿里云各个云产品提供离线(批量)数据进出通道分析型数据库:在毫秒级针对千亿级数据进行即时的多维分析透视和业务探索流计算:流式大数据分析平台,提供给用户在云上进行流式数据实时化分析工具人工智能机器学习:基于阿里云分布式计算引擎的一款机器学习算法平台,用户通过拖拉拽的方式可视化的操作组件来进行试验,平台提供了丰富的组件,包括数据预处理、特征工程、算法组件、预测与评估语音识别与合成:基于语音识别、语音合成、自然语言理解等技术,为企业在多种实际应用场景下,赋予产品“能听、会说、懂你”式的智能人机交互体验人脸识别:提供图像和视频帧中人脸分析的在线服务,包括人脸检测、人脸特征提取、人脸年龄估计和性别识别、人脸关键点定位等独立服务模块印刷文字识别:将图片中的文字识别出来,包括身份证文字识别、门店招牌识别、行驶证识别、驾驶证识别、名片识别等证件类文字识别场景云安全(云盾)服务器安全(安骑士):由轻量级Agent和云端组成,集检测、修复、防御为一体,提供网站后门查杀、通用Web软件0day漏洞修复、安全基线巡检、主机访问控制等功能,保障服务器安全DDoS高防IP:云盾DDoS高防IP是针对互联网服务器(包括非阿里云主机)在遭受大流量的DDoS攻击后导致服务不可用的情况下,推出的付费增值服务,用户可以通过配置高防IP,将攻击流量引流到高防IP,确保源站的稳定可靠Web应用防火墙:网站必备的一款安全防护产品。 通过分析网站的访问请求、过滤异常攻击,保护网站业务可用及资产数据安全加密服务:满足云上数据加密,密钥管理、加解密运算需求的数据安全解决方案CA证书服务:云上签发Symantec、CFCA、GeoTrust SSL数字证书,部署简单,轻松实现全站HTTPS化,防监听、防劫持,呈现给用户可信的网站访问数据风控:凝聚阿里多年业务风控经验,专业、实时对抗垃圾注册、刷库撞库、活动作弊、论坛灌水等严重威胁互联网业务安全的风险绿网:智能识别文本、图片、视频等多媒体的内容违规风险,如涉黄,暴恐,涉政等,省去90%人力成本安全管家:基于阿里云多年安全实践经验为云上用户提供的全方位安全技术和咨询服务,为云上用户建立和持续优化云安全防御体系,保障用户业务安全云盾混合云:在用户自有IDC、专有云、公共云、混合云等多种业务环境为用户建设涵盖网络安全、应用安全、主机安全、安全态势感知的全方位互联网安全攻防体系态势感知:安全大数据分析平台,通过机器学习和结合全网威胁情报,发现传统防御软件无法覆盖的网络威胁,溯源攻击手段、并且提供可行动的解决方案先知:全球顶尖白帽子和安全公司帮你找漏洞,最私密的安全众测平台。全面体检,提早发现业务漏洞及风险,按效果付费移动安全:为移动APP提供安全漏洞、恶意代码、仿冒应用等检测服务,并可对应用进行安全增强,提高反破解和反逆向能力。互联网中间件企业级分布式应用服务EDAS:以应用为中心的中间件PaaS平台、消息队列MQ:Apache RocketMQ商业版企业级异步通信中间件分布式关系型数据库服务DRDS:水平拆分/读写分离的在线分布式数据库服务云服务总线CSB:企业级互联网能力开放平台业务实施监控服务ARMS:端到端一体化实时监控解决方案产品分析E-MapReduce:基于Hadoop/Spark的大数据处理分析服务云数据库HybirdDB:基于Greenplum Database的MPP数据仓库高性能计算HPC:加速深度学习、渲染和科学计算的GPU物理机大数据计算服务MaxCompute:TB/PB级数据仓库解决方案分析型数据库:海量数据实时高并发在线分析开放搜索:结构化数据搜索托管服务管理与监控云监控:指标监控与报警服务访问控制:管理多因素认证、子账号与授权、角色与STS令牌资源编排:批量创建、管理、配置云计算资源操作审计:详细记录控制台和API操作密钥管理服务:安全、易用、低成本的密钥管理服务应用服务日志服务:针对日志收集、存储、查询和分析的服务开放搜索:结构化数据搜索托管服务性能测试:性能云测试平台,帮您轻松完成系统性能评估邮件推送:事务/批量邮件推送,验证码/通知短信服务API网关:高性能、高可用的API托管服务,低成本开放API物联网套件:助您快速搭建稳定可靠的物联网应用消息服务:大规模、高可靠、高并发访问和超强消息堆积能力视频服务视频点播:安全、弹性、高可定制的点播服务媒体转码:为多媒体数据提供的转码计算服务视频直播:低延迟、高并发的音频视频直播服务移动服务移动推送:移动应用通知与消息推送服务短信服务:验证码和短信通知服务,三网合一快速到达HTTPDNS:移动应用域名防劫持和精确调整服务移动安全:为移动应用提供全生命周期安全服务移动数据分析:移动应用数据采集、分析、展示和数据输出服务移动加速:移动应用访问加速云通信短信服务:验证码和短信通知服务,三网合一快速到达语音服务:语音通知和语音验证,支持多方通话流量服务:轻松玩转手机流量,物联卡专供物联终端使用私密专线:号码隔离,保护双方的隐私信息移动推送:移动应用通知与消息推送服务消息服务:大规模、高可靠、高并发访问和超强消息堆积能力邮件推送:事务邮件、通知邮件和批量邮件的快速发送

巴洛克上校 2019-12-02 00:25:55 0 浏览量 回答数 0

问题

wxpython绑定事件弹错:操作报错

kun坤 2020-06-04 10:31:54 4 浏览量 回答数 1

回答

简介 ES是一个基于RESTful web接口并且构建在Apache Lucene之上的开源分布式搜索引擎。 同时ES还是一个分布式文档数据库,其中每个字段均可被索引,而且每个字段的数据均可被搜索,能够横向扩展至数以百计的服务器存储以及处理PB级的数据。 可以在极短的时间内存储、搜索和分析大量的数据。通常作为具有复杂搜索场景情况下的核心发动机。 ES就是为高可用和可扩展而生的。一方面可以通过升级硬件来完成系统扩展,称为垂直或向上扩展(Vertical Scale/Scaling Up)。 另一方面,增加更多的服务器来完成系统扩展,称为水平扩展或者向外扩展(Horizontal Scale/Scaling Out)。尽管ES能够利用更强劲的硬件,但是垂直扩展毕竟还是有它的极限。真正的可扩展性来自于水平扩展,通过向集群中添加更多的节点来分担负载,增加可靠性。ES天生就是分布式的,它知道如何管理多个节点来完成扩展和实现高可用性。意味应用不需要做任何的改动。 Gateway,代表ES索引的持久化存储方式。在Gateway中,ES默认先把索引存储在内存中,然后当内存满的时候,再持久化到Gateway里。当ES集群关闭或重启的时候,它就会从Gateway里去读取索引数据。比如LocalFileSystem和HDFS、AS3等。 DistributedLucene Directory,它是Lucene里的一些列索引文件组成的目录。它负责管理这些索引文件。包括数据的读取、写入,以及索引的添加和合并等。 River,代表是数据源。是以插件的形式存在于ES中。  Mapping,映射的意思,非常类似于静态语言中的数据类型。比如我们声明一个int类型的变量,那以后这个变量只能存储int类型的数据。比如我们声明一个double类型的mapping字段,则只能存储double类型的数据。 Mapping不仅是告诉ES,哪个字段是哪种类型。还能告诉ES如何来索引数据,以及数据是否被索引到等。 Search Moudle,搜索模块,支持搜索的一些常用操作 Index Moudle,索引模块,支持索引的一些常用操作 Disvcovery,主要是负责集群的master节点发现。比如某个节点突然离开或进来的情况,进行一个分片重新分片等。这里有个发现机制。 发现机制默认的实现方式是单播和多播的形式,即Zen,同时也支持点对点的实现。另外一种是以插件的形式,即EC2。 Scripting,即脚本语言。包括很多,这里不多赘述。如mvel、js、python等。    Transport,代表ES内部节点,代表跟集群的客户端交互。包括 Thrift、Memcached、Http等协议 RESTful Style API,通过RESTful方式来实现API编程。 3rd plugins,代表第三方插件。 Java(Netty),是开发框架。 JMX,是监控。 使用案例 1、将ES作为网站的主要后端系统 比如现在搭建一个博客系统,对于博客帖子的数据可以直接在ES上存储,并且使用ES来进行检索,统计。ES提供了持久化的存储、统计和很多其他数据存储的特性。 注意:但是像其他的NOSQL数据存储一样,ES是不支持事务的,如果要事务机制,还是考虑使用其他的数据库做真实库。 2、将ES添加到现有系统 有些时候不需要ES提供所有数据的存储功能,只是想在一个数据存储的基础之上使用ES。比如已经有一个复杂的系统在运行,但是现在想加一个搜索的功能,就可以使用该方案。 3、将ES作为现有解决方案的后端部分 因为ES是开源的系统,提供了直接的HTTP接口,并且现在有一个大型的生态系统在支持他。比如现在我们想部署大规模的日志框架、用于存储、搜索和分析海量的事件,考虑到现有的工具可以写入和读取ES,可以不需要进行任何开发,配置这些工具就可以去运作。 设计结构 1、逻辑设计 文档 文档是可以被索引的信息的基本单位,它包含几个重要的属性: 是自我包含的。一篇文档同时包含字段和他们的取值。 是层次型的。文档中还可以包含新的文档,一个字段的取值可以是简单的,例如location字段的取值可以是字符串,还可以包含其他字段和取值,比如可以同时包含城市和街道地址。 拥有灵活的结构。文档不依赖于预先定义的模式。也就是说并非所有的文档都需要拥有相同的字段,并不受限于同一个模式 {   "name":"meeting",   "location":"office",   "organizer":"yanping" } {   "name":"meeting",   "location":{     "name":"sheshouzuo",        "date":"2019-6-28"   },   "memebers":["leio","shiyi"] } 类型 类型是文档的逻辑容器,类似于表格是行的容器。在不同的类型中,最好放入不同的结构的文档。 字段 ES中,每个文档,其实是以json形式存储的。而一个文档可以被视为多个字段的集合。 映射 每个类型中字段的定义称为映射。例如,name字段映射为String。 索引 索引是映射类型的容器一个ES的索引非常像关系型世界中的数据库,是独立的大量文档集合。   关系型数据库与ES的结构上的对比 2、物理设计 节点 一个节点是一个ES的实例,在服务器上启动ES之后,就拥有了一个节点,如果在另一个服务器上启动ES,这就是另一个节点。甚至可以在一台服务器上启动多个ES进程,在一台服务器上拥有多个节点。多个节点可以加入同一个集群。 当ElasticSearch的节点启动后,它会利用多播(multicast)(或者单播,如果用户更改了配置)寻找集群中的其它节点,并与之建立连接。这个过程如下图所示: 节点主要有3种类型,第一种类型是client_node,主要是起到请求分发的作用,类似路由。第二种类型是master_node,是主的节点,所有的新增,删除,数据分片都是由主节点操作(elasticsearch底层是没有更新数据操作的,上层对外提供的更新实际上是删除了再新增),当然也能承担搜索操作。第三种类型是date_node,该类型的节点只能做搜索操作,具体会分配到哪个date_node,就是由client_node决定,而data_node的数据都是从master_node同步过来的 分片 一个索引可以存储超出单个结点硬件限制的大量数据。比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。   为了解决这个问题,ES提供了将索引划分成多份的能力,这些份就叫做分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。 分片之所以重要,主要有两方面的原因:   1、允许你水平分割/扩展你的内容容量 允许你在分片(潜在地,位于多个节点上)之上进行分布式的、并行的操作,进而提高性能/吞吐量 至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是完全由ES管理的,对于作为用户的你来说,这些都是透明的。   2、在一个网络/云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了。这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,ES允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片,或者直接叫复制。 复制之所以重要,主要有两方面的原因: (1)在分片/节点失败的情况下,提供了高可用性。因为这个原因,注意到复制分片从不与原/主要(original/primary)分片置于同一节点上是非常重要的。 (2)扩展你的搜索量/吞吐量,因为搜索可以在所有的复制上并行运行 总之,每个索引可以被分成多个分片。一个索引也可以被复制0次(意思是没有复制)或多次。一旦复制了,每个索引就有了主分片(作为复制源的原来的分片)和复制分片(主分片的拷贝)之别。分片和复制的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变复制数量,但是不能改变分片的数量。   默认情况下,ES中的每个索引被分片5个主分片和1个复制,这意味着,如果你的集群中至少有两个节点,你的索引将会有5个主分片和另外5个复制分片(1个完全拷贝),这样的话每个索引总共就有10个分片。一个索引的多个分片可以存放在集群中的一台主机上,也可以存放在多台主机上,这取决于你的集群机器数量。主分片和复制分片的具体位置是由ES内在的策略所决定的。 3、插件HEAD elasticsearch-head是一个界面化的集群操作和管理工具 ● node:即一个 Elasticsearch 的运行实例,使用多播或单播方式发现 cluster 并加入。 ● cluster:包含一个或多个拥有相同集群名称的 node,其中包含一个master node。 ● index:类比关系型数据库里的DB,是一个逻辑命名空间。 ● alias:可以给 index 添加零个或多个alias,通过 alias 使用index 和根据index name 访问index一样,但是,alias给我们提供了一种切换index的能力,比如重建了index,取名● customer_online_v2,这时,有了alias,我要访问新 index,只需要把 alias 添加到新 index 即可,并把alias从旧的 index 删除。不用修改代码。 ● type:类比关系数据库里的Table。其中,一个index可以定义多个type,但一般使用习惯仅配一个type。 ● mapping:类比关系型数据库中的 schema 概念,mapping 定义了 index 中的 type。mapping 可以显示的定义,也可以在 document 被索引时自动生成,如果有新的 field,Elasticsearch 会自动推测出 field 的type并加到mapping中。 ● document:类比关系数据库里的一行记录(record),document 是 Elasticsearch 里的一个 JSON 对象,包括零个或多个field。 ● field:类比关系数据库里的field,每个field 都有自己的字段类型。 ● shard:是一个Lucene 实例。Elasticsearch 基于 Lucene,shard 是一个 Lucene 实例,被 Elasticsearch 自动管理。之前提到,index 是一个逻辑命名空间,shard 是具体的物理概念,建索引、查询等都是具体的shard在工作。shard 包括primary shard 和 replica shard,写数据时,先写到primary shard,然后,同步到replica shard,查询时,primary 和 replica 充当相同的作用。replica shard 可以有多份,也可以没有,replica shard的存在有两个作用,一是容灾,如果primary shard 挂了,数据也不会丢失,集群仍然能正常工作;二是提高性能,因为replica 和 primary shard 都能处理查询。另外,如上图右侧红框所示,shard数和replica数都可以设置,但是,shard 数只能在建立index 时设置,后期不能更改,但是,replica 数可以随时更改。但是,由于 Elasticsearch 很友好的封装了这部分,在使用Elasticsearch 的过程中,我们一般仅需要关注 index 即可,不需关注shard。   shard、node、cluster 在物理上构成了 Elasticsearch 集群,field、type、index 在逻辑上构成一个index的基本概念,在使用 Elasticsearch 过程中,我们一般关注到逻辑概念就好,就像我们在使用MySQL 时,我们一般就关注DB Name、Table和schema即可,而不会关注DBA维护了几个MySQL实例、master 和 slave 等怎么部署的一样。 ES中的索引原理 (1)传统的关系型数据库 二叉树查找效率是logN,同时插入新的节点不必移动全部节点,所以用树型结构存储索引,能同时兼顾插入和查询的性能。因此在这个基础上,再结合磁盘的读取特性(顺序读/随机读),传统关系型数据库采用了B-Tree/B+Tree这样的数据结构做索引 (2)ES 采用倒排索引 那么,倒排索引是个什么样子呢? 首先,来搞清楚几个概念,为此,举个例子: 假设有个user索引,它有四个字段:分别是name,gender,age,address。画出来的话,大概是下面这个样子,跟关系型数据库一样 Term(单词):一段文本经过分析器分析以后就会输出一串单词,这一个一个的就叫做Term Term Dictionary(单词字典):顾名思义,它里面维护的是Term,可以理解为Term的集合 Term Index(单词索引):为了更快的找到某个单词,我们为单词建立索引 Posting List(倒排列表):倒排列表记录了出现过某个单词的所有文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项(Posting)。根据倒排列表,即可获知哪些文档包含某个单词。(PS:实际的倒排列表中并不只是存了文档ID这么简单,还有一些其它的信息,比如:词频(Term出现的次数)、偏移量(offset)等,可以想象成是Python中的元组,或者Java中的对象) (PS:如果类比现代汉语词典的话,那么Term就相当于词语,Term Dictionary相当于汉语词典本身,Term Index相当于词典的目录索引) 我们知道,每个文档都有一个ID,如果插入的时候没有指定的话,Elasticsearch会自动生成一个,因此ID字段就不多说了 上面的例子,Elasticsearch建立的索引大致如下: name字段: age字段: gender字段: address字段: Elasticsearch分别为每个字段都建立了一个倒排索引。比如,在上面“张三”、“北京市”、22 这些都是Term,而[1,3]就是Posting List。Posting list就是一个数组,存储了所有符合某个Term的文档ID。 只要知道文档ID,就能快速找到文档。可是,要怎样通过我们给定的关键词快速找到这个Term呢? 当然是建索引了,为Terms建立索引,最好的就是B-Tree索引(MySQL就是B树索引最好的例子)。 我们查找Term的过程跟在MyISAM中记录ID的过程大致是一样的 MyISAM中,索引和数据是分开,通过索引可以找到记录的地址,进而可以找到这条记录 在倒排索引中,通过Term索引可以找到Term在Term Dictionary中的位置,进而找到Posting List,有了倒排列表就可以根据ID找到文档了 (PS:可以这样理解,类比MyISAM的话,Term Index相当于索引文件,Term Dictionary相当于数据文件) (PS:其实,前面我们分了三步,我们可以把Term Index和Term Dictionary看成一步,就是找Term。因此,可以这样理解倒排索引:通过单词找到对应的倒排列表,根据倒排列表中的倒排项进而可以找到文档记录) 为了更进一步理解,用两张图来具现化这一过程: (至于里面涉及的更加高深的数据压缩技巧,以及多个field联合查询利用跳表的数据结构快速做运算来查询,这些大家有兴趣可以自己去了解)

问问小秘 2020-04-29 15:40:48 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 云栖号物联网 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站 云栖号弹性计算 阿里云云栖号 云栖号案例 云栖号直播