1 | /* |
1 | /* |
Jad(JAva Decompiler)是一个Java的反编译器,可以通过命令行把Java的class文件反编译成源代码。下载点击
使用方法:
[1] 反编译一个class文件:jad example.class,会生成example.jad,用文本编辑器打开就是java源代码
[2] 指定生成源代码的后缀名:jad -sjava example.class,生成example.java
[3] 改变生成的源代码的名称,可以先使用-p将反编译后的源代码输出到控制台窗口,然后使用重定向,输出到文件:jad -p example.class > myexample.java
[4] 把源代码文件输出到指定的目录:jad -dnewdir -sjava example.class,在newdir目录下生成example.java
[5] 把packages目录下的class文件全部反编译:jad -sjava packages/*.class
[6] 把packages目录以及子目录下的文件全部反编译:jad -sjava packages/*/.class,不过你仍然会发现所有的源代码文件被放到了同一个文件中,没有按照class文件的包路径建立起路径
[7] 把packages目录以及子目录下的文件全部反编译并建立和java包一致的文件夹路径,可以使用-r命令:jad -r -sjava packages/*/.class
[8] 当重复使用命令反编译时,Jad会提示“whether you want to overwrite it or not”,使用-o可以强制覆盖旧文件
[9] 还有其他的参数可以设置生成的源代码的格式,可以输入jad命令查看帮助,这里有个人做了简单的翻译:jad命令总结
[10] 当然,你会发现有些源文件头部有些注释信息,不用找了,jad没有参数可以去掉它,用别的办法吧。
Main.java
1 |
|
Main.class
1 | cafe babe 0000 0034 0037 0a00 0d00 1d07 |
反编译后的结果
1 | // Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. |
这里特殊处理了一下小于等于3的数,因为小于等于3的自然数只有2和3是质数。
然后,我们只需要从2开始,一直到小于其自身,依次判断能否被n整除即可,能够整除则不是质数,否则是质数。
1 | public static boolean isPrime(int n){ |
我们继续分析,其实质数还有一个特点,就是它总是等于 6x-1 或者 6x+1,其中 x 是大于等于1的自然数。
如何论证这个结论呢,其实不难。首先 6x 肯定不是质数,因为它能被 6 整除;其次 6x+2 肯定也不是质数,因为它还能被2整除;依次类推,6x+3 肯定能被 3 整除;6x+4 肯定能被 2 整除。那么,就只有 6x+1 和 6x+5 (即等同于6x-1) 可能是质数了。所以循环的步长可以设为 6,然后每次只判断 6 两侧的数即可。
1 | public static boolean isPrime(int num) { |
1 | import java.util.*; |
1 | 1392 ms |
进程与线程是一个程序员的必知概念,面试经常被问及,但是一些文章内容只是讲讲理论知识,可能一些小伙伴并没有真的理解,在实际开发中应用也比较少。本篇文章除了介绍概念,通过Node.js 的角度讲解进程与线程,并且讲解一些在项目中的实战的应用,让你不仅能迎战面试官还可以在实战中完美应用。
Node.js是单线程吗?
Node.js 做耗时的计算时候,如何避免阻塞?
Node.js如何实现多进程的开启和关闭?
Node.js可以创建线程吗?
你们开发过程中如何实现进程守护的?
除了使用第三方模块,你们自己是否封装过一个多进程架构?
进程Process是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础,进程是线程的容器(来自百科)。进程是资源分配的最小单位。我们启动一个服务、运行一个实例,就是开一个服务进程,例如 Java 里的 JVM 本身就是一个进程,Node.js 里通过 node app.js 开启一个服务进程,多进程就是进程的复制(fork),fork 出来的每个进程都拥有自己的独立空间地址、数据栈,一个进程无法访问另外一个进程里定义的变量、数据结构,只有建立了 IPC 通信,进程之间才可数据共享。
1 | const http = require('http'); |
运行上面代码后,以下为 Mac 系统自带的监控工具 “活动监视器” 所展示的效果,可以看到我们刚开启的 Nodejs 进程 7663
线程是操作系统能够进行运算调度的最小单位,首先我们要清楚线程是隶属于进程的,被包含于进程之中。一个线程只能隶属于一个进程,但是一个进程是可以拥有多个线程的。
单线程就是一个进程只开一个线程
Javascript 就是属于单线程,程序顺序执行(这里暂且不提JS异步),可以想象一下队列,前面一个执行完之后,后面才可以执行,当你在使用单线程语言编码时切勿有过多耗时的同步操作,否则线程会造成阻塞,导致后续响应无法处理。你如果采用 Javascript 进行编码时候,请尽可能的利用Javascript异步操作的特性。
1 | const http = require('http'); |
查看打印结果,当我们调用127.0.0.1:3000/compute
的时候,如果想要调用其他的路由地址比如127.0.0.1/大约需要15秒时间,也可以说一个用户请求完第一个compute接口后需要等待15秒,这对于用户来说是极其不友好的。下文我会通过创建多进程的方式child_process.fork 和cluster 来解决解决这个问题。
单线程的一些说明
它是一个一站式(full-stack全栈式)框架,提供了从表现层-springMVC到业务层-spring再到持久层-springdata的一套完整的解决方案。我们在项目中可以只使用spring一个框架,它就可以提供表现层的mvc框架,持久层的Dao框架。它的两大核心IoC和AOP更是为我们程序解耦和代码简洁易维护提供了支持。
答: 若目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理。
优点:因为有接口,所以使系统更加松耦合
缺点:为每一个目标类创建接口
若目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类。
优点:因为代理类与目标类是继承关系,所以不需要有接口的存在。
缺点:因为没有使用接口,所以系统的耦合性没有使用JDK的动态代理好
这里有三种重要的方法给Spring 容器提供配置元数据。
XML配置文件。
基于注解的配置。
基于java的配置。
请注意以下明显的区别:
在设值注入方法支持大部分的依赖注入,如果我们仅需要注入int、string和long型的变量,我们不要用设值的方法注入。
对于基本类型,如果我们没有注入的话,可以为基本类型设置默认值。
在构造方法注入不支持大部分的依赖注入,因为在调用构造方法中必须传入正确的构造参数,否则的话为报错。
设值注入不会重写构造方法的值。
在使用设值注入时有可能还不能保证某种依赖是否已经被注入,也就是说这时对象的依赖关系有可能是不完整的。而在另一种情况下,构造器注入则不允许生成依赖关系不完整的对象。
一、Bean的定义
Spring通常通过配置文件定义Bean。如:
这个配置文件就定义了一个标识为 HelloWorld 的Bean。在一个配置文档中可以定义多个Bean。
二、Bean的初始化
有两种方式初始化Bean。
1、在配置文档中通过指定init-method 属性来完成
2、实现 org.springframwork.beans.factory.InitializingBean接口
那么,当这个Bean的所有属性被Spring的BeanFactory设置完后,会自动调用afterPropertiesSet()方法对Bean进行初始化,于是,配置文件就不用指定 init-method属性了。
三、Bean的调用
有三种方式可以得到Bean并进行调用:
1、使用BeanWrapper
2、使用BeanFactory
3、使用ApplicationConttext
四、Bean的销毁
1、使用配置文件中的 destory-method 属性
2、实现 org.springframwork.bean.factory.DisposebleBean接口
答:AOP–Aspect Oriented Programming面向切面编程;用来封装横切关注点,具体可以在下面的场景中使用:
Authentication 权限、Caching 缓存、Context passing 内容传递、Error handling 错误处理Lazy loading懒加载、Debugging调试、logging, tracing, profiling and monitoring 记录跟踪优化 校准、Performance optimization 性能优化、Persistence 持久化、Resource pooling 资源池、Synchronization 同步、Transactions 事务
原理:AOP是面向切面编程,是通过动态代理的方式为程序添加统一功能,集中解决一些公共问题。
优点:1.各个步骤之间的良好隔离性耦合性大大降低
2.源代码无关性,再扩展功能的同时不对源码进行修改操作
BeanNameAutoProxyCreator
DefaultAdvisorAutoProxyCreator
Metadata autoproxying
FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。
ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。
WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。
构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。
Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入。
一、IOC介绍
IOC是控制反转。
创建对象实例的控制权从代码控制剥离到IOC容器控制(之前的写法,由程序代码直接操控使用new关键字),实际就是你在xml文件控制,控制权的转移是所谓反转,侧重于原理。
二、DI介绍
DI是依赖注入
创建对象实例时,为这个对象注入属性值或其它对象实例,侧重于实现。
事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功。其必须遵循四个原则(ACID)。
原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做;
一致性(Consistency):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是应该处于正确的状态,即数据完整性约束没有被破坏;如银行转帐,A转帐给B,必须保证A的钱一定转给B,一定不会出现A的钱转了但B没收到,否则数据库的数据就处于不一致(不正确)的状态。
隔离性(Isolation):并发事务执行之间互不影响,在一个事务内部的操作对其他事务是不产生影响,这需要事务隔离级别来指定隔离性;
持久性(Durability):事务一旦执行成功,它对数据库的数据的改变必须是永久的,不会因比如遇到系统故障或断电造成数据不一致或丢失。
Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。但实际上,大部分的Spring bean并没有可变的状态(比如Serview类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话(比如 View Model 对象),就需要自行保证线程安全。
作者:程序汪追风
链接:https://juejin.im/post/5d5fd40bf265da03df5f1b3a
来源:掘金
Android
是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备ionic
是一个强大的 HTML5 应用程序开发框架(HTML5 Hybrid Mobile App Framework )git - 愚蠢的内容跟踪器
git [--version] [ - help] [-C <path>] [-c <name> = <value>]
[--exec-path [= <path>]] [--html-path] [--man-path] [--info-path]
[-p | --paginate | -P | --no-pager] [ - no-replace-objects] [--bare]
[--git-dir = <path>] [ - work-tree = <path>] [--namespace = <name>]
[--super前缀= <路径>]
<command> [<args>]
Git是一个快速,可扩展的分布式版本控制系统,具有异常丰富的命令集,可提供高级操作和对内部的完全访问。
请参阅gittutorial [7]以开始使用,然后查看 giteveryday [7]以获取有用的最小命令集。在Git的用户手册有一个更深入的介绍。
掌握了基本概念后,您可以回到此页面了解Git提供的命令。您可以使用“git help command”了解有关各个Git命令的更多信息。 gitcli [7] 手册页概述了命令行命令语法。
可以在以下位置查看最新Git文档的格式化和超链接副本https://git.github.io/htmldocs/git.html。
版
打印git程序来自的Git套件版本。
救命
打印概要和最常用命令的列表。如果选择–all或-a已给出,则打印所有可用命令。如果命名了Git命令,则此选项将显示该命令的手册页。
其他选项可用于控制手册页的显示方式。有关更多信息,请参阅git-help [1],因为git –help …内部转换为git help …。
-C <路径>
运行就好像git是在
此选项会影响预期的路径名的选项一样–git-dir,并 –work-tree在他们的路径名的解释,将相对于所造成的工作目录进行-C选择。例如,以下调用是等效的:
git --git-dir = a.git --work-tree = b -C c status
git --git-dir = c / a.git --work-tree = c / b status
-c
将配置参数传递给命令。给定的值将覆盖配置文件中的值。
请注意,允许省略=in git -c foo.bar …并设置 foo.bar为布尔值true(就像[foo]bar在配置文件中一样)。包括equals但空值(如git -c foo.bar= …)设置foo.bar为git config –type=bool将转换为的空字符串false。
–exec路径[= <路径>]
安装核心Git程序的路径。这也可以通过设置GIT_EXEC_PATH环境变量来控制。如果没有给出路径,git将打印当前设置然后退出。
–html路径
打印路径,不带斜杠,安装Git的HTML文档并退出。
–man路径
打印manpath(请参阅参考资料man(1))获取此版本Git的手册页并退出。
–info路径
打印安装记录此版本Git的Info文件的路径并退出。
-p
–paginate
如果标准输出是终端,则将所有输出传输到较少(或如果设置为$ PAGER)。这将覆盖pager.
-P
–no寻呼机
不要将Git输出传输到寻呼机。
–git-DIR = <路径>
设置存储库的路径。这也可以通过设置GIT_DIR环境变量来控制。它可以是当前工作目录的绝对路径或相对路径。
–namespace = <路径>
设置Git名称空间。有关更多详细信息,请参阅gitnamespaces [7]。相当于设置GIT_NAMESPACE环境变量。
–super前缀= <路径>
目前仅供内部使用。设置一个前缀,该前缀提供从存储库上方到其根目录的路径。一个用途是给出调用它的超级项目的子模块上下文。
–no替换对象
不要使用替换引用来替换Git对象。有关更多信息,请参阅 git-replace [1]。
–literal按本义,pathspecs
按字面意思处理pathspecs(即没有globbing,没有pathspec魔法)。这相当于将GIT_LITERAL_PATHSPECS环境变量设置为1。
–glob-pathspecs
为所有pathspec添加“glob”魔法。这相当于将GIT_GLOB_PATHSPECS环境变量设置为1。可以使用pathspec magic“:( literal)”在各个pathspec上禁用通配符
–noglob-pathspecs
为所有pathspec添加“literal”魔法。这相当于将GIT_NOGLOB_PATHSPECS环境变量设置为1。可以使用pathspec magic“:( glob)”在各个pathspec上启用globbing
–icase-pathspecs
为所有pathspec添加“icase”魔法。这相当于将GIT_ICASE_PATHSPECS环境变量设置为1。
–no-可选锁
不要执行需要锁定的可选操作。这相当于设置GIT_OPTIONAL_LOCKS为0。
–list-CMDS =基团[,组…]
按组列出命令。这是一个内部/实验选项,可能会在将来更改或删除。支持的组包括:builtins,parseopt(使用parse-options的内置命令),main(libexec目录中的所有命令),其他(所有其他命令$PATH都有git-前缀),list-
Update your browser to view this website correctly. Update my browser now