前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >20190312_浅谈go&java差异(一)

20190312_浅谈go&java差异(一)

作者头像
上帝
发布2019-03-19 16:14:38
7790
发布2019-03-19 16:14:38
举报
文章被收录于专栏:影子
多线程
  • java

java中对于大量的比较耗时的任务多采用多线程对方式对任务进行处理,同时由于进程和线程 本身是通过宿主机OS进行管理的,当在cpu核数较少或线程分配不当 会导致多线程的效果不佳的事常有发生

代码片段:

代码语言:javascript
复制
    //处理器核心数
    int processor = Runtime.getRuntime().availableProcessors();
    //XSSFWorkbook 一次只能写入六万多条数据,所以这里最好使用SXSSFWorkbook
    SXSSFWorkbook workBook = new SXSSFWorkbook();
    //创建格式
    CellStyle style = workBook.createCellStyle();
    //居中格式
    style.setAlignment(HorizontalAlignment.CENTER);
    //手工创建线程池
    ExecutorService executorService = new ThreadPoolExecutor(processor, processor, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingDeque(),
            new ThreadFactoryBuilder().setNameFormat("poi-task-%d").build());
    //计数器 等待线程池中的线程执行完毕
    CountDownLatch countDownLatch = new CountDownLatch(processor);
    for (int i = 0; i < processor; i++) {
        int sheetId = i;
        //放入线程池中
        executorService.execute(() -> createSheet(workBook, style,sheetId, countDownLatch));
    }
    try {
        //等待所有线程执行完毕
        countDownLatch.await();
        executorService.shutdown();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
  • go 由于进程和线程都是基于OS管理的,不可避免的产生开销;go区别与以上两者使用的是协程(goroutine),协程是线程的内的细颗粒化, 同时它是被go自己管理的所以开销相当的小,同时一个go应用可以轻松构建上百万个goroutine,不仅如此,go也提供了通道(channel)方便 对协程之间进行数据交互

代码片段:

代码语言:javascript
复制
import (
    "fmt"
    "sync"
)

func says(s string, gw *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        fmt.Println(">>> ", s)
    }
    gw.Done()
}
func main() {
    var gw sync.WaitGroup
    gw.Add(1)
    go says("Hello s", &gw)
    gw.Wait()
}
函数参数传递
  • java

java对于函数值对传递采取对是值传递的方式,对于基本数据类型:传递前后值所在栈的位置是不一致的(也就是被拷贝了一份) 对于非基本数据类型:虽然也会做拷贝,但实际上这前后的对象引用的是同一内存位置的值,这就造成了"引用传递的假象"

代码片段:

代码语言:javascript
复制
public class TransParams {

    public static void main(String[] args){
        Person p = new Person();
        p.setAge(99);
        p.setName("Lisa");

        System.out.println(p.getAge());
        System.out.println(p);
        System.out.println("======>split<=====");

        TransParams tp = new TransParams();
        tp.setValue(p);
        System.out.println(p.getAge());
        System.out.println(p);
    }

    public  void setValue(Person p){
        p.setAge(19);
    }
}
class Person {
    private Integer age;
    private String name;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

运行结果:

代码语言:javascript
复制
   99
   com.task.charset.Person@7e0b37bc
   ======>split<=====
   19
   com.task.charset.Person@7e0b37bc
  • go go语言的处理方式不同于java,具体分两个种:拷贝传递 和 指针传递 对于拷贝传递:不论是基本数据类型还是结构体类型,前后的值都不会是同一个 对于引用传递:传递前后都是同一个值对象,不会存在java的理解歧义 代码片段:
代码语言:javascript
复制
import "fmt"

func main() {
    var s1 []string
    fmt.Println("拷贝传递前>", s1)
    tr01(s1)
    fmt.Println("拷贝传递后>", s1)

    fmt.Println("=====><=====")

    var s2 []string
    fmt.Println("指针传递前>", s2)
    tr02(&s2)
    fmt.Println("指针传递后>", s2)
}

func tr01(m []string) {
    m = append(m, "youth01")
}

func tr02(mm *[]string) {
    *mm = append(*mm, "youth02")
}

输出结果:

代码语言:javascript
复制
拷贝传递前> []
拷贝传递后> []
=====><=====
指针传递前> []
指针传递后> [youth02]
日期格式处理
  • java

在java8之前jdk仅提供了Date类型的格式化,对应的日期处理类是SimpleDateFormat, 在java8至java8之后Oracle提供了LocalDate与LocalDateTime的两种日期格式,对应的日期处理类是DateTimeFormat

代码片段:

代码语言:javascript
复制
public class Format2LocalDate {
    private static final Logger LOG = LoggerFactory.getLogger(Format2LocalDate.class);

    private static final DateTimeFormatter DATE_FORMAT_SHORT = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss");

    @Test
    public void transDate(){
        this.parse();
        this.format();
        LOG.info(".....................");
        this.parseD();
        this.formatD();
    }
    public void parse(){
        String str = "20190116 12:12:22";
        Date today = Date.from(LocalDateTime.parse(str,DATE_FORMAT_SHORT).atZone(DateUtil.CHINA_ZONE_ID).toInstant());
        LOG.info("转换结果为> {}",today);
    }

    public void format(){
        LocalDateTime ldt = LocalDateTime.now();
        LOG.info("格式化字符串> {}",ldt.format(DATE_FORMAT_SHORT));

    }


    public final static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";


    public void parseD(){
        String dateStr = "2019-01-01 12:22:33";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT);
        Date date = null;
        try {
             date =  simpleDateFormat.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        LOG.info("转换结果为> {}",date);
    }

    public void formatD(){
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT);

        LOG.info("格式化结果为> {}",simpleDateFormat.format(date));

    }
}

输出结果为:

代码语言:javascript
复制
转换结果为> Wed Jan 16 12:12:22 CST 2019
格式化字符串> 20190313 21:20:23
.....................
转换结果为> Tue Jan 01 12:22:33 CST 2019
格式化结果为> 2019-03-13 21:20:23
  • go go的日期处理相对于java来说十分的怪异,官方给出的例子是个固定的日期字符串,并非"yyyymmdd"这种形式,这里就不用说了 看代码 代码片段:
代码语言:javascript
复制
/**
  官方定义的不可更改
*/
const DATE_FORMAT string = "2006-01-02 15:04:05"

func main() {
    parse()
    format()
}

func parse() {
    tm := time.Now()
    strs := tm.Format(DATE_FORMAT)
    fmt.Println("日期转换为字符串> ", strs)
}
func format() {
    tm, _ := time.Parse(DATE_FORMAT, "2019-01-01 12:12:12")
    fmt.Println("字符串转换为日期> ", tm)
}

运行结果:

代码语言:javascript
复制
日期转换为字符串>  2019-03-13 21:29:30
字符串转换为日期>  2019-01-01 12:12:12 +0000 UTC
数学运算
  • java java的数学基本运算往往会有精度丢失问题,所以对于敏感运算建议使用BigDecimal 代码片段:
代码语言:javascript
复制
//加减乘除都出现了对应的精度问题
public class MathCalcul {
    private static final Logger LOG = LoggerFactory.getLogger(MathCalcul.class);

    @Test
    public void calcul(){
        LOG.info("加: {}",0.1 + 0.2);
        LOG.info("减: {}",1.1 - 0.11);
        LOG.info("乘: {}",1.13 * 100);
        LOG.info("除: {}",100.13 / 100);
    }
}

输出结果:

代码语言:javascript
复制
加: 0.30000000000000004
减: 0.9900000000000001
乘: 112.99999999999999
除: 1.0012999999999999
  • go go 不存在精度丢失问题,可以看代码可知
代码语言:javascript
复制
func main() {
    fmt.Println("加: ", 0.1+0.2)
    fmt.Println("减: ", 1.1-0.11)
    fmt.Println("乘: ", 1.13*100)
    fmt.Println("除: ", 100.13/100)
}

输出结果:

代码语言:javascript
复制
加:  0.3
减:  0.99
乘:  113
除:  1.0013
http Server
  • java java的http Server是基于Servlet,应对高并发时的策略是多线程,处理效率一般 代码示例:
代码语言:javascript
复制
class MyServlet extends HttpServlet{
    private static final ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings");

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_get_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(405, msg);
        } else {
            resp.sendError(400, msg);
        }

    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_post_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(405, msg);
        } else {
            resp.sendError(400, msg);
        }

    }
}
  • go go 源码是自带http包的,所以无需第三方封装,开发较为简单;应对高并发时的策略是多协程,处理效果较好 代码示例:
代码语言:javascript
复制
import (
    "fmt"
    "net/http"
)

func index_handle(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Whoa,Go is cool!")
}
func main() {
    http.HandleFunc("/", index_handle)
    http.ListenAndServe(":8000", nil)
}
常量与静态变量
  • java java 中常量(final) 与 静态(static) 是分开的,常量:只能动态赋值一次后不可改变 静态:类型不变 示例:
代码语言:javascript
复制
//静态
public static String str  = "hello";
//常量
public final String str2 = "hello2";
//不可变量(初始化后不可重新赋值)
public static final String str3 = "hello3";
  • go go 没有静态一说,只有常量(const)一说,在初始化后不能改变,其实就相当于 java中的 final + static 示例:
代码语言:javascript
复制
const str string = "hello"

__本章就到这里吧,敬请期待下一讲。(^_^)__

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-03-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 多线程
  • 函数参数传递
  • 日期格式处理
  • 数学运算
  • http Server
  • 常量与静态变量
相关产品与服务
专用宿主机
专用宿主机(CVM Dedicated Host,CDH)提供用户独享的物理服务器资源,满足您资源独享、资源物理隔离、安全、合规需求。专用宿主机搭载了腾讯云虚拟化系统,购买之后,您可在其上灵活创建、管理多个自定义规格的云服务器实例,自主规划物理资源的使用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档