首页 文章 精选 留言 我的

精选列表

搜索[提高],共10005篇文章
优秀的个人博客,低调大师

Java提高篇(二):IO字节流、字符流和处理流

在我们的Java语言当中,通常会有对文件进行读写,因此我们引入java的IO类来进行文件的读写。 一.字节流 下面是一个字节流的实例: 1 import java.io.*; 2 public class IO { 3 public static void main(String[] args) { 4 System.out.println("现在利用Java的一个类读取一个数据已经定义好的数据"); 5 FileInputStream fis=null;//利用这个函数写进来的是字节型读入而非字符型 6 FileOutputStream fos=null;//这个类是我们引入的IO包当中的类了,首先进行对象和引用变量的创建,后面使用了抛出异常的操作是为了让机器避免发生出错。 7 try 8 { 9 fis=new FileInputStream("F:/我自己编写的代码库/JAVA/src/from.txt");//后面引入参数,说明读取的文件的绝对路径,绝对路径里面有中文都居然成功了。 10 fos =new FileOutputStream("F:/我自己编写的代码库/JAVA/src/fromto.txt"); 11 byte buffer[]=new byte[100];//这里定义比特二进制的数组,证明了我们使用的是字节型流,而不是字符型,字符型利用了其它的定义 12 int temp=fis.read(buffer,0,100);//第一:输入进来的必须是比特数组流。第二:开始进行输入的比特序列号,如第一个,第二个。第三:输入流的比特长度 13 for (int i=0;i<=99;i++) 14 { 15 System.out.println(buffer[i]); 16 } 17 fos.write(buffer,0,temp);//temp变量reveal了读入数据所接收到的字节的长度,这个正好是read函数的返回值 18 } 19 catch (Exception e) 20 { 21 System.out.println(e);//在改变了我们的读取数组长度之后,读取成功了,之前在for循环的地方越界了 22 } 23 } 24 25 } 如果想读入一篇具有多个文字的文件的话,可以使用以下代码: 1 import java.io.*; 2 3 public class IO2 { 4 public static void main(String[] args) { 5 System.out.println("现在进行大型文件的读写"); 6 FileInputStream fis1=null; 7 FileOutputStream fos1=null; 8 try 9 { 10 fis1=new FileInputStream("F:/我自己编写的代码库/JAVA/src/from1.txt"); 11 fos1=new FileOutputStream("F:/我自己编写的代码库/JAVA/src/fromto1.txt"); 12 byte buffer[]=new byte[1024]; 13 while(true) 14 { 15 int temp=fis1.read(buffer,0,buffer.length);//read方法返回的是每次读取文件的字节数(比如a的asc码等) 16 if(temp==-1)//假设读到1024字节了,或者在1024字节之前就没有字节可读了,就会返回-1这个数值,然后跳出该循环,进行下一个循环 17 { 18 break;//这个程序在进行下一个循环的进入点在哪里呢?并没有提到,按道理来说是不会从刚刚已经读过的数据开始读,应该里面有一种自动读取的机制 19 } 20 fos1.write(buffer,0,buffer.length); 21 } 22 } 23 catch (Exception e) 24 { 25 System.out.println(e); 26 } 27 finally { 28 try{ 29 fis1.close(); 30 fos1.close();//在这里进行IO流的关闭,有开就有关,不然的话就会造成资源的浪费 31 System.out.println("读写完毕"); 32 } 33 catch (Exception e) 34 { 35 System.out.println(e); 36 } 37 } 38 }} 注意前面创建对象的时候,我们创建的数组具有1024个字节,这是因为我们常常通过1024个字节进行读取,1024个字节正好等于了1个K,这样才可以对大文件当中的文字进行读写。最后我们在finally处,关闭了这个流,如果不关闭这个流的话,文件写入进去之后,是不会被保存下来的。 二.字符流 示例代码如下: 1 mport java.io.*; 2 public class IO3 { 3 public static void main(String[] args) { 4 System.out.println("现在开始字符流型程序的编写"); 5 FileReader fis2=null; 6 FileWriter fos2=null; 7 try { 8 fis2=new FileReader("F:/我自己编写的代码库/JAVA/src/from2.txt"); 9 fos2=new FileWriter("F:/我自己编写的代码库/JAVA/src/fromto2.txt"); 10 char buffer[]=new char[100];//字符流和字节流的区别就是这里,引入的对象buffer是字符型定义的是字符而不是二进制了。以及前面创建的两个对象分别是: FileReader和FileWriter。这就是两个不同的区别,其它的完全相同。 11 int temp=fis2.read(buffer,0,buffer.length); 12 for(int i=0;i<=99;i++) 13 { 14 System.out.println(buffer[i]); 15 } 16 fos2.write(buffer,0,buffer.length); 17 System.out.println("完成输入以及输出"); 18 } 19 catch (Exception e) 20 { 21 System.out.println(e); 22 } 23 finally { 24 try{ 25 fis2.close(); 26 fos2.close();//只有关闭了输入输出流之后,输入进去的字节才会保存,不关闭的话,就仅仅会停留在内存当中不会保存的。这就是需要关闭的原因了。 27 } 28 catch (Exception e) 29 { 30 System.out.println(e); 31 } 32 } 33 } 34 } 读取大型文件的代码只需要根据和字节流进行相似的处理就可以进行读取大型文件了。 三.处理流 实例代码如下: 1 import java.io.*; 2 public class IO4 { 3 public static void main(String[] args) { 4 System.out.println("现在开始处理流程序的书写\n"); 5 FileReader a=null; 6 BufferedReader b=null; 7 try 8 { 9 String line=null; 10 a=new FileReader("F:/我自己编写的代码库/JAVA/src/from2.txt"); 11 b=new BufferedReader(a); 12 while(true) 13 { 14 line=b.readLine(); 15 if(line==null) 16 { 17 break; 18 } 19 System.out.println(line);//这里打印出了我们读取文件的内容,至于里面的内容为什么会像像这样打印,明天再来讲解。 20 } 21 } 22 catch (Exception e) 23 { 24 System.out.println(e); 25 } 26 } 27 } 上述代码还是比较容易理解的。

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

30个极大提高开发效率的Visual Studio Code插件

译者按: 看完这篇文章,我打算从 Sublime Text 转到 Visual Studio Code 了! 原文: Immensely upgrade your development environment with these Visual Studio Code extensions 译者: Fundebug 为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。 我们的 VSC(VSCode)将会像一个长了五只可以发射激光的独角兽一样!接下来会介绍我每天使用的非常有用的插件。 如果你还是一个 VSC 的新手,那么点击左侧最下方的按钮来安装插件。 Material Theme 下载量:130 万 Visual Studio Code 最悠久的主题! Auto Import 下载量:46 万 自动去查找、分析、然后提供代码补全。对于 TypeScript 和 TSX,可以适用。 Import Cost 下载量:41 万 该插件会在行尾显示导入的包的大小。为了计算包大小,该插件要使用 Webpack 和 babili-webpack-plugin。 Indent-Rainbow 下载量:13 万 一个简单的插件可以使得对齐更加具有可读性。 IntelliSense for CSS class names in HTML 下载量:243 万 基于你的项目以及通过link标签引用的外部文件,该智能插件提供 HTML 中 CSS class 名字的补全。 SVG Viewer 下载量:29 万 一个用来预览 SVG 的插件。 Prettier 下载量:357 万 你绝对不能少了这个插件,你需要它来一键美化你的 JavaScript/TypeScript/CSS 代码。 React Native Tools 下载量:218 万 代码提示、Debugging、集成 RN 的命令。 Sublime Text Keymap and Settings Importer 下载量:76 万 从下载量来看,看来不少人从 Sublime Text 转移过来了。 这个插件将 visual studio code 的快捷键绑定改成了和 Sublime Text 3 一样。你可以试一试:cmd + P (Mac),ctrl + P (Windows)。 你可以跳转到文件,如果在搜索前添加>符号,你甚至可以搜索动作,比如打开内置的终端、安装插件等等。 对于习惯使用 ST3 的人,这是一个很大的加分项。 npm Intellisense 下载量:88 万 VSCode 插件可以在导入语句自动补全 npm 模块名称。 lit-html 下载量:3 万 在 JavaScript/TypeScript 的文件中,如果有使用到 HTML 标记,lit-html 提供语法高亮和相应的补全支持。 highlight-matching-tag 下载量:6 万 这本来应该是 VSCode 应该默认提供的功能,高亮匹配的标签。 GitLens 下载量:772 万 啥也别说,直接上图! Git Project Manager 下载量:37 万 Git Project Manager 可以然你直接一键搜索并打开某个的基于 Git 管理的项目。 Git History 下载量:332 万 用来查看 git log 或则一个文件的 git 历史,比较不同的分支,commits。 File Utils 下载量:8 万 提供了一个更加简洁的方法来创建、复制、移动、重命名、删除文件/文件夹。 Bracket Pair Colorizer 下载量:228 万 如果你的代码有很多的回调,那么这种高亮可以帮助你更好地区分不同的代码块。 Color Highlight 下载量:25 万 直观展示你定义的颜色。 CSS Peek 下载量:23 万 可以在 HTML 中通过 CSS id 或则 class 来定位到其定义。 Debugger for Chrome 下载量:1111 万 用 Chrome 来 Debug 你的 JavaScript 代码,或则其它支持 Chrome Debugger 协议的平台。 Quokka.js 下载量:172 万 实时执行 JavaScript 代码(做快速的 demo 很有用)。 Trailing Spaces 下载量:7 万 高亮那些冗余的空格,可以快速删掉。 TypeScript Hero 下载量:72 万 辅助用 TypeScript 编程的童鞋! WakaTime 下载量:24 万 从你的使用习惯中生成数据报表。 Vetur 下载量:451 万 VS Code 下面的 Vue 工具!有 Pine Wu 开发,已经累计 400 多万下载量! Code Runner 下载量:346 万 支持多种语言的代码的立即执行。支持的语言:C, C++, Java, JavaScript, PHP, Python, Perl, Perl 6, Ruby, Go, Lua, Groovy, PowerShell, BAT/CMD, BASH/SH, F# Script, F# (.NET Core), C# Script, C# (.NET Core), VBScript, TypeScript, CoffeeScript, Scala, Swift, Julia, Crystal, OCaml Script, R, AppleScript, Elixir, Visual Basic .NET, Clojure, Haxe, Objective-C, Rust, Racket, AutoHotkey, AutoIt, Kotlin, Dart, Free Pascal, Haskell, Nim, D。 PHP IntelliSense 下载量:415 万 vscode-icons 下载量:799 万 Icon 集合。 Jest 下载量:29 万 愉快地使用 Facebook 的 Jest。 React.js code snippets 下载量:59 万 用 ES6 语法去开发 React.js 应用非常方便。 关于Fundebug Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了6亿+错误事件,得到了Google、360、金山软件等众多知名用户的认可。欢迎免费试用! 版权声明: 转载时请注明作者Fundebug以及本文地址:https://blog.fundebug.com/2018/07/24/vs-extensions/ 我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。

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

Java 面试就业指导,100 % 提高面试成功率!

想要成为合格的Java程序员或工程师到底需要具备哪些专业技能,面试者在面试之前到底需要准备哪些东西呢? 本文陈列的这些内容既可以作为个人简历中的内容,也可以作为面试的时候跟面试官聊的东西,你可以把这些内容写到你的简历中,当然更需要的是你在面试的时候向面试官展示这些专业技能。 相信此文对正在寻觅Java程序员(Java工程师)职位的freshman以及希望成为中高级Java开发者的junior都会有所帮助。 专业技能 1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架、多线程(并发编程)、I/O(NIO)、Socket、JDBC、XML、反射等。 2.熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。 3.对Spring的IoC容器和AOP原理有深入了解,熟练的运用Spring框架管理各种Web组件及其依赖关系,熟练的使用Spring进行事务、日志、安全性等的管理,有使用Spring MVC作为表示层技术以及使用Spring提供的持久化支持进行Web项目开发的经验,熟悉Spring对其他框架的整合。 4.熟练的使用Hibernate、MyBatis等ORM框架,熟悉Hibernate和MyBatis的核心API,对Hibernate的关联映射、继承映射、组件映射、缓存机制、事务管理以及性能调优等有深入的理解。 5.熟练的使用HTML、CSS和JavaScript进行Web前端开发,熟悉jQuery和Bootstrap,对Ajax技术在Web项目中的应用有深入理解,有使用前端MVC框架(AngularJS)和JavaScript模板引擎(HandleBars)进行项目开发的经验。 6.熟悉常用的关系型数据库产品(MySQL、Oracle),熟练的使用SQL和PL/SQL进行数据库编程。 7.熟悉面向对象的设计原则,对GoF设计模式和企业应用架构模式有深入的了解和实际开发的相关经验,熟练的使用UML进行面向对象的分析和设计,有TDD(测试驱动开发)和DDD(领域驱动设计)的经验。 8.熟悉Apache、NginX、Tomcat、WildFly、Weblogic等Web服务器和应用服务器的使用,熟悉多种服务器整合、集群和负载均衡的配置。 9熟练的使用产品原型工具Axure,熟练的使用设计建模工具PowerDesigner和Enterprise Architect,熟练的使用Java开发环境Eclipse和IntelliJ,熟练的使用前端开发环境WebStorm,熟练的使用软件版本控制工具SVN和Git,熟练的使用项目构建和管理工具Maven和Gradle。点击这里查看BATJ面试题总结。 说明:上面罗列的这些东西并不是每一项你都要烂熟于心,根据企业招聘的具体要求可以做相应的有针对性的准备。 我个人觉得前6项应该是最低要求,是作为一个Java开发者必须要具备的专业技能。 项目介绍 我们应该如何向面试官介绍项目? 本系统是X委托Y开发的用于Z的系统,系统包括A、B、C、D等模块。 系统使用了Java企业级开发的开源框架E以及前端技术F。 表示层运用了G架构,使用H作为视图I作为控制器并实现了REST风格的请求; 业务逻辑层运用了J模式,并通过K实现事务、日志和安全性等功能,通过L实现缓存服务; 持久层使用了M封装CRUD操作,底层使用N实现数据存取。整个项目采用了P开发模型。 说明: 上面的描述中,E通常指Spring(Java企业级开发的一站式选择); F最有可能是jQuery库及其插件或者是Bootstrap框架,当然如果要构建单页应用(SPA)最佳的方案是前端MVC框架(如AngularJS)和JavaScript模板引擎(如HandleBars); G显然是MVC(模型-视图-控制),最有可能的实现框架是Spring MVC,除此之外还有Struts 2、JSF以及Apache为JSF提供的MyFaces实现,可以使用JSP作为MVC中的V,也可使用模板引擎(如Freemarker和Velocity)来生成视图,还可以是各种文档或报表(如Excel和PDF等),而Servlet和自定义的控制器是MVC中的C,当然Spring MVC中提供了作为前端控制器的DispatcherServlet; J通常是事务脚本, K应该是AOP(面向切面编程)技术, L目前广泛使用的有memcached和Redis; M的选择方案很多,最有可能的是Hibernate和MyBatis,也可以两种技术同时运用,但通常是将增删改交给Hibernate来处理,而复杂的查询则由MyBatis完成, 此外TopLink、jOOQ也是优秀的持久层解决方案;底层的数据存取传统上是使用关系型数据库,可以是MySQL、Oracle、SQLServer、DB2等,随着大数据时代的来临,也可以采用NoSQL(如MongoDB、MemBase、BigTable等)和其他大数据存取方案(如GFS、HDFS等); 项目的开发模型P可以是瀑布模型、快速原型模型、增量模型、螺旋模型、喷泉模型、RAD模型等 项目开发流程 1.可行性分析 可行性分析报告 / 项目开发计划书 2.需求分析 >>> 需求规格说明书 · OOAD(用例图、时序图、活动图) · 界面原型:帮助理解需求、业务层设计时推导事务脚本 3.设计 >>> 概要设计说明书/详细设计说明书 · 抽取业务实体(领域对象):类图、E-R图(概念设计阶段) · 分层架构:确定各层的技术实现方案(具体到使用的框架、数据库服务器、应用服务器等)。 业务层设计:事务脚本模式(事务:用户发送一次请求就是一个事务; 脚本:一个方法或一个函数;事务脚本:把一次请求封装为一个方法或一个函数; 事务脚本模式:一个事务开始于脚本的打开,终止于脚本的关闭)。 业务层涉及的对象有三种类型:事务脚本类(封装了业务的流程)、数据访问对象(DAO,封装了持久化操作)、数据传输对象(DTO,封装了失血/贫血领域对象),三者之间的关系是事务脚本类组合(聚合)数据访问对象,这二者都依赖了数据传输对象 · 正向工程(UML类图生成Java代码)和逆向工程(Java代码生成UML类图) · 数据库物理设计(ER图转换成表间关系图、建库和建表、使用工具插入测试数据) 4.编码 5.测试 >>> 测试报告 / 缺陷报告 · 单元测试:对软件中的最小可测试单元进行检查和验证,在Java中是对类中的方法进行测试,可以使用JUnit工具来实施。 · 集成测试:集成测试也叫组装测试或联合测试。在单元测试的基础上,将所有模块按照设计要求组装成为子系统进行测试。 · 系统测试:将已经确认的软件、硬件、外设、网络等元素结合在一起,进行信息系统的各种组装测试和确认测试,系统测试是针对整个产品系统进行的测试,目的是验证系统是否满足了需求规格的定义,找出与需求规格不符或与之矛盾的地方,从而提出更加完善的方案。 · 验收测试:在软件产品完成了单元测试、集成测试和系统测试之后,产品发布之前所进行的软件测试活动。它是技术测试的最后一个阶段,也称为交付测试。验收测试的目的是确保软件准备就绪,并且可以让最终用户将其用于执行软件的既定功能和任务。 6.交付和维护 >>> 用户手册 / 操作手册 项目管理 · 版本控制:CVS/SVN/Git · 自动构建:Ant/Maven/Ivy/Gradle · 持续集成:Hudson/Jenkins 系统结构 · 负载均衡服务器:F5、A10 · 应用服务器: · HTTP服务器:Apache、NginX(HTTP、反向代理、邮件代理服务器) · Servlet容器:Tomcat、Resin · EJB容器:WildFly(JBoss Application Server)、GlassFish、Weblogic、Websphere · 数据库服务器:MySQL、Oracle 第三方工具(插件)应用 · 图表工具:基于jQuery的图表插件(如jQchart、Flot、Charted等)、Chart.js、Highcharts等。 · 报表工具:Pentaho Reporting、iReport、DynamicReports等。 · 文档处理:POI、iText等。 · 工作流引擎:jBPM、OpenWFE、Snaker、SWAMP等。 · 作业调度:Quartz、JobServer、Oddjob等。 · 缓存服务:EhCache、memcached、SwarmCache等。 · 消息队列:Open-MQ、ZeroMQ等。 · 安全框架:Shiro、PicketBox等。 · 搜索引擎:IndexTank、Lucene、ElasticSearch等。 · Ajax框架:jQuery、ExtJS、DWR等。 · UI插件:EasyUI、MiniUI等。 · 富文本框:UEditor、CKEditor等。 面试提问 · 项目是为哪个公司开发的?项目的投入是多少? · 有多少人参与了项目开发?整个团队中,测试人员、开发人员、项目经理比例是多少? · 项目开发了多长时间?项目总的代码量有多少?你的代码量有多少? · 项目采用了怎样的开发模型或开发流程?项目的架构是怎样的?项目的技术选型是怎样的? · 你在项目中承担了怎样的职责?是否经常开会或加班?项目完成后有哪些收获或是经验教训? · 项目中最困难的部分是什么?如何解决团队开发时遇到的各种冲突? 说明:对于没有实际项目经验的,可以在前程无忧、智联招聘、拉勾网等网站上搜索招聘Java程序员的公司,找到他们的官方网站了解他们做的项目,查看项目的详细介绍,然后尝试完成其中一部分功能,最好请教一下高人看看自己的设计和代码是否恰当,这样相当于积累了一定的项目经验。点击这里查看BATJ面试题总结。 常见错误 1.只在计算机上练习 2.不做行为面试题演练 3.不做模拟面试训练 4.试图死记硬背答案 5.不大声说出你的解题思路 6.代码不够严谨 7.不写测试代码 8.轻言放弃 反问面试官的问题 1. 我注意到你们使用了X技术,请问你们是如何解决Y问题的? 2. 为什么你们的产品使用了X技术而不是Y技术?据我所知,X技术虽然有A、B、C等好处,但也存在D和E问题,而Y技术可以解决D和E问题。 3. 我对您说的X技术不是太熟悉,但我感觉它是一个不错的解决方案,您能多讲讲它的工作原理吗? 4. 你们团队是如何进行项目规划的?一周会有几次例会?每周的代码量大概是多少? 5. 就X问题我能想到的解决方案目前就只有Y了,请问您会怎么解决这个问题? S.A.R.法则 S.A.R法则是指先描述问题的场景,然后解释你采取的行动,最后陈述结果。 算法题的五种解法 1.举例法:通过举例子发现其中的一般规则。 例子:圆内接三角形是锐角三角形的概率是多少?这是搜狗的一个面试题,可以在圆上随意画三个点连接成三角形就可以知道答案了。 2.模式匹配法 例子:一个有序数组的元素经过循环移动,元素的顺序变成"3 4 5 6 1 2"。怎样找到数组中最小的那个元素,假设数组中的元素各不相同。这个题目和折半查找看起来是那么相似,因此可以借鉴折半查找的算法,最小元素显然出现在"mid > right"的转折点。 3.简化推广法 说明:简化问题规模和数据类型,然后再发现通用的解法。 4.简单构造法 例子:找出"abcde"的所有可能的排列组合。先考虑只有"a"的情况,再考虑"ab"的情况,以此类推。最终你可能会得到一个递归公式。这种方法往往会演变成递归法。 5.数据结构头脑风暴法 例子:随机生成一些数字,并找出其中位数。这种问题可以在头脑中将你了解的数据结构过一遍,看看哪种是最合适的数据结构。上面的题目可以建立两个堆,一个大根堆和一个小根堆,较小的元素放在大根堆,较大的元素放在小根堆,如果两个堆不平衡,可以从其中一个堆取出元素放入另一个堆即可。最后中位数应该是两个堆的根之一。 原文发布时间为:2018-08-31 本文来自云栖社区合作伙伴“Java技术栈”,了解相关信息可以关注“Java技术栈”。

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

【Java入门提高篇】Day13 Java中的反射机制

前一段时间一直忙,所以没什么时间写博客,拖了这么久,也该更新更新了。最近看到各种知识付费的推出,感觉是好事,也是坏事,好事是对知识沉淀的认可与推动,坏事是感觉很多人忙于把自己的知识变现,相对的在沉淀上做的实际还不够,我对此暂时还没有什么想法,总觉得,慢慢来,会更快一点,自己掌握好节奏就好。 好了,言归正传。 反射机制是Java中的一个很强大的特性,可以在运行时获取类的信息,比如说类的父类,接口,全部方法名及参数,全部常量和变量,可以说类在反射面前已经衣不遮体了(咳咳,这是正规车)。先举一个小栗子,大家随意感受一下: public void testA(){ String name = "java.lang.String"; try{ Class cl = Class.forName(name); Class supercl = cl.getSuperclass(); String modifiers = Modifier.toString(cl.getModifiers()); if (modifiers.length() > 0){ System.out.print(modifiers + " "); } System.out.print(name); if (supercl != null && supercl != Object.class){ System.out.print(" extents " + supercl.getName()); } System.out.print("{\n"); printFields(cl); System.out.println(); printConstructors(cl); System.out.println(); printMethods(cl); System.out.println("}"); }catch (ClassNotFoundException e){ e.printStackTrace(); } System.exit(0); } private static void printConstructors(Class cl){ Constructor[] constructors = cl.getDeclaredConstructors(); for (Constructor c : constructors){ String name = c.getName(); System.out.print(" "); String modifiers = Modifier.toString(c.getModifiers()); if (modifiers.length() > 0){ System.out.print(modifiers + " "); } System.out.print(name + "("); Class[] paraTypes = c.getParameterTypes(); for (int j = 0; j < paraTypes.length; j++){ if (j > 0){ System.out.print(", "); } System.out.print(paraTypes[j].getSimpleName()); } System.out.println(");"); } } private static void printMethods(Class cl){ Method[] methods = cl.getDeclaredMethods(); for (Method m : methods){ Class retType = m.getReturnType(); String name = m.getName(); System.out.print(" "); String modifiers = Modifier.toString(m.getModifiers()); if (modifiers.length() > 0){ System.out.print(modifiers + " "); } System.out.print(retType.getSimpleName() + " " + name +"("); Class[] paramTypes = m.getParameterTypes(); for(int j = 0; j < paramTypes.length; j++){ if (j > 0){ System.out.print(", "); } System.out.print(paramTypes[j].getName()); } System.out.println(");"); } } private static void printFields(Class cl){ Field[] fields = cl.getFields(); for (Field f : fields){ Class type = f.getType(); String name = f.getName(); System.out.print(" "); String modifiers = Modifier.toString(f.getModifiers()); if (modifiers.length() > 0){ System.out.print(modifiers + " "); } System.out.println(type.getSimpleName() + " " + name +";"); } } 调用testA方法输出如下: public final java.lang.String{ public static final Comparator CASE_INSENSITIVE_ORDER; public java.lang.String(byte[], int, int); public java.lang.String(byte[], Charset); public java.lang.String(byte[], String); public java.lang.String(byte[], int, int, Charset); public java.lang.String(byte[], int, int, String); java.lang.String(char[], boolean); public java.lang.String(StringBuilder); public java.lang.String(StringBuffer); public java.lang.String(byte[]); public java.lang.String(int[], int, int); public java.lang.String(); public java.lang.String(char[]); public java.lang.String(String); public java.lang.String(char[], int, int); public java.lang.String(byte[], int); public java.lang.String(byte[], int, int, int); public boolean equals(java.lang.Object); public String toString(); public int hashCode(); public int compareTo(java.lang.String); public volatile int compareTo(java.lang.Object); public int indexOf(java.lang.String, int); public int indexOf(java.lang.String); public int indexOf(int, int); public int indexOf(int); static int indexOf([C, int, int, [C, int, int, int); static int indexOf([C, int, int, java.lang.String, int); public static String valueOf(int); public static String valueOf(long); public static String valueOf(float); public static String valueOf(boolean); public static String valueOf([C); public static String valueOf([C, int, int); public static String valueOf(java.lang.Object); public static String valueOf(char); public static String valueOf(double); public char charAt(int); private static void checkBounds([B, int, int); public int codePointAt(int); public int codePointBefore(int); public int codePointCount(int, int); public int compareToIgnoreCase(java.lang.String); public String concat(java.lang.String); public boolean contains(java.lang.CharSequence); public boolean contentEquals(java.lang.CharSequence); public boolean contentEquals(java.lang.StringBuffer); public static String copyValueOf([C); public static String copyValueOf([C, int, int); public boolean endsWith(java.lang.String); public boolean equalsIgnoreCase(java.lang.String); public static transient String format(java.util.Locale, java.lang.String, [Ljava.lang.Object;); public static transient String format(java.lang.String, [Ljava.lang.Object;); public void getBytes(int, int, [B, int); public byte[] getBytes(java.nio.charset.Charset); public byte[] getBytes(java.lang.String); public byte[] getBytes(); public void getChars(int, int, [C, int); void getChars([C, int); private int indexOfSupplementary(int, int); public native String intern(); public boolean isEmpty(); public static transient String join(java.lang.CharSequence, [Ljava.lang.CharSequence;); public static String join(java.lang.CharSequence, java.lang.Iterable); public int lastIndexOf(int); public int lastIndexOf(java.lang.String); static int lastIndexOf([C, int, int, java.lang.String, int); public int lastIndexOf(java.lang.String, int); public int lastIndexOf(int, int); static int lastIndexOf([C, int, int, [C, int, int, int); private int lastIndexOfSupplementary(int, int); public int length(); public boolean matches(java.lang.String); private boolean nonSyncContentEquals(java.lang.AbstractStringBuilder); public int offsetByCodePoints(int, int); public boolean regionMatches(int, java.lang.String, int, int); public boolean regionMatches(boolean, int, java.lang.String, int, int); public String replace(char, char); public String replace(java.lang.CharSequence, java.lang.CharSequence); public String replaceAll(java.lang.String, java.lang.String); public String replaceFirst(java.lang.String, java.lang.String); public String[] split(java.lang.String); public String[] split(java.lang.String, int); public boolean startsWith(java.lang.String, int); public boolean startsWith(java.lang.String); public CharSequence subSequence(int, int); public String substring(int); public String substring(int, int); public char[] toCharArray(); public String toLowerCase(java.util.Locale); public String toLowerCase(); public String toUpperCase(); public String toUpperCase(java.util.Locale); public String trim(); } 这里把String类型的所有方法和变量都获取到了,使用的仅仅是String类型的全名。当然,反射的功能不仅仅是获取类的信息,还可以在运行时动态创建对象,回想一下,我们正常的对象使用,都是需要在代码中先声明,然后才能使用它,但是使用反射后,就能在运行期间动态创建对象并调用其中的方法,甚至还能直接查看类的私有成员变量,还能获取类的注解信息,在泛型中类型判断时也经常会用到。反射可以说完全打破了类的封装性,把类的信息全部暴露了出来。 上面的代码看不太明白也没关系,只要稍微感受一下反射的能力就好了。介绍完了反射能做的事情,本篇教程就不再写一些玩具代码了,这次以一个实用型的代码为媒介来介绍反射。 在开发中,经常会遇到两个不同类对象之间的复制,把一个类中的字段信息get取出来,然后set到另一个类中,大部分情况下,两个类对应的字段是一样,每次这样使用是很麻烦的,那么利用反射就可以实现一个封装,只需要调用一个方法即可实现简单的类字段复制。 那么,先来想想,要复制一个类对象的所有字段信息到另一个类对象中,首先,怎么获取一个类的某个字段的值呢?我们先来编写一个方法: /** * 获取对象的指定字段的值 * @param obj 目标对象 * @param fieldName 目标字段 * @return 返回字段值 * @throws Exception 可能抛出异常 */ private static Object getFieldValue(Object obj, String fieldName) throws Exception{ //获取类型信息 Class clazz = obj.getClass(); //取对应的字段信息 Field field = clazz.getDeclaredField(fieldName); //设置可访问权限 field.setAccessible(true); //取字段值 Object value = field.get(obj); return value; } 这里使用了两个之前没有说过的类,一个是Class,是不是很眼熟,想一想,我们每次定义一个类的时候是不是都要用到它,哈哈,那你就想错了,那是class关键词,java是大小写的敏感的,这里的Class是一个类名,那这个类是干嘛用的呢? 虚拟机在加载每一个类的时候,会自动生成一个对应的Class类来保存该类的信息,可以理解为Class类是那个类的代理类,是连接实际类与类加载器的桥梁,可以通过它来获取虚拟机的类加载器引用,从而实现更多的骚操作。Class类是一个泛型类,每个类都有对应的一个Class类,比如String对应的Class类就是Class<String>。 Class有很多方法来获取更多关于类的信息,这里使用getDeclaredField方法来获取指定字段信息,返回的是Field类型对象,这个对象里存储着关于字段的一些信息,如字段名称,字段类型,字段修饰符,字段可访问性等,setAccessible方法可以设置字段的可访问性质,这样就能直接访问private修饰的字段了,然后使用get方法来获取指定对象的对应字段的值。 我们来测试一下: public void testB(){ try{ Employee employee = new Employee(); employee.setName("Frank"); employee.setSalary(6666.66); System.out.println((String)getFieldValue(employee,"name")); System.out.println((double)getFieldValue(employee,"salary")); }catch (Exception e){ e.printStackTrace(); } } 输出如下: Frank 6666.66 接下来,我们需要获取类中所有字段,然后在另一个类中查找是否有对应字段,如果有的话就设置字段的值到相应的字段中。 /** * 复制一个类对象属性到另一个类对象中 * @param objA 需要复制的对象 * @param objB 复制到的目标对象类型 * @return 返回复制后的目标对象 */ private static void parseObj(Object objA,Object objB) throws Exception{ if (objA == null){ return; } //获取objA的类信息 Class classA = objA.getClass(); Class classB = objB.getClass(); try { //获取objA的所有字段 Field[] fieldsA = classA.getDeclaredFields(); //获取objB的所有字段 Field[] fieldsB = classB.getDeclaredFields(); if (fieldsA == null || fieldsA.length <= 0 || fieldsB == null || fieldsB.length <= 0){ return; } //生成查询map Map<String,Field> fieldMap = new HashMap<>(); for (Field field:fieldsA){ fieldMap.put(field.getName(),field); } //开始复制字段信息 for (Field fieldB : fieldsB){ //查找是否在objB的字段中存在该字段 Field fielaA = fieldMap.get(fieldB.getName()); if (fielaA != null){ fieldB.setAccessible(true); fieldB.set(objB,getFieldValue(objA,fielaA.getName())); } } } catch (IllegalStateException e) { throw new IllegalStateException("instace fail: " ,e); } } 这里获取到classA和classB的所有字段之后,先生成了一个map用于查找,可以减少遍历次数,然后之后只需要遍历一次就可以判断相应字段是否存在,如果存在则取出对应值设置到相应的字段里去。 接下来测试一下: public void testB(){ try{ //生成Employee对象 Employee employee = new Employee("Frank",6666.66); //生成一个Manager对象 Manager manager = new Manager(); //复制对象 parseObj(employee,manager); System.out.println(manager.getName()); System.out.println(manager.getSalary()); }catch (Exception e){ e.printStackTrace(); } } public class Employee { private String name; private Double salary; public Employee(String name, Double salary) { this.name = name; this.salary = salary; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; } } public class Manager { private String name; private Double salary; private Double bonus; public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; } public Double getBonus() { return bonus; } public void setBonus(Double bonus) { this.bonus = bonus; } } 输出如下: Frank 6666.66 完美,这样我们就利用了反射机制完美的把相同的字段在不同类的对象之间进行了复制,这里仅仅是两个字段,所以可能好处不明显,但事实上,实际开发中,经常会有将BO转换为VO的操作,这时候,这个操作就很有必要了,简单的一行命令就可以代替一大堆的get和set操作。 当然,使用反射机制固然高端大气上档次,但是也是一把双刃剑,使用不当很可能会带来严重后果,而且使用反射的话,会占用更多资源,运行效率也会降低,上述工具类是用运行效率换开发效率。开发中不建议大量使用,还是那句话,技术只是手段,需要使用的时候再使用,不要为了使用而使用。 至于反射中的其他方法和姿势,大家尽可以慢慢去摸索,这里仅仅是抛砖引玉。 至此,本篇讲解完毕,欢迎大家继续关注。 真正重要的东西,用眼睛是看不见的。

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

【Java入门提高篇】Day12 Java代理——Cglib动态代理

今天来介绍另一种更为强大的代理——Cglib动态代理。 什么是Cglib动态代理? 我们先回顾一下上一篇的jdk动态代理,jdk动态代理是通过接口来在运行时动态创建委托类的代理对象,但是跟静态代理一样有一个缺点,就是必须和委托类实现相同的接口,当接口数量增加时,便需要增加代理类的数量才能满足需求,而且如果委托类是别人写的,而且没有实现任何接口,那么jdk动态代理就有些力不从心了。 这时候Cglib动态代理就脱颖而出了,Cglib并不依赖接口,可以直接生成委托类的代理对象,而且可以代理委托类的任意非final修饰的public和protected方法,我们可以先来看一个栗子。 先定义一个Programmer类: public class Programmer { private String name; public void setName(String name) { System.out.println("Setting Name."); this.name = name; }public void code(){ System.out.println(name + " is writing bugs."); } } 然后定义一个代理类: public class ProgrammerProxy implements MethodInterceptor { /** * 内部持有委托类对象的引用 */ private Object target; /** * 创建代理类对象 */ public Programmer createProxy(Programmer object){ target = object; //创建Enhancer对象 Enhancer enhancer = new Enhancer(); //设置要代理的目标类,以扩展功能 enhancer.setSuperclass(this.target.getClass()); //设置单一回调对象,在回调中拦截对目标方法的调用 enhancer.setCallback(this); //设置类加载器 enhancer.setClassLoader(object.getClass().getClassLoader()); //创建代理对象 return (Programmer)enhancer.create(); } /** * 回调方法:在代理实例上拦截并处理目标方法的调用,返回结果 * @param proxy 代理类 * @param method 被代理的方法 * @param params 该方法的参数数组 * @param methodProxy */ @Override public Object intercept(Object proxy, Method method, Object[] params, MethodProxy methodProxy) throws Throwable { //调用之前处理 doBefore(); //调用原方法 method.invoke(target,params); //调用之后处理 doAfter(); return null; } private void doAfter() { System.out.println("do after."); } private void doBefore() { System.out.println("do before."); } } 然后测试一下: public class ProxyTest { @Test public void testCglibProxy(){ //创建一个Programmer对象 Programmer programmerA = new Programmer(); programmerA.setName("Frank"); //创建代理对象 Programmer programmerProxyA = new ProgrammerProxy().createProxy(programmerA); programmerProxyA.code(); //修改代理对象 programmerProxyA.setName("Wang"); programmerProxyA.code(); //修改委托类对象 programmerA.setName("Song"); programmerProxyA.code(); } } 输出如下: Setting Name. do before. Frank is writing bugs. do after. do before. Setting Name. do after. do before. Wang is writing bugs. do after. Setting Name. do before. Song is writing bugs. do after. Cglib实现动态代理的步骤也不是很麻烦,先创建一个类实现MethodInterceptor接口,重写intercept方法,在intercep中可以截获委托类的所有非final修饰的public和protected方法,上例中,method.invoke(target,params);即为调用原对象的原方法,在代理类中保存了委托类对象的引用,这一点跟JDK动态代理是一样的。在调用原方法前先调用了doBefore方法,调用之后还调用了doAfter方法,从而实现了代理功能。至于createProxy方法,也只是一个固定步骤,先创建Enhance对象,然后将委托类的一些属性往里塞,然后调用create方法来动态生成代理对象。 在测试类中,为了更明显的说明代理类与委托类的关系,分别用代理类对象programmerProxyA和委托类对象programmerA对name字段进行修改,可以产生一样的效果。 下面来对比一下Cglib动态代理与JDK动态代理: 1.两者都是动态代理,都是运行时动态生成代理对象。 2.JDK动态代理利用的是接口信息来实现的代理,委托类必须实现某个或者某些接口,而Cglib则是利用继承关系,利用asm在运行时动态生成委托类的子类,从而实现对委托类的代理。因此不依赖接口。 3.Cglib由于是利用继承关系来实现代理的,因此无法代理被final修饰的类以及被final修饰的方法。 4.Cglib一般来说效率要比JDK动态代理效率更高,可以实现的代理也更为强大。 当然,具体情况具体分析,虽然Cglib比Jdk动态代理更强大,但并不一定各个地方都强行使用,有时候JDK动态代理相对来说更加简单粗暴。 至此,本篇完结,代理相关内容讲解完毕,欢迎大家继续关注。 jar包下载地址:http://download.csdn.net/download/qiuyingjia/10181844真正重要的东西,用眼睛是看不见的。

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

多套方案来提高python web框架的并发处理能力

Python常见部署方法有 : 1 2 3 fcgi :用spawn-fcgi或者框架自带的工具对各个project分别生成监听进程,然后和http 服务互动 wsgi :利用http服务的mod_wsgi模块来跑各个project(Web应用程序或框架简单而通用的Web服务器 之间的接口)。 uWSGI 是一款像php-cgi一样监听同一端口,进行统一管理和负载平衡的工具,uWSGI,既不用wsgi协议也不用fcgi协议,而是自创了一个uwsgi的协议,据说该协议大约是fcgi协议的 10 倍那么快。 1 其实 WSGI 是分成 server 和 framework (即 application) 两部分 (当然还有 middleware)。严格说 WSGI 只是一个协议, 规范 server 和 framework 之间连接的接口。 WSGI server 把服务器功能以 WSGI 接口暴露出来。比如 mod_wsgi 是一种 server, 把 apache 的功能以 WSGI 接口的形式提供出来。 1 2 3 4 5 WSGI framework 就是我们经常提到的 Django 这种框架。不过需要注意的是, 很少有单纯的 WSGI framework , 基于 WSGI 的框架往往都自带 WSGI server。比如 Django、CherryPy 都自带 WSGI server 主要是测试用途, 发布时则使用生产环境的 WSGI server。而有些 WSGI 下的框架比如 pylons、bfg 等, 自己不实现 WSGI server。使用 paste 作为 WSGI server。 Paste 是流行的 WSGI server, 带有很多中间件。还有 flup 也是一个提供中间件的库。 搞清除 WSGI server 和 application, 中间件自然就清楚了。除了 session、cache 之类的应用, 前段时间看到一个 bfg 下的中间件专门用于给网站换肤的 (skin) 。中间件可以想到的用法还很多。 这里再补充一下, 像 django 这样的框架如何以 fastcgi 的方式跑在 apache 上的。这要用到 flup.fcgi 或者 fastcgi.py (eurasia 中也设计了一个 fastcgi.py 的实现) 这些工具, 它们就是把 fastcgi 协议转换成 WSGI 接口 (把 fastcgi 变成一个 WSGI server) 供框架接入。整个架构是这样的: django -> fcgi2wsgiserver -> mod_fcgi -> apache 。 虽然我不是 WSGI 的粉丝, 但是不可否认 WSGI 对 python web 的意义重大。有意自己设计 web 框架, 又不想做 socket 层和 http 报文解析的同学, 可以从 WSGI 开始设计自己的框架。在 python 圈子里有个共识, 自己随手搞个 web 框架跟喝口水一样自然, 非常方便。或许每个 python 玩家都会经历一个倒腾框架的 uWSGI的主要特点如下: 超快的性能。 低内存占用(实测为apache2的mod_wsgi的一半左右)。 多app管理。 详尽的日志功能(可以用来分析app性能和瓶颈)。 高度可定制(内存大小限制,服务一定次数后重启等)。 uwsgi的官方文档: http://projects.unbit.it/uwsgi/wiki/Doc nginx.conf 1 2 3 4 location / { include uwsgi_params uwsgi_pass 127.0 . 0.1 : 9090 } 启动app 1 uwsgi -s : 9090 -w myapp uwsgi的调优参数~ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 uwsgi的参数 以上是单个project的最简单化部署,uwsgi还是有很多令人称赞的功能的,例如: 并发 4 个线程: uwsgi -s : 9090 -w myapp -p 4 主控制线程+ 4 个线程: uwsgi -s : 9090 -w myapp -M -p 4 执行超过 30 秒的client直接放弃: uwsgi -s : 9090 -w myapp -M -p 4 -t 30 限制内存空间128M: uwsgi -s : 9090 -w myapp -M -p 4 -t 30 --limit- as 128 服务超过 10000 个req自动respawn: uwsgi -s : 9090 -w myapp -M -p 4 -t 30 --limit- as 128 -R 10000 后台运行等: uwsgi -s : 9090 -w myapp -M -p 4 -t 30 --limit- as 128 -R 10000 -d uwsgi.log 为了让多个站点共享一个uwsgi服务,必须把uwsgi运行成虚拟站点:去掉“-w myapp”加上”–vhost”: uwsgi -s :9090 -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log --vhost 然后必须配置virtualenv,virtualenv是Python的一个很有用的虚拟环境工具,这样安装: 最后配置nginx,注意每个站点必须单独占用一个server,同一server不同location定向到不同的应用不知为何总是失败,估计也 算是一个bug。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 server { listen 80 ; server_name app1.mydomain.com; location / { include uwsgi_params; uwsgi_pass 127.0 . 0.1 : 9090 ; uwsgi_param UWSGI_PYHOME / var /www/myenv; uwsgi_param UWSGI_SCRIPT myapp1; uwsgi_param UWSGI_CHDIR / var /www/myappdir1; } } server { listen 80 ; server_name app2.mydomain.com; location / { include uwsgi_params; uwsgi_pass 127.0 . 0.1 : 9090 ; uwsgi_param UWSGI_PYHOME / var /www/myenv; uwsgi_param UWSGI_SCRIPT myapp2; uwsgi_param UWSGI_CHDIR / var /www/myappdir2; } } 这样,重启nginx服务,两个站点就可以共用一个uwsgi服务了。 再来搞下 fastcgi的方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 location / { fastcgi_param REQUEST_METHOD $request_method; fastcgi_param QUERY_STRING $query_string; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param GATEWAY_INTERFACE CGI/ 1.1 ; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_script_name; fastcgi_pass 127.0 . 0.1 : 9002 ; } 1 2 3 4 5 6 location / static / { root /path/to/www; if (-f $request_filename) { rewrite ^/ static /(.*)$ / static /$ 1 break ; } } 启动一个fastcgi的进程 1 spawn-fcgi -d /path/to/www -f /path/to/www/index.py -a 127.0 . 0.1 -p 9002 用web.py写的一个小demo测试 1 2 3 4 5 6 7 8 9 10 11 #!/usr/bin/env python # -*- coding: utf- 8 -*- import web urls = ( "/.*" , "hello" ) app = web.application(urls, globals()) class hello: def GET(self): return 'Hello, world!' if __name__ == "__main__" : web.wsgi.runwsgi = lambda func, addr=None: web.wsgi.runfcgi(func, addr) app.run() 启动nginx 1 nginx 这样就ok了~ 下面开始介绍下 我一般用的方法: 前端nginx用负责负载分发: 部署的时候采用了单IP多端口方式,服务器有4个核心,决定开4个端口对应,分别是8885~8888,修改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 upstream backend { server 127.0 . 0.1 : 8888 ; server 127.0 . 0.1 : 8887 ; server 127.0 . 0.1 : 8886 ; server 127.0 . 0.1 : 8885 ; } server{ listen 80 ; server_name message.test.com; keepalive_timeout 65 ; # proxy_read_timeout 2000 ; # sendfile on; tcp_nopush on; tcp_nodelay on; location / { proxy_pass_header Server; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_pass http: //backend; } } 然后运行四个python程序,端口为咱们配置好的端口 我这里用tornado写了一个执行系统程序的例子: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 import subprocess import tornado.ioloop import time import fcntl import functools import os class GenericSubprocess (object): def __init__ ( self, timeout=- 1 , **popen_args ): self.args = dict() self.args[ "stdout" ] = subprocess.PIPE self.args[ "stderr" ] = subprocess.PIPE self.args[ "close_fds" ] = True self.args.update(popen_args) self.ioloop = None self.expiration = None self.pipe = None self.timeout = timeout self.streams = [] self.has_timed_out = False def start(self): "" "Spawn the task. Throws RuntimeError if the task was already started. "" " if not self.pipe is None: raise RuntimeError( "Cannot start task twice" ) self.ioloop = tornado.ioloop.IOLoop.instance() if self.timeout > 0 : self.expiration = self.ioloop.add_timeout( time.time() + self.timeout, self.on_timeout ) self.pipe = subprocess.Popen(**self.args) self.streams = [ (self.pipe.stdout.fileno(), []), (self.pipe.stderr.fileno(), []) ] for fd, d in self.streams: flags = fcntl.fcntl(fd, fcntl.F_GETFL)| os.O_NDELAY fcntl.fcntl( fd, fcntl.F_SETFL, flags) self.ioloop.add_handler( fd, self.stat, self.ioloop.READ|self.ioloop.ERROR) def on_timeout(self): self.has_timed_out = True self.cancel() def cancel (self ) : "" "Cancel task execution Sends SIGKILL to the child process. "" " try : self.pipe.kill() except: pass def stat( self, *args ): '' 'Check process completion and consume pending I/O data' '' self.pipe.poll() if not self.pipe.returncode is None: '' 'cleanup handlers and timeouts' '' if not self.expiration is None: self.ioloop.remove_timeout(self.expiration) for fd, dest in self.streams: self.ioloop.remove_handler(fd) '' 'schedulle callback (first try to read all pending data)' '' self.ioloop.add_callback(self.on_finish) for fd, dest in self.streams: while True: try : data = os.read(fd, 4096 ) if len(data) == 0 : break dest.extend([data]) except: break @property def stdout(self): return self.get_output( 0 ) @property def stderr(self): return self.get_output( 1 ) @property def status(self): return self.pipe.returncode def get_output(self, index ): return "" .join(self.streams[index][ 1 ]) def on_finish(self): raise NotImplemented() class Subprocess (GenericSubprocess): "" "Create new instance Arguments: callback: method to be called after completion. This method should take 3 arguments: statuscode( int ), stdout(str), stderr(str), has_timed_out(boolean) timeout: wall time allocated for the process to complete. After this expires Task.cancel is called. A negative timeout value means no limit is set The task is not started until start is called. The process will then be spawned using subprocess.Popen(**popen_args). The stdout and stderr are always set to subprocess.PIPE. "" " def __init__ ( self, callback, *args, **kwargs): "" "Create new instance Arguments: callback: method to be called after completion. This method should take 3 arguments: statuscode( int ), stdout(str), stderr(str), has_timed_out(boolean) timeout: wall time allocated for the process to complete. After this expires Task.cancel is called. A negative timeout value means no limit is set The task is not started until start is called. The process will then be spawned using subprocess.Popen(**popen_args). The stdout and stderr are always set to subprocess.PIPE. "" " self.callback = callback self.done_callback = False GenericSubprocess.__init__(self, *args, **kwargs) def on_finish(self): if not self.done_callback: self.done_callback = True '' 'prevent calling callback twice' '' self.ioloop.add_callback(functools.partial(self.callback, self.status, self.stdout, self.stderr, self.has_timed_out)) if __name__ == "__main__" : ioloop = tornado.ioloop.IOLoop.instance() def print_timeout( status, stdout, stderr, has_timed_out) : assert(status!= 0 ) assert(has_timed_out) print "OK status:" , repr(status), "stdout:" , repr(stdout), "stderr:" , repr(stderr), "timeout:" , repr(has_timed_out) def print_ok( status, stdout, stderr, has_timed_out) : assert(status== 0 ) assert(not has_timed_out) print "OK status:" , repr(status), "stdout:" , repr(stdout), "stderr:" , repr(stderr), "timeout:" , repr(has_timed_out) def print_error( status, stdout, stderr, has_timed_out): assert(status!= 0 ) assert(not has_timed_out) print "OK status:" , repr(status), "stdout:" , repr(stdout), "stderr:" , repr(stderr), "timeout:" , repr(has_timed_out) def stop_test(): ioloop.stop() t1 = Subprocess( print_timeout, timeout= 3 , args=[ "sleep" , "5" ] ) t2 = Subprocess( print_ok, timeout= 3 , args=[ "sleep" , "1" ] ) t3 = Subprocess( print_ok, timeout= 3 , args=[ "sleepdsdasdas" , "1" ] ) t4 = Subprocess( print_error, timeout= 3 , args=[ "cat" , "/etc/sdfsdfsdfsdfsdfsdfsdf" ] ) t1.start() t2.start() try : t3.start() assert( false ) except: print "OK" t4.start() ioloop.add_timeout(time.time() + 10 , stop_test) ioloop.start() 本文转自 rfyiamcool 51CTO博客,原文链接:http://blog.51cto.com/rfyiamcool/1227629,如需转载请自行联系原作者

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

如何提高.net程序性能

2003年开始由vb/vc转向.net(C#)开发,.net的开发效率确实非常的高,我们主要作C/S的业务处理程序,对程序的响应速度要求比较高,用户不希望在界面上等待。在这方面,.net作的太烂了,根据无法跟vb之类编译成本机代码的程序性能相比,我想园子中搞winform开发的有好很多人吧,不知你们是怎样处理这个问题的,大家是如何忧化.net代码的。 求dudu放在首页一天,也希望园子的朋友们讨论这个问题 谢谢大家,我增加几个相关的连接? 微软对.NET失去信心?.NET专家激起千层浪 http://www.yesky.com/113/1924613.shtml 托管代码和非托管代码效率的对比。 http://www.cnblogs.com/wuchang/archive/2006/12/07/584997.html 作者:魏琼东出处:http://www.cnblogs.com/eastjade关于作者:有13年的软件从业经历,专注于中小软件企业软件开发过程研究,通过在技术与管理帮助中小软件企业实现技术层面开源节流的目的。熟悉需求分析、企业架构、项目管理。现主要从事基于AgileEAS.NET平台的技术咨询工作,主要服务于医疗卫生、铁路、电信、物流、物联网、制造、零售等行业。如有问题或建议,请多多赐教!本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过mail.james@qq.com联系我,也可以加入QQ群:113723486、199463175、116773358、116773358、212867943、147168308、59827496、193486983、15118502和大家共同讨论,非常感谢。 本文转自魏琼东博客园博客,原文链接:http://www.cnblogs.com/eastjade/archive/2007/06/13/782569.html,如需转载请自行联系原作者

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

OpenAI 推出 AI “忏悔”框架:训练模型承认不当行为,提高诚实度

OpenAI 正在开发一个名为“忏悔”(Confession)的创新框架,旨在训练人工智能模型能够坦诚承认自身何时做出了不当行为或潜在的问题决策。 大型语言模型(LLM)通常被训练成提供“符合预期”的回答,这使得它们越来越容易做出阿谀奉承或信口开河的虚假陈述。OpenAI 的新训练模型正是为了解决这一问题,引导模型在主要答案之后做出二次回应,详细说明其得出主要答案的过程。 与传统 LLM 评判标准(如帮助性、准确性和服从性)不同,“忏悔”机制对二次回应的评判标准仅基于诚实性。 研究人员明确表示,他们的目标是鼓励模型坦诚地说明其行为,即便这些行为包括潜在的问题行为,例如:作弊,故意降低分数,违反指令等。 OpenAI 表示:“如果模型诚实地承认作弊、故意降低分数或违反指令,这种坦白反而会增加其奖励,而不是减少。” OpenAI 认为,无论出于何种目的,类似“忏悔”这样的系统都可能对 LLM 的训练有所帮助,并强调其最终目标是让 AI 更加透明。相关的技术文档已同步发布,供感兴趣者查阅。

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

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

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

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