精华内容
下载资源
问答
  • 来源:美团技术博客美团技术团队 在遥远的希艾斯星球爪哇国塞沃城中,两年轻的程序员正在为一件事情苦恼,程序出问题了,一时看不出问题出在哪里,于是有了以下对话:“Debug一下吧。”“线上机器,没开Debug端口...

    4cdaad18900cdcb8bab8c9dcf260ad5a.png

    来源:美团技术博客

    美团技术团队

    在遥远的希艾斯星球爪哇国塞沃城中,两名年轻的程序员正在为一件事情苦恼,程序出问题了,一时看不出问题出在哪里,于是有了以下对话:

    “Debug一下吧。”

    “线上机器,没开Debug端口。”

    “看日志,看看请求值和返回值分别是什么?”

    “那段代码没打印日志。”

    “改代码,加日志,重新发布一次。”

    “怀疑是线程池的问题,重启会破坏现场。”

    长达几十秒的沉默之后:“据说,排查问题的最高境界,就是只通过Review代码来发现问题。”

    比几十秒长几十倍的沉默之后:“我轮询了那段代码一十七遍之后,终于得出一个结论。”

    “结论是?”

    “我还没到达只通过Review代码就能发现问题的至高境界。”

    Java对象行为

    文章开头的问题本质上是动态改变内存中已存在对象的行为问题。

    所以,得先弄清楚JVM中和对象行为有关的地方在哪里,有没有更改的可能性。

    对象使用两种东西来描述事物:行为和属性。

    举个例子:

    12ec5febb89cccd8a1c6a894e31dd060.png

    上面Person类中age和name是属性,speak是行为。对象是类的实例,每个对象的属性都属于对象本身,但是每个对象的行为却是公共的。举个例子,比如我们现在基于Person类创建了两个对象,personA和personB:

    f50e20ee45288eb5110ead92d5a1af3f.png

    personA和personB有各自的姓名和年龄,但是有共同的行为:speak。想象一下,如果我们是Java语言的设计者,我们会怎么存储对象的行为和属性呢?

    “很简单,属性跟着对象走,每个对象都存一份。行为是公共的东西,抽离出来,单独放到一个地方。”

    “咦?抽离出公共的部分,跟代码复用好像啊。”

    “大道至简,很多东西本来都是殊途同归。”

    也就是说,第一步我们首先得找到存储对象行为的这个公共的地方。一番搜索之后,我们发现这样一段描述:

    Method area is created on virtual machine startup, shared among all Java virtual machine threads and it is logically part of heap area. It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors.

    Java的对象行为(方法、函数)是存储在方法区的。

    “方法区中的数据从哪来?”

    “方法区中的数据是类加载时从class文件中提取出来的。”

    “class文件从哪来?”

    “从Java或者其他符合JVM规范的源代码中编译而来。”

    “源代码从哪来?”

    “废话,当然是手写!”

    “倒着推,手写没问题,编译没问题,至于加载……有没有办法加载一个已经加载过的类呢?如果有的话,我们就能修改字节码中目标方法所在的区域,然后重新加载这个类,这样方法区中的对象行为(方法)就被改变了,而且不改变对象的属性,也不影响已经存在对象的状态,那么就可以搞定这个问题了。可是,这岂不是违背了JVM的类加载原理?毕竟我们不想改变ClassLoader。”

    “少年,可以去看看java.lang.instrument.Instrumentation。”

    java.lang.instrument.Instrumentation

    看完文档之后,我们发现这么两个接口:redefineClasses和retransformClasses。一个是重新定义class,一个是修改class。这两个大同小异,看redefineClasses的说明:

    This method is used to replace the definition of a class without reference to the existing class file bytes, as one might do when recompiling from source for fix-and-continue debugging. Where the existing class file bytes are to be transformed (for example in bytecode instrumentation) retransformClasses should be used.

    都是替换已经存在的class文件,redefineClasses是自己提供字节码文件替换掉已存在的class文件,retransformClasses是在已存在的字节码文件上修改后再替换之。

    当然,运行时直接替换类很不安全。比如新的class文件引用了一个不存在的类,或者把某个类的一个field给删除了等等,这些情况都会引发异常。所以如文档中所言,instrument存在诸多的限制:

    The redefinition may change method bodies, the constant pool and attributes. The redefinition must not add, remove or rename fields or methods, change the signatures of methods, or change inheritance. These restrictions maybe be lifted in future versions. The class file bytes are not checked, verified and installed until after the transformations have been applied, if the resultant bytes are in error this method will throw an exception.

    我们能做的基本上也就是简单修改方法内的一些行为,这对于我们开头的问题,打印一段日志来说,已经足够了。当然,我们除了通过retransform来打印日志,还能做很多其他非常有用的事情,这个下文会进行介绍。

    那怎么得到我们需要的class文件呢?一个最简单的方法,是把修改后的Java文件重新编译一遍得到class文件,然后调用redefineClasses替换。但是对于没有(或者拿不到,或者不方便修改)源码的文件我们应该怎么办呢?其实对于JVM来说,不管是Java也好,Scala也好,任何一种符合JVM规范的语言的源代码,都可以编译成class文件。JVM的操作对象是class文件,而不是源码。所以,从这种意义上来讲,我们可以说“JVM跟语言无关”。既然如此,不管有没有源码,其实我们只需要修改class文件就行了。

    直接操作字节码

    Java是软件开发人员能读懂的语言,class字节码是JVM能读懂的语言,class字节码最终会被JVM解释成机器能读懂的语言。无论哪种语言,都是人创造的。所以,理论上(实际上也确实如此)人能读懂上述任何一种语言,既然能读懂,自然能修改。只要我们愿意,我们完全可以跳过Java编译器,直接写字节码文件,只不过这并不符合时代的发展罢了,毕竟高级语言设计之始就是为我们人类所服务,其开发效率也比机器语言高很多。

    对于人类来说,字节码文件的可读性远远没有Java代码高。尽管如此,还是有一些杰出的程序员们创造出了可以用来直接编辑字节码的框架,提供接口可以让我们方便地操作字节码文件,进行注入修改类的方法,动态创造一个新的类等等操作。其中最著名的框架应该就是ASM了,cglib、Spring等框架中对于字节码的操作就建立在ASM之上。

    我们都知道,Spring的AOP是基于动态代理实现的,Spring会在运行时动态创建代理类,代理类中引用被代理类,在被代理的方法执行前后进行一些神秘的操作。那么,Spring是怎么在运行时创建代理类的呢?动态代理的美妙之处,就在于我们不必手动为每个需要被代理的类写代理类代码,Spring在运行时会根据需要动态地创造出一个类。这里创造的过程并非通过字符串写Java文件,然后编译成class文件,然后加载。Spring会直接“创造”一个class文件,然后加载,创造class文件的工具,就是ASM了。

    到这里,我们知道了用ASM框架直接操作class文件,在类中加一段打印日志的代码,然后retransform就可以了。

    BTrace

    截止到目前,我们都是停留在理论描述的层面。那么如何进行实现呢?先来看几个问题:

    1. 在我们的工程中,谁来做这个寻找字节码,修改字节码,然后retransform的动作呢?我们并非先知,不可能知道未来有没有可能遇到文章开头的这种问题。考虑到性价比,我们也不可能在每个工程中都开发一段专门做这些修改字节码、重新加载字节码的代码。
    2. 如果JVM不在本地,在远程呢?
    3. 如果连ASM都不会用呢?能不能更通用一些,更“傻瓜”一些。

    幸运的是,因为有BTrace的存在,我们不必自己写一套这样的工具了。什么是BTrace呢?BTrace已经开源,项目描述极其简短:

    A safe, dynamic tracing tool for the Java platform.

    BTrace是基于Java语言的一个安全的、可提供动态追踪服务的工具。BTrace基于ASM、Java Attach API、Instrument开发,为用户提供了很多注解。依靠这些注解,我们可以编写BTrace脚本(简单的Java代码)达到我们想要的效果,而不必深陷于ASM对字节码的操作中不可自拔。

    看BTrace官方提供的一个简单例子:拦截所有http://java.io包中所有类中以read开头的方法,打印类名、方法名和参数名。当程序IO负载比较高的时候,就可以从输出的信息中看到是哪些类所引起,是不是很方便?

    67e72c73c207849df16fae7a17b9e3f2.png

    再来看另一个例子:每隔2秒打印截止到当前创建过的线程数。

    b744a6429d047503b2afb99173041f05.png

    c6b6fb46ad6397e4755e33ec0a777de1.png

    看了上面的用法是不是有所启发?忍不住冒出来许多想法。比如查看HashMap什么时候会触发rehash,以及此时容器中有多少元素等等。

    有了BTrace,文章开头的问题可以得到完美的解决。至于BTrace具体有哪些功能,脚本怎么写,这些Git上BTrace工程中有大量的说明和举例,网上介绍BTrace用法的文章更是恒河沙数,这里就不再赘述了。

    我们明白了原理,又有好用的工具支持,剩下的就是发挥我们的创造力了,只需在合适的场景下合理地进行使用即可。

    既然BTrace能解决上面我们提到的所有问题,那么BTrace的架构是怎样的呢?

    BTrace主要有下面几个模块:

    1. BTrace脚本:利用BTrace定义的注解,我们可以很方便地根据需要进行脚本的开发。
    2. Compiler:将BTrace脚本编译成BTrace class文件。
    3. Client:将class文件发送到Agent。
    4. Agent:基于Java的Attach API,Agent可以动态附着到一个运行的JVM上,然后开启一个BTrace Server,接收client发过来的BTrace脚本;解析脚本,然后根据脚本中的规则找到要修改的类;修改字节码后,调用Java Instrument的retransform接口,完成对对象行为的修改并使之生效。

    整个BTrace的架构大致如下:

    7d54323fc1000d1652de0e7baa3916b4.png

    BTrace最终借Instrument实现class的替换。如上文所说,出于安全考虑,Instrument在使用上存在诸多的限制,BTrace也不例外。BTrace对JVM来说是“只读的”,因此BTrace脚本的限制如下:

    1.不允许创建对象
    2.不允许创建数组
    3.不允许抛异常
    4.不允许catch异常
    5.不允许随意调用其他对象或者类的方法,只允许调用com.sun.btrace.BTraceUtils中提供的静态方法(一些数据处理和信息输出工具)
    6.不允许改变类的属性
    7.不允许有成员变量和方法,只允许存在static public void方法
    8.不允许有内部类、嵌套类
    9.不允许有同步方法和同步块
    10.不允许有循环
    11.不允许随意继承其他类(当然,java.lang.Object除外)
    12.不允许实现接口
    13.不允许使用assert
    14.不允许使用Class对象

    如此多的限制,其实可以理解。BTrace要做的是,虽然修改了字节码,但是除了输出需要的信息外,对整个程序的正常运行并没有影响。

    Arthas

    BTrace脚本在使用上有一定的学习成本,如果能把一些常用的功能封装起来,对外直接提供简单的命令即可操作的话,那就再好不过了。阿里的工程师们早已想到这一点,就在去年,阿里巴巴开源了自己的Java诊断工具——Arthas

    Arthas提供简单的命令行操作,功能强大。究其背后的技术原理,和本文中提到的大致无二。Arthas的文档很全面,想详细了解的话可以戳这里。

    本文旨在说明Java动态追踪技术的来龙去脉,掌握技术背后的原理之后,只要愿意,各位读者也可以开发出自己的“冰封王座”出来。

    三生万物

    现在,让我们试着站在更高的地方“俯瞰”这些问题。

    Java的Instrument给运行时的动态追踪留下了希望,Attach API则给运行时动态追踪提供了“出入口”,ASM则大大方便了“人类”操作Java字节码的操作。

    基于Instrument和Attach API前辈们创造出了诸如JProfiler、Jvisualvm、BTrace这样的工具。以ASM为基础发展出了cglib、动态代理,继而是应用广泛的Spring AOP。

    Java是静态语言,运行时不允许改变数据结构。然而,Java 5引入Instrument,Java 6引入Attach API之后,事情开始变得不一样了。虽然存在诸多限制,然而,在前辈们的努力下,仅仅是利用预留的近似于“只读”的这一点点狭小的空间,仍然创造出了各种大放异彩的技术,极大地提高了软件开发人员定位问题的效率。

    计算机应该是人类有史以来最伟大的发明之一,从电磁感应磁生电,到高低电压模拟0和1的比特,再到二进制表示出几种基本类型,再到基本类型表示出无穷的对象,最后无穷的对象组合交互模拟现实生活乃至整个宇宙。

    两千五百年前,《道德经》有言:“道生一,一生二,二生三,三生万物。”

    两千五百年后,计算机的发展过程也大抵如此吧。

    展开全文
  • 这才是今天让我大开眼界的地方 操作呢也有一点点复杂。还是以慕课网为例吧。。其实哪个网站都可以,只要有评论功能都可以的吧。 ...。...评论之前先打开 开发者工具--NetWork--发表评论---会多出来一个docomment(哇真的...

     

    这才是今天让我大开眼界的地方

    操作呢也有一点点复杂。还是以慕课网为例吧。。其实哪个网站都可以,只要有评论功能都可以的吧。

    http://www.imooc.com/comment/348 进到这里,注册个账号再操作哈,否则可能会被拦截,另外成功后不要只顾爽,万一被封号。。

     评论之前先打开 开发者工具--NetWork--发表评论---会多出来一个docomment(哇真的是这个名字害惨我了)--Request headers复制出来,随便找个地方先放着,页面不要关。

    新建文件

    var http = require('http')
    var querystring = require('querystring')
    
    var postData = querystring.stringify({
        'content':'测试一下2',
        'cid':348
    })
    var options={
        hostname:'www.imooc.com',
        port:80,
        path:'/course/docomment',//一定要认真复制过来
        method:'POST',
        headers:{
            //复制过来的,修改:键值对,要加上单引号
            //content-length:postData.length
        }
    }
    
    
    
    var req=http.request(options,function(res){
        console.log('Status:'+res.statusCode)
        console.log('headers:'+JSON.stringify(res.headers))
    
        res.on('data',function(chunk){
            console.log(Buffer.isBuffer(chunk))
            console.log(typeof chunk)
        })
        res.on('end',function(){
            console.log('评论完毕')
        })
    
    })
    req.on('error',function(e){
        console.log('Error',e.message)
    })
    req.write(postData)
    req.end()
    

      headers里边是刚刚复制下来的代码,但要做一些改动,添加单引号和逗号:

     'Accept':'application/json, text/javascript, */*; q=0.01',
            'Accept-Encoding':'gzip, deflate',
            'Accept-Language':'zh-CN,zh;q=0.8',
            'Connection':'keep-alive',
            'Content-Length':postData.length,//不要加引号
            'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8',
            'Cookie':'UM_distinctid=15beabcd1b7131-0149534ca2496d-396b4e08-100200-15beabcd1b91b2; imooc_uuid=72ef5436-b5ca-4fad-aa51-a6a68657e678; imooc_isnew_ct=1494291895; wf_tid=b434831d8868; wf_rid=0cc03c1a020f; CNZZDATA1261110065=398582083-1494286575-https%253A%252F%252Fwww.baidu.com%252F%7C1499496727; loginstate=1; apsid=QxMjhhMWQ4MjhiMzFkMDI3ZGI4MjgwZjg0OTVmZjYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzAwMjIyOQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGY3YWRjMjA0N2QxZDcxMzI3NDE3ZDc0ZWJkN2ZmZWVhnG9lWZxvZVk%3DMW; PHPSESSID=uviejkunukoenifojgf4jad9i4; IMCDNS=0; Hm_lvt_f0cfcccd7b1393990c78efdeebff3968=1499875108,1499920320,1499924161,1499943591; Hm_lpvt_f0cfcccd7b1393990c78efdeebff3968=1499947257; imooc_isnew=2; cvde=596752a7d1e51-30',
            'Host':'www.imooc.com',
            'Origin':'http://www.imooc.com',
            'Referer':'http://www.imooc.com/comment/348',
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
            'X-Requested-With':'XMLHttpRequest'
            //复制过来的,修改:键值对,要加上单引号
            //content-length:postData.length
    

      耗了不少时间,出现过status:302  和 404,也是找了好久的错误。

    302就是postData那个地方加了单引号。

    404就是docomment写成了document。。。长的很像的好不好。。。。

     

     

     

     

     status 是200才可以成功的。

     

     哇 我可以做水军了么O(∩_∩)O

    转载于:https://www.cnblogs.com/Amy-is-a-fish-yeah/p/7163838.html

    展开全文
  • C++中修改文件夹以及文件名

    万次阅读 2015-11-01 16:08:14
    我们可以通过程序来修改已经存在的文件夹或是文件的命名。之前没有尝试过,因为需要一些复杂的操作。但是殊不知,仅仅一个rename函数就可以搞定,自惭形秽。直接上代码吧:#include #include #include<Windows.h>...

    我们可以通过程序来修改已经存在的文件夹或是文件的命名。

    之前没有尝试过,因为需要一些复杂的操作。

    但是殊不知,仅仅一个rename函数就可以搞定,自惭形秽。

    直接上代码吧:

    #include <iostream>
    #include <fstream>
    #include<Windows.h>
    
    int WINAPI WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
    {
        std::string original_name = "D:\\originalname";
        std::string new_name= "D:\\newname";
        std::fstream f;
        f.open(original_name.c_str());
        if (f)
        {
            rename(original_name.c_str(), new_name.c_str());
            MessageBox(NULL, TEXT("RENAME SUCCESS"), NULL, NULL);
            f.close();
        }
        else
        {
            MessageBox(NULL, TEXT("NO FILE"), NULL, NULL);
            f.close();
    
        }
    
        return 0;
    }

    简单极了。主要就是设计到一些IO的知识。

    展开全文
  • FlyWeightFactory负责创建和管理享元单元,当一个客户端请求时,工厂需要检查当前对象池中是否有符合条件的对象,如果有,就返回已经存在的对象,如果没有,则创建一个新对象,FlyWeight是超类。一提到共享池,我们...

    享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。

    这里写图片描述

    FlyWeightFactory负责创建和管理享元单元,当一个客户端请求时,工厂需要检查当前对象池中是否有符合条件的对象,如果有,就返回已经存在的对象,如果没有,则创建一个新对象,FlyWeight是超类。一提到共享池,我们很容易联想到Java里面的JDBC连接池,想想每个连接的特点,我们不难总结出:适用于作共享的一些个对象,他们有一些共有的属性,就拿数据库连接池来说,url、driverClassName、username、password及dbname,这些属性对于每个连接来说都是一样的,所以就适合用享元模式来处理,建一个工厂类,将上述类似属性作为内部数据,其它的作为外部数据,在方法调用时,当做参数传进来,这样就节省了空间,减少了实例的数量。

    数据库连接池的代码:
    public class ConnectionPool {
    private Vector pool;
    /公有属性/
    private String url = “jdbc:mysql://localhost:3306/test”;
    private String username = “root”;
    private String password = “root”;
    private String driverClassName = “com.mysql.jdbc.Driver”;
    private int poolSize = 100;
    private static ConnectionPool instance = null;
    Connection conn = null;
    /构造方法,做一些初始化工作/
    private ConnectionPool() {
    pool = new Vector(poolSize);
    for (int i = 0; i < poolSize; i++) {
    try {
    Class.forName(driverClassName);
    conn = DriverManager.getConnection(url, username, password);
    pool.add(conn);
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    }
    /* 返回连接到连接池 /
    public synchronized void release() {
    pool.add(conn);
    }
    /
    返回连接池中的一个数据库连接 */
    public synchronized Connection getConnection() {
    if (pool.size() > 0) {
    Connection conn = pool.get(0);
    pool.remove(conn);
    return conn;
    } else {
    return null;
    }
    }
    }

    通过连接池的管理,实现了数据库连接的共享,不需要每一次都重新创建连接,节省了数据库重新创建的开销,提升了系统的性能!

    展开全文
  • 今天要吧SQL的表数据到到oralce中,就用SQL自带的DTS导了。 中途遇到oracle"无法打开监听"的问题,想起昨天改了机器,把 oracle net manager打开一...服务里可以启动监听了,但是用PLSQL Developer登录已经提示“...
  • 当你点进这篇文章的时候,一定会好奇我为什么要用“心酸”这个词,这个词已经太久没被人提起,也许心酸这种感情只能存在于一个人在追中梦想过程中内心角落吧。从小我们总是会被问这样一个问题“你的梦想是什么?”每...
  • Zookeeper简介 在上班之前都不知道有这样一个东西,在开始说假死脑裂之前先说说Zookeeper吧。 Zookeeper zookeeper是一个分布式应用程序的协调服务。...Paxos算法为基础,paxos算法存在活锁的问题,即...
  • 备忘录模式是一个非常简单的设计模式,简单到已经让我们忽略了这种设计模式的存在了。备忘录模式这个名字可能还是有人会觉得稍微有点陌生,但是它的另一个名字快照模式听起来可能心里就会有点明白这到底是一种什么...
  • 尽管已经被重写)。那么如何判断是否在类似 IE 8 这样的环境中呢?underscore 中有个 hasEnumBug 函数就是用来做这个判断的: <pre><code> javascript // Keys in IE < 9 that won't be ...
  • $("#namediv").html("用户名已经存在"); }else{ //不为空了,按钮一直显示 var ui =document.getElementById("tijiao"); ui.style.display=""; $("#...
  • 本篇文章将为大家带来JVM进行监控和故障诊断常用的命令行工具,如下图:其中jps、jstat、jinfo、jmap、jhat、jstack从JDK 1.5开始就已经存在,jcmd是在JDK 1.7引入的。jps格式:jps [参数] [远程主机,需要远程...
  • 1.假如现在已经建好为'news'的数据库,此时在F:\oracle\product\10.1.0\oradata\目录下已经存在news目录(注意:我的Oracle10g安装在F:\oracle下,若你的Oracle安装在别的目录,那么你新建的数据库目录就在*\...
  • 先来个自我介绍吧,我就是你们口中的路由,我的作用就是告诉你们怎么到达某地,比如你想去一个地方(前提是这个地方是已经存在的)我会查询我的路线图(路由配置)告诉你怎么过去。明白了吧,我的作用就是给你们导航...
  •  在安全领域中,“攻”“防”一直在持续着,并且很不幸,攻击者永远处于主动地位,一切防御方案都是基于已经发生的攻击来制定的,但是深入理解原理,不仅可以快速应对攻击,也能从中推测出一些可能的衍生攻击方案并...
  • Google正在建造自己的互联网!

    千次阅读 2006-02-06 10:55:00
    Google似乎是无所不能的,至少,我是这样认为的。如果你刚好也有这种想法,那么你...在这个年头,这种事情一点也不奇怪,因为那个曾经是“著名的谣言”——Google正在开始自己的操作系统——几天前已经正式被Google确认
  • java构造函数,也叫构造方法,是java中一种特殊的函数。函数与相同,无返回值。方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法。下面我们来详细了解一下它们吧
  • 需求:比如说我要注册一个用户首先有名字输入框,然后是一组checkbox选择框,当我点击注册之后发现名字已经存在了,我又要回到这个注册页面上,并且原来已经勾选的要选上(用struts2的标签)。 解决:对于这个问题...
  • swift 关于 typealias

    2016-08-30 09:51:15
    好吧看到了这个typealias 有道词典翻译是 ” 类型别名“ 翻译很到位 下面就来说说吧 typealisa 简单使用 ...说白了就是给 某个已经存在的类型 改一个姓名字 昵称 以便于好理解 好记 上面的point就是 C
  • Mybatis之逆向工程

    2019-03-22 18:37:44
    首先逆向工程的作用就是帮我们把 已经存在的数据表 生成他们的pojo对象。 接下来,我们开始逆向工程吧~ 建立一个数据库,为 codepay /* Navicat MySQL Data Transfer Source Server : 本地 Source Server ...
  • 提交了4、5个新的app,以及每个版本更新了十几次版本之后,... 首先来说下新app的提交吧~ 很多时候会碰到创建新app的时候发现名字已经存在不能使用该名字创建了,那怎么办呢!就我所知的办法有两个: 1、 你可以...
  • node-发布npm包

    2019-07-23 12:37:13
    登录 首先你需要去注册一个npm账户 ...创建完成以后,切换到项目目录,npm login ... 执行npm publish ...百度一下,说是因为npm包里已经存在node-learn这个包了,好吧,我们修改下名字 重新执行npm publish, ...
  • 与App Store审核的斗智斗勇管理提醒:本帖被 fm2010 执行加亮操作(2015-10-08)第一次在这里发,也不... 首先来说下新app的提交吧~ 很多时候会碰到创建新app的时候发现名字已经存在不能使用该名字创建了,那怎么办呢...
  • 您好,您的官网认证申请,因为申请不符合要求,该网站名存在多个官网,且您的域名并非唯一的官网 ,没有通过。如果您的填写资料有误,可在3个工作日后重新提交。​ ​ ​ 好吧 申请官网的时候 回复的审核内容是...

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 234
精华内容 93
关键字:

吧名已经存在