首页 文章 精选 留言 我的

精选列表

搜索[前端工程师],共10000篇文章
优秀的个人博客,低调大师

Java工程师如何写出高效代码?

1.常量&变量 1.1.直接赋值常量值,禁止声明新对象 直接赋值常量值,只是创建了一个对象引用,而这个对象引用指向常量值。 反例:Long i = new Long(1L);String s = new String("abc"); 正例:Long i = 1L;String s = "abc"; 1.2.当成员变量值无需改变时,尽量定义为静态常量 在类的每个对象实例中,每个成员变量都有一份副本,而成员静态常量只有一份实例。 反例:public class HttpConnection { private final long timeout = 5L; ... } 正例:public class HttpConnection { private static final long TIMEOUT = 5L; ... } 1.3.尽量使用基本数据类

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

Java工程师该如何编写高效代码?

阿里妹导读:世界上只有两种物质:高效率和低效率;世界上只有两种人:高效率的人和低效率的人。——萧伯纳同理,世界上只有两种代码:高效代码和低效代码;世界上只有两种人:编写高效代码的人和编写低效代码的人。如何编写高效代码,是每个研发团队都面临的一个重大问题。本文作者根据实际经验,查阅了大量资料,总结了"Java高效代码50例",让每一个Java程序员都能编写出"高效代码"。 1.常量&变量 1.1.直接赋值常量值,禁止声明新对象 直接赋值常量值,只是创建了一个对象引用,而这个对象引用指向常量值; 反例: Long i = new Long(1L); String s = new String("abc"); 正例: Long i = 1L; String s = "abc"; 1.2.当成员变量值无需改变时,尽量定义为静态常量 在类的每个对象实例中,每个成员变量都有一份副本,而成员静态常量只有一份实例。 反例: public class HttpConnection { private final long timeout = 5L; ... } 正例: public class HttpConnection { private static final long TIMEOUT = 5L; ... } 1.3.尽量使用基本数据类型,避免自动装箱和拆箱 Java 中的基本数据类型double、float、long、int、short、char、boolean,分别对应包装类Double、Float、Long、Integer、Short、Character、Boolean。JVM支持基本类型与对应包装类的自动转换,被称为自动装箱和拆箱。装箱和拆箱都是需要CPU和内存资源的,所以应尽量避免使用自动装箱和拆箱。 反例: Integer sum = 0; int[] values = ...; for (int value : values) { sum += value; // 相当于result = Integer.valueOf(result.intValue() + value); } 正例: int sum = 0; int[] values = ...; for (int value : values) { sum += value; } 1.4.如果变量的初值会被覆盖,就没有必要给变量赋初值 反例: List<UserDO> userList = new ArrayList<>(); if (isAll) { userList = userDAO.queryAll(); } else { userList = userDAO.queryActive(); } 正例: List<UserDO> userList; if (isAll) { userList = userDAO.queryAll(); } else { userList = userDAO.queryActive(); } 1.5.尽量使用函数内的基本类型临时变量 在函数内,基本类型的参数和临时变量都保存在栈(Stack)中,访问速度较快;对象类型的参数和临时变量的引用都保存在栈(Stack)中,内容都保存在堆(Heap)中,访问速度较慢。在类中,任何类型的成员变量都保存在堆(Heap)中,访问速度较慢。 反例: public final class Accumulator { private double result = 0.0D; public void addAll(@NonNull double[] values) { for(double value : values) { result += value; } } ... } 正例: public final class Accumulator { private double result = 0.0D; public void addAll(@NonNull double[] values) { double sum = 0.0D; for(double value : values) { sum += value; } result += sum; } ... } 1.6.尽量不要在循环体外定义变量 在老版JDK中,建议“尽量不要在循环体内定义变量”,但是在新版的JDK中已经做了优化。通过对编译后的字节码分析,变量定义在循环体外和循环体内没有本质的区别,运行效率基本上是一样的。 反而,根据“ 局部变量作用域最小化 ”原则,变量定义在循环体内更科学更便于维护,避免了延长大对象生命周期导致延缓回收问题 。 反例: UserVO userVO; List<UserDO> userDOList = ...; List<UserVO> userVOList = new ArrayList<>(userDOList.size()); for (UserDO userDO : userDOList) { userVO = new UserVO(); userVO.setId(userDO.getId()); ... userVOList.add(userVO); } 正例: List<UserDO> userDOList = ...; List<UserVO> userVOList = new ArrayList<>(userDOList.size()); for (UserDO userDO : userDOList) { UserVO userVO = new UserVO(); userVO.setId(userDO.getId()); ... userVOList.add(userVO); } 1.7.不可变的静态常量,尽量使用非线程安全类 不可变的静态常量,虽然需要支持多线程访问,也可以使用非线程安全类。 反例: public static final Map<String, Class> CLASS_MAP; static { Map<String, Class> classMap = new ConcurrentHashMap<>(16); classMap.put("VARCHAR", java.lang.String.class); ... CLASS_MAP = Collections.unmodifiableMap(classMap); } 正例: public static final Map<String, Class> CLASS_MAP; static { Map<String, Class> classMap = new HashMap<>(16); classMap.put("VARCHAR", java.lang.String.class); ... CLASS_MAP = Collections.unmodifiableMap(classMap); } 1.8.不可变的成员变量,尽量使用非线程安全类 不可变的成员变量,虽然需要支持多线程访问,也可以使用非线程安全类。 反例: @Service public class StrategyFactory implements InitializingBean { @Autowired private List<Strategy> strategyList; private Map<String, Strategy> strategyMap; @Override public void afterPropertiesSet() { if (CollectionUtils.isNotEmpty(strategyList)) { int size = (int) Math.ceil(strategyList.size() * 4.0 / 3); Map<String, Strategy> map = new ConcurrentHashMap<>(size); for (Strategy strategy : strategyList) { map.put(strategy.getType(), strategy); } strategyMap = Collections.unmodifiableMap(map); } } ... } 正例: @Service public class StrategyFactory implements InitializingBean { @Autowired private List<Strategy> strategyList; private Map<String, Strategy> strategyMap; @Override public void afterPropertiesSet() { if (CollectionUtils.isNotEmpty(strategyList)) { int size = (int) Math.ceil(strategyList.size() * 4.0 / 3); Map<String, Strategy> map = new HashMap<>(size); for (Strategy strategy : strategyList) { map.put(strategy.getType(), strategy); } strategyMap = Collections.unmodifiableMap(map); } } ... 2.对象&类 2.1.禁止使用JSON转化对象 JSON提供把对象转化为JSON字符串、把JSON字符串转为对象的功能,于是被某些人用来转化对象。这种对象转化方式,虽然在功能上没有问题,但是在性能上却存在问题。 反例: List<UserDO> userDOList = ...; List<UserVO> userVOList = JSON.parseArray(JSON.toJSONString(userDOList), UserVO.class); 正例: List<UserDO> userDOList = ...; List<UserVO> userVOList = new ArrayList<>(userDOList.size()); for (UserDO userDO : userDOList) { UserVO userVO = new UserVO(); userVO.setId(userDO.getId()); ... userVOList.add(userVO); } 2.2.尽量不使用反射赋值对象 用反射赋值对象,主要优点是节省了代码量,主要缺点却是性能有所下降。 反例: List<UserDO> userDOList = ...; List<UserVO> userVOList = new ArrayList<>(userDOList.size()); for (UserDO userDO : userDOList) { UserVO userVO = new UserVO(); BeanUtils.copyProperties(userDO, userVO); userVOList.add(userVO); } 正例: List<UserDO> userDOList = ...; List<UserVO> userVOList = new ArrayList<>(userDOList.size()); for (UserDO userDO : userDOList) { UserVO userVO = new UserVO(); userVO.setId(userDO.getId()); ... userVOList.add(userVO); } 2.3.采用Lambda表达式替换内部匿名类 对于大多数刚接触JDK8的同学来说,都会认为Lambda表达式就是匿名内部类的语法糖。实际上, Lambda表达式在大多数虚拟机中采用invokeDynamic指令实现,相对于匿名内部类在效率上会更高一些。 反例: List<User> userList = ...; Collections.sort(userList, new Comparator<User>() { @Override public int compare(User user1, User user2) { Long userId1 = user1.getId(); Long userId2 = user2.getId(); ... return userId1.compareTo(userId2); } }); 正例: List<User> userList = ...; Collections.sort(userList, (user1, user2) -> { Long userId1 = user1.getId(); Long userId2 = user2.getId(); ... return userId1.compareTo(userId2); }); 2.4.尽量避免定义不必要的子类 多一个类就需要多一份类加载,所以尽量避免定义不必要的子类。 反例: public static final Map<String, Class> CLASS_MAP = Collections.unmodifiableMap(new HashMap<String, Class>(16) { private static final long serialVersionUID = 1L; { put("VARCHAR", java.lang.String.class); } }); 正例: public static final Map<String, Class> CLASS_MAP; static { Map<String, Class> classMap = new HashMap<>(16); classMap.put("VARCHAR", java.lang.String.class); ... CLASS_MAP = Collections.unmodifiableMap(classMap); } 2.5.尽量指定类的final修饰符 为类指定final修饰符,可以让该类不可以被继承。如果指定了一个类为final,则该类所有的方法都是final的,Java编译器会寻找机会内联所有的final方法。内联对于提升Java运行效率作用重大,具体可参见Java运行期优化,能够使性能平均提高50%。 反例: public class DateHelper { ... } 正例: public final class DateHelper { ... } 注意:使用Spring的AOP特性时,需要对Bean进行动态代理,如果Bean类添加了final修饰,会导致异常。 3.方法 3.1.把跟类成员变量无关的方法声明成静态方法 静态方法的好处就是不用生成类的实例就可以直接调用。静态方法不再属于某个对象,而是属于它所在的类。只需要通过其类名就可以访问,不需要再消耗资源去反复创建对象。即便在类内部的私有方法,如果没有使用到类成员变量,也应该声明为静态方法。 反例: public int getMonth(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); return calendar.get(Calendar.MONTH) + 1; } 正例: public static int getMonth(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); return calendar.get(Calendar.MONTH) + 1; } 3.2.尽量使用基本数据类型作为方法参数类型,避免不必要的装箱、拆箱和空指针判断 反例: public static double sum(Double value1, Double value2) { double double1 = Objects.isNull(value1) ? 0.0D : value1; double double2 = Objects.isNull(value2) ? 0.0D : value2; return double1 + double2; } double result = sum(1.0D, 2.0D); 正例: public static double sum(double value1, double value2) { return value1 + value2; } double result = sum(1.0D, 2.0D); 3.3.尽量使用基本数据类型作为方法返回值类型,避免不必要的装箱、拆箱和空指针判断 在JDK类库的方法中,很多方法返回值都采用了基本数据类型,首先是为了避免不必要的装箱和拆箱,其次是为了避免返回值的空指针判断。比如:Collection.isEmpty()和Map.size()。 反例: public static Boolean isValid(UserDO user) { if (Objects.isNull(user)) { return false; } return Boolean.TRUE.equals(user.getIsValid()); } // 调用代码 UserDO user = ...; Boolean isValid = isValid(user); if (Objects.nonNull(isValid) && isValid.booleanValue()) { ... } 正例: public static boolean isValid(UserDO user) { if (Objects.isNull(user)) { return false; } return Boolean.TRUE.equals(user.getIsValid()); } // 调用代码 UserDO user = ...; if (isValid(user)) { ... } 3.4.协议方法参数值非空,避免不必要的空指针判断 协议编程,可以@NonNull和@Nullable标注参数,是否遵循全凭调用者自觉。 反例: public static boolean isValid(UserDO user) { if (Objects.isNull(user)) { return false; } return Boolean.TRUE.equals(user.getIsValid()); } 正例: public static boolean isValid(@NonNull UserDO user) { return Boolean.TRUE.equals(user.getIsValid()); } 3.5.协议方法返回值非空,避免不必要的空指针判断 协议编程,可以@NonNull和@Nullable标注参数,是否遵循全凭实现者自觉。 反例: // 定义接口 public interface OrderService { public List<OrderVO> queryUserOrder(Long userId); } // 调用代码 List<OrderVO> orderList = orderService.queryUserOrder(userId); if (CollectionUtils.isNotEmpty(orderList)) { for (OrderVO order : orderList) { ... } } 正例: // 定义接口 public interface OrderService { @NonNull public List<OrderVO> queryUserOrder(Long userId); } // 调用代码 List<OrderVO> orderList = orderService.queryUserOrder(userId); for (OrderVO order : orderList) { ... } 3.6.被调用方法已支持判空处理,调用方法无需再进行判空处理 反例: UserDO user = null; if (StringUtils.isNotBlank(value)) { user = JSON.parseObject(value, UserDO.class); } 正例: UserDO user = JSON.parseObject(value, UserDO.class); 3.7.尽量避免不必要的函数封装 方法调用会引起入栈和出栈,导致消耗更多的CPU和内存,应当尽量避免不必要的函数封装。当然,为了使代码更简洁、更清晰、更易维护,增加一定的方法调用所带来的性能损耗是值得的。 反例: // 函数封装 public static boolean isVip(Boolean isVip) { return Boolean.TRUE.equals(isVip); } // 使用代码 boolean isVip = isVip(user.getVip()); 正例: boolean isVip = Boolean.TRUE.equals(user.getVip()); 3.8.尽量指定方法的final修饰符 方法指定final修饰符,可以让方法不可以被重写,Java编译器会寻找机会内联所有的final方法。内联对于提升Java运行效率作用重大,具体可参见Java运行期优化,能够使性能平均提高50%。 注意:所有的private方法会隐式地被指定final修饰符,所以无须再为其指定final修饰符。 反例: public class Rectangle { ... public double area() { ... } } 正例: public class Rectangle { ... public final double area() { ... } } 注意:使用Spring的AOP特性时,需要对Bean进行动态代理,如果方法添加了final修饰,将不会被代理。 4.表达式 4.1.尽量减少方法的重复调用 反例: List<UserDO> userList = ...; for (int i = 0; i < userList.size(); i++) { ... } 正例: List<UserDO> userList = ...; int userLength = userList.size(); for (int i = 0; i < userLength; i++) { ... } 4.2.尽量避免不必要的方法调用 反例: List<UserDO> userList = userDAO.queryActive(); if (isAll) { userList = userDAO.queryAll(); } 正例: List<UserDO> userList; if (isAll) { userList = userDAO.queryAll(); } else { userList = userDAO.queryActive(); } 4.3.尽量使用移位来代替正整数乘除 用移位操作可以极大地提高性能。对于乘除2^n(n为正整数)的正整数计算,可以用移位操作来代替。 反例: int num1 = a * 4; int num2 = a / 4; 正例: int num1 = a << 2; int num2 = a >> 2; 4.4.提取公共表达式,避免重复计算 提取公共表达式,只计算一次值,然后重复利用值。 反例: double distance = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); 正例: double dx = x2 - x1; double dy = y2 - y1; double distance = Math.sqrt(dx * dx + dy * dy); 或 double distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); 4.5.尽量不在条件表达式中用!取反 使用!取反会多一次计算,如果没有必要则优化掉。 反例: if (!(a >= 10)) { ... // 条件处理1 } else { ... // 条件处理2 } 正例: if (a < 10) { ... // 条件处理1 } else { ... // 条件处理2 } 4.6.对于多常量选择分支,尽量使用switch语句而不是if-else语句 if-else语句,每个if条件语句都要加装计算,直到if条件语句为true为止。switch语句进行了跳转优化,Java中采用tableswitch或lookupswitch指令实现,对于多常量选择分支处理效率更高。经过试验证明:在每个分支出现概率相同的情况下,低于5个分支时if-else语句效率更高,高于5个分支时switch语句效率更高。 反例: if (i == 1) { ...; // 分支1 } else if (i == 2) { ...; // 分支2 } else if (i == ...) { ...; // 分支n } else { ...; // 分支n+1 } 正例: switch (i) { case 1 : ... // 分支1 break; case 2 : ... // 分支2 break; case ... : ... // 分支n break; default : ... // 分支n+1 break; } 备注:如果业务复杂,可以采用Map实现策略模式。 5.字符串 5.1.尽量不要使用正则表达式匹配 正则表达式匹配效率较低,尽量使用字符串匹配操作。 反例: String source = "a::1,b::2,c::3,d::4"; String target = source.replaceAll("::", "="); Stringp[] targets = source.spit("::"); 正例: String source = "a::1,b::2,c::3,d::4"; String target = source.replace("::", "="); Stringp[] targets = StringUtils.split(source, "::"); 5.2.尽量使用字符替换字符串 字符串的长度不确定,而字符的长度固定为1,查找和匹配的效率自然提高了。 反例: String source = "a:1,b:2,c:3,d:4"; int index = source.indexOf(":"); String target = source.replace(":", "="); 正例: String source = "a:1,b:2,c:3,d:4"; int index = source.indexOf(':'); String target = source.replace(':', '='); 5.3.尽量使用StringBuilder进行字符串拼接 String是final类,内容不可修改,所以每次字符串拼接都会生成一个新对象。StringBuilder在初始化时申请了一块内存,以后的字符串拼接都在这块内存中执行,不会申请新内存和生成新对象。 反例: String s = ""; for (int i = 0; i < 10; i++) { if (i != 0) { s += ','; } s += i; } 正例: StringBuilder sb = new StringBuilder(128); for (int i = 0; i < 10; i++) { if (i != 0) { sb.append(','); } sb.append(i); } 5.4.不要使用""+转化字符串 使用""+进行字符串转化,使用方便但是效率低,建议使用String.valueOf. 反例: int i = 12345; String s = "" + i; 正例: int i = 12345; String s = String.valueOf(i); 6.数组 6.1.不要使用循环拷贝数组,尽量使用System.arraycopy拷贝数组 推荐使用System.arraycopy拷贝数组,也可以使用Arrays.copyOf拷贝数组。 反例: int[] sources = new int[] {1, 2, 3, 4, 5}; int[] targets = new int[sources.length]; for (int i = 0; i < targets.length; i++) { targets[i] = sources[i]; } 正例: int[] sources = new int[] {1, 2, 3, 4, 5}; int[] targets = new int[sources.length]; System.arraycopy(sources, 0, targets, 0, targets.length); 6.2.集合转化为类型T数组时,尽量传入空数组T[0] 将集合转换为数组有2种形式:toArray(new T[n])和toArray(new T[0])。在旧的Java版本中,建议使用toArray(new T[n]),因为创建数组时所需的反射调用非常慢。在OpenJDK6后,反射调用是内在的,使得性能得以提高,toArray(new T[0])比toArray(new T[n])效率更高。此外,toArray(new T[n])比toArray(new T[0])多获取一次列表大小,如果计算列表大小耗时过长,也会导致toArray(new T[n])效率降低。 反例: List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, ...); Integer[] integers = integerList.toArray(new Integer[integerList.size()]); 正例: List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, ...); Integer[] integers = integerList.toArray(new Integer[0]); // 勿用new Integer[]{} 建议:集合应该提供一个toArray(Class clazz)方法,避免无用的空数组初始化(new T[0])。 6.3.集合转化为Object数组时,尽量使用toArray()方法 转化Object数组时,没有必要使用toArray[new Object[0]],可以直接使用toArray()。避免了类型的判断,也避免了空数组的申请,所以效率会更高。 反例: List<Object> objectList = Arrays.asList(1, "2", 3, "4", 5, ...); Object[] objects = objectList.toArray(new Object[0]); 正例: List<Object> objectList = Arrays.asList(1, "2", 3, "4", 5, ...); Object[] objects = objectList.toArray(); 7.集合 7.1.初始化集合时,尽量指定集合大小 Java集合初始化时都会指定一个默认大小,当默认大小不再满足数据需求时就会扩容,每次扩容的时间复杂度有可能是O(n)。所以,尽量指定预知的集合大小,就能避免或减少集合的扩容次数。 反例: List<UserDO> userDOList = ...; Set<Long> userSet = new HashSet<>(); Map<Long, UserDO> userMap = new HashMap<>(); List<UserVO> userList = new ArrayList<>(); for (UserDO userDO : userDOList) { userSet.add(userDO.getId()); userMap.put(userDO.getId(), userDO); userList.add(transUser(userDO)); } 正例: List<UserDO> userDOList = ...; int userSize = userDOList.size(); Set<Long> userSet = new HashSet<>(userSize); Map<Long, UserDO> userMap = new HashMap<>((int) Math.ceil(userSize * 4.0 / 3)); List<UserVO> userList = new ArrayList<>(userSize); for (UserDO userDO : userDOList) { userSet.add(userDO.getId()); userMap.put(userDO.getId(), userDO); userList.add(transUser(userDO)); } 7.2.不要使用循环拷贝集合,尽量使用JDK提供的方法拷贝集合 JDK提供的方法可以一步指定集合的容量,避免多次扩容浪费时间和空间。同时,这些方法的底层也是调用System.arraycopy方法实现,进行数据的批量拷贝效率更高。 反例: List<UserDO> user1List = ...; List<UserDO> user2List = ...; List<UserDO> userList = new ArrayList<>(user1List.size() + user2List.size()); for (UserDO user1 : user1List) { userList.add(user1); } for (UserDO user2 : user2List) { userList.add(user2); } 正例: List<UserDO> user1List = ...; List<UserDO> user2List = ...; List<UserDO> userList = new ArrayList<>(user1List.size() + user2List.size()); userList.addAll(user1List); userList.addAll(user2List); 7.3.尽量使用Arrays.asList转化数组为列表 原理与"不要使用循环拷贝集合,尽量使用JDK提供的方法拷贝集合"类似。 反例: List<String> typeList = new ArrayList<>(8); typeList.add("Short"); typeList.add("Integer"); typeList.add("Long"); String[] names = ...; List<String> nameList = ...; for (String name : names) { nameList.add(name); } 正例: List<String> typeList = Arrays.asList("Short", "Integer", "Long"); String[] names = ...; List<String> nameList = ...; nameList.addAll(Arrays.asList(names)); 7.4.直接迭代需要使用的集合 直接迭代需要使用的集合,无需通过其它操作获取数据。 反例: Map<Long, UserDO> userMap = ...; for (Long userId : userMap.keySet()) { UserDO user = userMap.get(userId); ... } 正例: Map<Long, UserDO> userMap = ...; for (Map.Entry<Long, UserDO> userEntry : userMap.entrySet()) { Long userId = userEntry.getKey(); UserDO user = userEntry.getValue(); ... } 7.5.不要使用size方法检测空,必须使用isEmpty方法检测空 使用size方法来检测空逻辑上没有问题,但使用isEmpty方法使得代码更易读,并且可以获得更好的性能。任何isEmpty方法实现的时间复杂度都是O(1),但是某些size方法实现的时间复杂度有可能是O(n)。 反例: List<UserDO> userList = ...; if (userList.size() == 0) { ... } Map<Long, UserDO> userMap = ...; if (userMap.size() == 0) { ... } 正例: List<UserDO> userList = ...; if (userList.isEmpty()) { ... } Map<Long, UserDO> userMap = ...; if (userMap.isEmpty()) { ... } 7.6.非随机访问的List,尽量使用迭代代替随机访问 对于列表,可分为随机访问和非随机访问两类,可以用是否实现RandomAccess接口判断。随机访问列表,直接通过get获取数据不影响效率。而非随机访问列表,通过get获取数据效率极低。 反例: LinkedList<UserDO> userDOList = ...; int size = userDOList.size(); for (int i = 0; i < size; i++) { UserDO userDO = userDOList.get(i); ... } 正例: LinkedList<UserDO> userDOList = ...; for (UserDO userDO : userDOList) { ... } 其实,不管列表支不支持随机访问,都应该使用迭代进行遍历。 7.7.尽量使用HashSet判断值存在 在Java集合类库中,List的contains方法普遍时间复杂度是O(n),而HashSet的时间复杂度为O(1)。如果需要频繁调用contains方法查找数据,可以先将List转换成HashSet。 反例: List<Long> adminIdList = ...; List<UserDO> userDOList = ...; List<UserVO> userVOList = new ArrayList<>(userDOList.size()); for (UserDO userDO : userDOList) { if (adminIdList.contains(userDO.getId())) { userVOList.add(transUser(userDO)); } } 正例: Set<Long> adminIdSet = ...; List<UserDO> userDOList = ...; List<UserVO> userVOList = new ArrayList<>(userDOList.size()); for (UserDO userDO : userDOList) { if (adminIdSet.contains(userDO.getId())) { userVOList.add(transUser(userDO)); } } 7.8.避免先判断存在再进行获取 如果需要先判断存在再进行获取,可以直接获取并判断空,从而避免了二次查找操作。 反例: public static UserVO transUser(UserDO user, Map<Long, RoleDO> roleMap) { UserVO userVO = new UserVO(); userVO.setId(user.getId()); ... if (roleMap.contains(user.getRoleId())) { RoleDO role = roleMap.get(user.getRoleId()); userVO.setRole(transRole(role)); } } 正例: public static UserVO transUser(UserDO user, Map<Long, RoleDO> roleMap) { UserVO userVO = new UserVO(); userVO.setId(user.getId()); ... RoleDO role = roleMap.get(user.getRoleId()); if (Objects.nonNull(role)) { userVO.setRole(transRole(role)); } } 8.异常 8.1.直接捕获对应的异常 直接捕获对应的异常,避免用instanceof判断,效率更高代码更简洁。 反例: try { saveData(); } catch (Exception e) { if (e instanceof IOException) { log.error("保存数据IO异常", e); } else { log.error("保存数据其它异常", e); } } 正例: try { saveData(); } catch (IOException e) { log.error("保存数据IO异常", e); } catch (Exception e) { log.error("保存数据其它异常", e); } 8.2.尽量避免在循环中捕获异常 当循环体抛出异常后,无需循环继续执行时,没有必要在循环体中捕获异常。因为,过多的捕获异常会降低程序执行效率。 反例: public Double sum(List<String> valueList) { double sum = 0.0D; for (String value : valueList) { try { sum += Double.parseDouble(value); } catch (NumberFormatException e) { return null; } } return sum; } 正例: public Double sum(List<String> valueList) { double sum = 0.0D; try { for (String value : valueList) { sum += Double.parseDouble(value); } } catch (NumberFormatException e) { return null; } return sum; } 8.3.禁止使用异常控制业务流程 相对于条件表达式,异常的处理效率更低。 反例: public static boolean isValid(UserDO user) { try { return Boolean.TRUE.equals(user.getIsValid()); } catch(NullPointerException e) { return false; } } 正例: public static boolean isValid(UserDO user) { if (Objects.isNull(user)) { return false; } return Boolean.TRUE.equals(user.getIsValid()); } 9.缓冲区 9.1.初始化时尽量指定缓冲区大小 初始化时,指定缓冲区的预期容量大小,避免多次扩容浪费时间和空间。 反例: StringBuffer buffer = new StringBuffer(); StringBuilder builder = new StringBuilder(); 正例: StringBuffer buffer = new StringBuffer(1024); StringBuilder builder = new StringBuilder(1024); 9.2.尽量重复使用同一缓冲区 针对缓冲区,Java虚拟机需要花时间生成对象,还要花时间进行垃圾回收处理。所以,尽量重复利用缓冲区。 反例: StringBuilder builder1 = new StringBuilder(128); builder1.append("update t_user set name = '").append(userName).append("' where id = ").append(userId); statement.executeUpdate(builder1.toString()); StringBuilder builder2 = new StringBuilder(128); builder2.append("select id, name from t_user where id = ").append(userId); ResultSet resultSet = statement.executeQuery(builder2.toString()); ... 正例: StringBuilder builder = new StringBuilder(128); builder.append("update t_user set name = '").append(userName).append("' where id = ").append(userId); statement.executeUpdate(builder.toString()); builder.setLength(0); builder.append("select id, name from t_user where id = ").append(userId); ResultSet resultSet = statement.executeQuery(builder.toString()); ... 其中,使用setLength方法让缓冲区重新从0开始。 9.3.尽量设计使用同一缓冲区 为了提高程序运行效率,在设计上尽量使用同一缓冲区。 反例: // 转化XML(UserDO) public static String toXml(UserDO user) { StringBuilder builder = new StringBuilder(128); builder.append("<UserDO>"); builder.append(toXml(user.getId())); builder.append(toXml(user.getName())); builder.append(toXml(user.getRole())); builder.append("</UserDO>"); return builder.toString(); } // 转化XML(Long) public static String toXml(Long value) { StringBuilder builder = new StringBuilder(128); builder.append("<Long>"); builder.append(value); builder.append("</Long>"); return builder.toString(); } ... // 使用代码 UserDO user = ...; String xml = toXml(user); 正例: // 转化XML(UserDO) public static void toXml(StringBuilder builder, UserDO user) { builder.append("<UserDO>"); toXml(builder, user.getId()); toXml(builder, user.getName()); toXml(builder, user.getRole()); builder.append("</UserDO>"); } // 转化XML(Long) public static void toXml(StringBuilder builder, Long value) { builder.append("<Long>"); builder.append(value); builder.append("</Long>"); } ... // 使用代码 UserDO user = ...; StringBuilder builder = new StringBuilder(1024); toXml(builder, user); String xml = builder.toString(); 去掉每个转化方法中的缓冲区申请,申请一个缓冲区给每个转化方法使用。从时间上来说,节约了大量缓冲区的申请释放时间;从空间上来说,节约了大量缓冲区的临时存储空间。 9.4.尽量使用缓冲流减少IO操作 使用缓冲流BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream等,可以大幅较少IO次数并提升IO速度。 反例: try (FileInputStream input = new FileInputStream("a"); FileOutputStream output = new FileOutputStream("b")) { int size = 0; byte[] temp = new byte[1024]; while ((size = input.read(temp)) != -1) { output.write(temp, 0, size); } } catch (IOException e) { log.error("复制文件异常", e); } 正例: try (BufferedInputStream input = new BufferedInputStream(new FileInputStream("a")); BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream("b"))) { int size = 0; byte[] temp = new byte[1024]; while ((size = input.read(temp)) != -1) { output.write(temp, 0, size); } } catch (IOException e) { log.error("复制文件异常", e); } 其中,可以根据实际情况手动指定缓冲流的大小,把缓冲流的缓冲作用发挥到最大。 10.线程 10.1.在单线程中,尽量使用非线程安全类 使用非线程安全类,避免了不必要的同步开销。 反例: StringBuffer buffer = new StringBuffer(128); buffer.append("select * from ").append(T_USER).append(" where id = ?"); 正例: StringBuilder buffer = new StringBuilder(128); buffer.append("select * from ").append(T_USER).append(" where id = ?"); 10.2.在多线程中,尽量使用线程安全类 使用线程安全类,比自己实现的同步代码更简洁更高效。 反例: private volatile int counter = 0; public void access(Long userId) { synchronized (this) { counter++; } ... } 正例: private final AtomicInteger counter = new AtomicInteger(0); public void access(Long userId) { counter.incrementAndGet(); ... } 10.3.尽量减少同步代码块范围 在一个方法中,可能只有一小部分的逻辑是需要同步控制的,如果同步控制了整个方法会影响执行效率。所以,尽量减少同步代码块的范围,只对需要进行同步的代码进行同步。 反例: private volatile int counter = 0; public synchronized void access(Long userId) { counter++; ... // 非同步操作 } 正例: private volatile int counter = 0; public void access(Long userId) { synchronized (this) { counter++; } ... // 非同步操作 } 10.4.尽量合并为同一同步代码块 同步代码块是有性能开销的,如果确定可以合并为同一同步代码块,就应该尽量合并为同一同步代码块。 反例: // 处理单一订单 public synchronized handleOrder(OrderDO order) { ... } // 处理所有订单 public void handleOrder(List<OrderDO> orderList) { for (OrderDO order : orderList) { handleOrder(order); } } 正例: // 处理单一订单 public handleOrder(OrderDO order) { ... } // 处理所有订单 public synchronized void handleOrder(List<OrderDO> orderList) { for (OrderDO order : orderList) { handleOrder(order); } } 10.5.尽量使用线程池减少线程开销 多线程中两个必要的开销:线程的创建和上下文切换。采用线程池,可以尽量地避免这些开销。 反例: public void executeTask(Runnable runnable) { new Thread(runnable).start(); } 正例: private static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(10); public void executeTask(Runnable runnable) { executorService.execute(runnable); } 后记 作为一名长期奋战在业务一线的"IT民工",没有机会去研究什么高深莫测的"理论",只能专注于眼前看得见摸得着的"技术",致力于做到"干一行、爱一行、专一行、精一行"。 原文发布时间:2019-12-18作者:常意本文来自阿里云合作伙伴“阿里技术”,了解相关信息可以关注“阿里技术”。

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

Python全栈工程师(文件操作、编码)

ParisGabriel 每天坚持手写一天一篇 决定坚持几年 为了梦想为了信仰 Python人工智能从入门到精通 最近简直要死了 发烧感冒 喉咙痛。。。。、 如何长期保存计算机中数据: 需要文件操作 文件 file: 文件是用于数据存储的单位 文件通常用来长期储存数据 文件中的数据是以字节为单位进行顺序储存的文件的操作流程: 1.打开文件 2.读/写文件 3.关闭文件 注: 任何操作系统, 一个应用程序同时打开文件的数量有最大数限制文件打开函数: open(file, mode=‘rt’) 用于打开一个文件, 返回此文件流对象, 如果打开文件失败, 则会触发osError错误文件的关闭方法: F.colse() #关闭问津, 释放系统资源 示例: # 此示例示意文件的打开和关闭操作 try: f = open('./aaa.txt') # 不存在此文件 # f = open('./myfile.txt') # 不存在此文件 print("打开文件成功") # 此处要进行读/写操作 f.close() # 半闭文件 except OSError: print("文件打开失败") 文件方法: 文件 mode 模式字符的含义 字符 含义 'r' 以只读方式打开(默认) 'w' 以只写方式打开,删除原有文件内容(如果文件不存在,则创建该文件并以只写方式打开) 'x' 创建一个新文件, 并以写模式打开这个文件,如果文件存在则会产生"FileExistsError"错误 'a' 以只写文件打开一个文件,如果有原文件则追加到文件末尾 'b' 用二进制模式打开 't' 文本文件模式打开 (默认) '+' 为更新内容打开一个磁盘文件 (可读可写) 缺省模式是 'rt' 'w+b' 可以实现二进制随机读写,当打开文件时,文件内容将被清零 'r+b' 以二进制读和更新模式打开文件,打开文件时不会清空文件内容 'r+' 以文本模式读和更新模式打开文件,打开文件时不会清空文件内容 python 文件常用方法: 方法 说明 F.close() 关闭文件(关闭后文件不能再读写会发生ValueError错误) F.readline() 读取一行数据, 如果到达文件尾则返回空行 F.readlines(max_chars=-1) 返回每行字符串的列表,max_chars为最大字符(或字节)数 F.writelines(lines) 将字符串的列表或字符串的列表中的内容写入文件 二进制文件操作方法 F.read(size=-1) 从一个文件流中最多读取size个字符(文本文件)或字节(二进制文件),如果不给出参数,则默认读取文件中全部的内容并返回 F.write(text) 写一个字符串到文件流中,返回写入的字符数(文本文件)或字节数(二进制文件) F.tell() 返回当前文件流读写指针的绝对位置(字节为单位) F.seek(offset, whence=0) 改变数据流读写指针的位置,返回新的绝对位置 F.flush() 把写入文件对象的缓存内容写入到磁盘 F.readable() 判断这个文件是否可读,可读返回True,否则返回False F.writable() 判断这个文件是否可写,可写返回True,否则返回False F.seekable() 返回这个文件对象是否支持随机定位 F.truncate(pos = None) 剪掉 自pos位置之后的数据,返回新的文件长度 文本文件操作: 操作模式: ‘t’ 说明: 1.默认文件中储存的都为字节数据, 在读写过程中会自动进行编解码操作 2.文本文件以行位单位进行分割, 在python内部统一用"\n"做为换行符进行分割 3.对文本文件的读写操作需要用字符串(str)进行数据操作 Linux换行符: '\n' Windows 换行符: '\r\n' 新的Mac OS 换行符: '\n' 旧的Macintosh换行符: '\r'(已不用了) 文件流对象是可迭代对象, 迭代过程中将换行符“\n”作为分隔符 f = open('phonenumber.txt') for line in f: print(line) # 打印每一行的数据 标准输入输出文件: sys.stdin 标准输入文件 Ctrl + D 输入文件结束符 sys.stdout 标准输出文件 sys.stderr 标准错误输出文件 标准文件绝对不能关闭 Linux系统内所有的硬件都会映射成文件 关闭文件会导致错误模块:sys 注: 标准文件不需要打开和关闭就可以使用 示例: import sys sys.stdout.write("我是标准输出\n") sys.stderr.write("我是一个错误\n") import sys s = sys.stdin.read() print("s=", s) print("程序结束") 二进制文件操作: 二进制文件操作模式字符:‘b’ 默认文件中存储的是以字节数据为单位, 通常有人为规定的格式 二进制文件操作需要用字节串进行读写 F.read()/F.readline() F.readlines()返回类型 对于文本操作 F.write() 对于二进制文件也需要用字节串进行操作 F.tell: 作用: 返回当前的读写位置(从文件头以字节为单位) F.seek方法: F.seek(偏移量,whence=相对位置) 偏移量 大于0的数代表向文件尾方向移动的字节数 小于0的数代表向文件头方向移动的字节数 相对位置 0代表从文件头开始偏移 1代表从文件当前位置开始偏移 2代表从文件尾开始偏移 (第一个参数必须是负的) 示例: # 此示例示意用seek改变文件的读写位置,用tell来得到读写位置 f = open('myseek.txt', 'rb') b = f.read(2) # b'AB' 读取出来 print(b) # b'AB # 从头开始向后走5个字节 # f.seek(5, 0) # 从当前位置向后走3个字节 # f.seek(3, 1) # 从文件尾向前数15个字节 f.seek(-15, 2) b = f.read(5) print(b) # b'abcde' f.close() 汉字编码(只讲两种) 国标系列: GB18030(二字节或四字节编码27553个字) GBk(二字节编码21003个字) GB2312(二字节编码6763个字) (Windows 常用) 国际标准: Unicode <---> UTF-8 (Ascii 占1字节 汉字占3字节) (Linux Mac OS X / IOS /Android) python编码字符串: ‘gb18030’ ‘gb2312’ ‘gbk’ ‘utf-8’ ‘ascii’ ....以上字符串用于encide和decode中编码注释: 在Python源文件中的第一行或第二行写入如下内容: # -*- codeing:gbk -*- #设置源文件编码格式为gbk 或 # -*- codeing:utf-8 -*- #设置源文件编码格式为utf-8 作用: 告诉解释执行器此文件的编码是什么 练习: 自己写一个文件 'info.txt' 内部存一些文字信息 如: 张三 20 100 李四 21 96 小王 22 98 写程序将这些数据读取出来,打印到终端上 答案: try: f = open("myfile.txt") L = f.readlines() for x in L: s = x.strip() n, a, s = s.split() print("姓名:", n, "年龄:", int(a), "成绩:", int(s)) except: print("打开文件是失败") 练习: 1. 写程序,循环输入很多个人的姓名,电话号码, 当输入结束后将这些信息存入到文件phonenumber.txt中 (建议先用列表暂存数据,格式自己定义) 2. 写程序,将phonenumber.txt文件中的数据读取出来. 再用以下格式打印出来: 如: 小张 的电话是 13888888888 小李 的电话是 13999999999 练习: 1. 写程序实现复制文件的功能 要求: 1. 要考虑特大文件问题 2. 要关闭文件 3. 要能复制二进制文件 如: 请输入源文件路径名: /home/tarena/xxx.tar.gz 请输入目标文件路径名: ./a.tar.gz 显示: 文件已成功复制 答案: def copy_myfile(): try: ypath = input("please inout raw path:") xpath = input("please inout new path:") f1 = open(xpath, "w+b") f = open(ypath, "r+b") for x in f: f1.write(x) f1.close() f.close() print("File copied") except: print("file not inexeistence") copy_myfile() 2. 修改学生信息管理程序,要求加入两个功能: 9) 保存信息到文件(si.txt) L = [{"name": "Tom", "age": 20, "score": 98}, {"name": "Lin", "age": 21, "score": 99}, {"name": "Garin", "age": 19, "score": 100}] def student_file(L): try: f = open("./si.txt", "x") for x in L: f.write(x["name"]) f.write(" ") f.write(str(x["age"])) f.write(" ") f.write(str(x["score"])) f.write("\n") except FileExistsError: f = open("./si.txt", "a") for x in L: f.write(x["name"]) f.write(" ") f.write(str(x["age"])) f.write(" ") f.write(str(x["score"])) f.write("\n") student_file(L) 10) 从文件中读取数据(si.tx def open_student_file(): f = open("./si.txt") L = [] for line in f.readlines(): s = line.strip() n, a, s = s.split() # 拆成列表 student = {"name": n, "age": a, "score": s} L.append(student) f.close() return L 源码: https://pan.baidu.com/s/1vVuH7OwNdn8vqaBKAivniQ异常还没处理...........

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

Python全栈工程师(每周总结:3)

ParisGabriel 每天坚持 一天一篇 点个订阅吧灰常感谢 当个死粉也阔以 week summer: Python人工智能从入门到精通 函数式编程: 是指用一系列函数解决问题 每一个函数完成细小的功能,一系列函数的任意组合可以完成大问题 函数仅接受输入并产生输入,不包含任何影响输出的内部 状态函数的可重用性: 如果一个函数的输入参数一定,则返回结果必须一定的函数 称为可重用函数 可重入和不可重入区别就是访问除局部变量以外的变量函数式编程要求: def 创建函数最好不要访问局部作用域以外的变量,这样可以保证 结果的唯一性(可重入性)高阶函数 high order function: 满足下列条件之一的就是高阶函数 1.函数接受一个或多个函数作用参数传入 2.函数返回一个函数 内建高阶函数: map,filter,sorted map(func, *iterables): 用函数和对可迭代对象中的每一个元素作为参数计算出新的可迭代对象, 当最短的一个可迭代对象不再提供数据时此可迭代对象生成结束 func 函数 *iterables 排列 filter(function, iterable): 筛选可迭代对象iterable中的数据,返回一个可迭代器对象,此可迭代对象 将对iterable进行筛选.函数function 将对iterable中的每个元素进行求值, 返回False则将此数据丢弃,返回True,则保留此数据 sorted(iterable, key=None, reverse=False): 将原可迭代对象的数据进行排序,生成排序后的列表iterable 可迭代对象 key 函数是用来提供一个值,这个值将作为排序的依据reverse 标志用来设 置是否降序排序 返回可迭代对象函数: range() map() filter() reverse()递归函数; 函数直接调用或间接的调用自身 直接调用自己 def f(): f() 间接调用自己 def fa(): fb() def fb(): fa() 递归一定要控制递归的层数,当符合条件时要终止递归 几乎所有的递归都能用while循环来代替递归特点: 优点: 递归吧问题简单化,让思路更清晰,代码更简洁 缺点: 递归因系统环境影响大,当递归深时,可能会得到不可预知的结果 递推阶段: 从原问题出发,按递归公式递推从未知到已知,最终达到递归的终止条件 回归阶段 按递归终止条件求出结果,逆向逐步代入递归公式 回归到原问题求解 闭包 closure: 闭包是引用了此函数外部的变量函数 闭包是将内部嵌套和函数外部的执行环境绑定在一起的对象 装饰器 decorators(专业提高篇) 装饰器是一个函数 ,主要用来包装另一个函数或类 装饰的目的是在 不改变函数的的原名(或类名)的情况下 改变对象的行为函数装饰器 函数装饰器指装饰器传入的是一个函数,返回的也是一个函数 原理就是改变原变量绑定的函数函数的文档字符串: 函数内第一次未被赋值给任何变量的字符串是此函数的文档字符串 模块 Module: 模块是一个包含有一系列数据、函数、类等组成的程序组 模块是一个文件,模块文件通常以.py结尾 作用: 让一些相关的数据、函数、类等有逻辑的组织在一起,使用逻辑结构清晰 模块的数据、函数、类等 可提供给其他模块或程序使用模块的分类; 内建模块(builtins)在解析器的内可以直接使用、 标准库模块,安装python时已安装且可以使用 第三方模块(通常开源),需要自己安装 用户自己编写模块(可以作为其他人的第三方模块) import 将某模块整体导入到当前模块中 from import 将谋模块的一个或多个属性导入到当前模块的作用域 from import * 将某模块的所有属性全部导入到当前模块dir函数: dir([对象]) 返回一个字符串的列表 不给参数这返回当前作用域内的所有变量的列表 内建模块 数学模块用法: import math # 或 from math import * 变量 描述 math.e 自然对数的底e math.pi 圆周率pi 函数名 描述math.ceil(x) 对x向上取整,比如x=1.2,返回2math.floor(x) 对x向下取整,比如x=1.2,返回1math.sqrt(x) 返回x的平方根math.factorial(x) 求x的阶乘math.log(x[, base]) 返回以base为底x的对数, 如果不给出base,则以自然对数e为底math.log10(x) 求以10为底x的对数math.pow(x, y) 返回 x**y (x的y次方)math.fabs(x) 返回浮点数x的绝对值角度和弧度degrees互换 math.degree(x) 将弧度x转换为角度math.radians(x) 将角度x转换为弧度三角函数 math.sin(x) 返回x的正弦(x为弧度)math.cos(x) 返回x的余弦(x为弧度)math.tan(x) 返回x的正切(x为弧度)math.asin(x) 返回x的反正弦(返回值为为弧度)math.acos(x) 返回x的反余弦(返回值为为弧度)math.atan(x) 返回x的反正切(返回值为为弧度) 时间模块 time 此模块提供了时间相关的函数,且一直可用 时间简介 公元纪年是从公元 0000年1月1日0时开始的 计算机元年是从1970年1月1日0时开始的,此时时间为0,之后每过一秒时间+1 UTC 时间 (Coordinated Universal Time) 是从Greenwich时间开始计算的. UTC 时间不会因时区问题而产生错误 DST 阳光节约时间(Daylight Saving Time),又称夏令时, 是一个经过日照时间修正后的时间 时间元组 时间元组是一个9个整型元素组成的,这九个元素自前至后依次为: 四位的年(如: 1993) 月 (1-12) 日 (1-31) 时 (0-23) 分 (0-59) 秒 (0-59) 星期几 (0-6, 周一是 0) 元旦开始日 (1-366) 夏令时修正时间 (-1, 0 or 1). 注: 如果年份值小于100,则会自动转换为加上1900后的值 模块名: time 时间模块用法: import time # 或 from time import xxx # 或 from time import * 变量 描述 time.altzone 夏令时时间与UTC时间差(秒为单位) time.daylight 夏令时校正时间 time.timezone 本地区时间与UTC时间差(秒为单位) time.tzname 时区名字的元组, 第一个名字为未经夏令时修正的时区名, 第一个名字为经夏令时修正后的时区名 注: CST为中国标准时间(China Standard Time UTC+8:00) 函数名 描述 time.time() 返回从计算机元年至当前时间的秒数的浮点数(UTC时间为准) time.sleep(secs) 让程序按给定秒数的浮点数睡眠一段时间 time.gmtime([secs]) 用给定秒数转换为用UTC表达的时间元组 (缺省返回当前时间元组) time.asctime([tuple]) 将时间元组转换为日期时间字符串 time.mktime(tuple) 将本地日期时间元组转换为新纪元秒数时间(UTC为准) time.localtime([secs]) 将UTC秒数时间转换为日期元组(以本地时间为准) 系统模块 sys 运行时系统相关的信息 sys模块的属性 属性 描述sys.path 模块搜索路径 path[0] 是当前脚本程序的路径名,否则为 ''sys.modules 已加载模块的字典sys.version 版本信息字符串sys.version_info 版本信息的命名元组sys.platform 操作系统平台名称信息sys.argv 命令行参数 argv[0] 代表当前脚本程序路径名sys.copyright 获得Python版权相关的信息sys.builtin_module_names 获得Python内建模块的名称(字符串元组)sys模块的函数 函数名 描述sys.exit([arg]) 退出程序,正常退出时sys.exit(0)sys.getrecursionlimit() 得到递归嵌套层次限制(栈的深度)sys.setrecursionlimit(n) 得到和修改递归嵌套层次限制(栈的深度) $ pip3 install tensorflow 第三方模块 tensorflow 的安装 必须有网 命令自动下载安装 自定义模块文件名必须是标识符模块的加载过程: 1. 在模块导入时,模块的所有语句都会执行 2. 如果一个模块已经导入,则再次导入时不会重新执行模块内的语句 重新加载mymodl1模块 import imp imp.reload(mymodl1) __doc__属性 文档字符串自动赋值给__file__ 属性 查看模块的当前路径dir(模块名) 查看模块属性模块以导入和执行的过程: 1. 先搜索相关的路径,找到模块名.py 2. 判断是否有此模块对应的.pyc文件。如果.pyc比.py文件新,则直接加载.pyc文件 3. 否则 用模块.py,文件生成.pyc,并加载执行 pyc python的编译 编译 解释执行 mymod.py --------> mymod.pyc --------> python3 模块的文档字符串和函数一样 模块的 __doc__ 属性 此属性用于绑定模块的文档字符串 模块的 __file__属性 此属性用于记录模块对应的文件路径名 模块的 __name__属性 __name__属性 用来记录模块自身名字 判断是否为主模块 主模块: __name__绑定 '__main__' 非主模块: __name__ 绑定模块名 模块的 __all__列表 模块中的 __all__列表是一个用来存放可导出属性的字符串列表 模块的隐藏属性 模块中以'_'开头的属性,在from xxx import * 导入时,通常将不被导入 标准库模块 随机模块 random说明: random模块是用于模拟或生成随机输出的模块. import random as R 函数名 描述R.random() 返回一个[0, 1) 之间的随机实数R.uniform(a,b) 返回[a,b) 区间内的随机实数R.randrange([start,] stop[, step]) 返回range(start,stop,step)中的随机数R.choice(seq) 从序列中返回随意元素R.shuffle(seq[, random]) 随机指定序列的顺序(乱序序列)R.sample(seq,n) 从序列中选择n个随机且不重复的元素包(模块包) package 包是将模块以文件夹的组织形式进行分组管理的管理方法 __init__.py是常规包内必须存在的文件 __init__.py会在包加载时自动调用 __init__.py : 1. 编写此包的内容 2. 在内部填写文档字符串 . 在__init__.py文件内可以加载此包所依懒的一些其它模块 __init__.py内的 __all__ 列表 用来记录此包中有哪些子包或模块在用from import *语句 时被导入 __all__列表只对 from xxx import *语句起作用 导入包时的索引路径顺序: 1. 搜索程序的当前路径 2. sys.path 提供的路径 包的相对导入: 包的相对导入是指包内模块的相互导入 相对导入时不能超出包的外部 包的相对导入 只对后两种导入方式有用 异常(基础)except: 什么是错误: 是指由于逻辑或语法等导程序无法正常执行的问题 什么是异常: 是程序出错的标识符的一种状态 当异常发时 程序不会再向下执行,而转去调用此函数的地方 待处理此错误并恢复为正常状态异常的作用: 用作信号, 通知上层调用者有错误产生需要处理 异常处理语句(4条): try-except 语句: 用于接受异常通知, 捕获异常 try-finally 语句: 执行必须执行的语句 raise 语句: 发送异常通知, 并进入异常状态 assert 语句: 根据条件选着性的发送 AssertionError类型的异常通知为什么要处理异常机制: 在程序调用层数比较深的时候, 向主调用函数传递错误信息 需要层层return返回 比较麻烦, 用异常处理机制可以较简单的传递错误信息 用<>括号表示的一定是对象 什么是迭代器 迭代器是访问可迭代对象的工具 迭代器是指用iter(obj) 函数返回的对象 迭代器可以用next(it) 函数获取可迭代对象的数据 迭代器只能向前取值,不会后退 用iter函数可以返回一个可迭代对象的迭代器 迭代器函数iter和nextiter(iterable) 从可迭代对象中返回一个迭代器,iterable 必须是能提供一个迭代器的对象next(iterator) 从迭代器iterator中获取下一个记录,如果无法获取下一条记录,则触发StopIteration异常 什么是生成器: 生成器是能够动态提供数据的对象,生成器对象也是可迭代对象 动态就是现用现生成数据 生成器有两种: 1. 生成器函数 2. 生成器表达式 生成器函数的定义 含有yield语句的函数是生成器函数,此函数被调用将返回一个生成器对象 yield 翻译为(产生或生成) 动态生成数据 在函数内可以一个或多少 在生成器函数调用return 会触发一个StopIteration异常 函数: zip(iter1[, iter2[, ...]]) 返回一个zip对象,此对象用于生成元组,元组的个数由最小的可迭代对象决定 enumerate(iterable[, start]) 生成带索引的枚举对象,返回迭代类型为索引-值对(index-value对) , 默认索引从零开始,也可以用start指定(排序 自定义标号) 字节串和字节数组字节串bytes (也叫字节序列) 作用: 存储以字节为单位的数据 字节串是不可变的字节序列 字节: 字节是由8个位(bit)组成的数据单位,是计算机进行数据管理的单位 字节是用 0 ~ 255 范围内的整数表示的 2 ** 8 - 1 字节串的构造函数 bytes bytes() 生成一个空的字节串 等同于 b'' bytes(整数可迭代对象) # 用可迭代对象初始化一个字节串 bytes(整数n) 生成n个值为0的字节串 bytes(字符串, encoding='utf-8') 用字符串转为编码生成一个字节串 bytes 的运算: + += * *= < <= > >= == != in / not in 索引和切片 len(x) max(x) min(x) sum(x) any(x) all(x) bytes 和 str 的区别: bytes 存储字节( 通常值在 range(0, 256)) str 存储unicode字符( 通常值在0~65535) bytes 与 str 的转换 编码(encode) str ------------> bytes b = s.encode(encoding='utf-8') 解码(decode) bytes ----------> str s = b.decode(encoding='utf-8') 字节数组 bytearray 是可变的字节序列 字节数组的构造函数: bytearray bytearray() 创建空的字节数组 bytearray(整数) 用可迭代对象初始化一个字节数组 bytearray(整型可迭代对象) 生成n个值为0的字节数组 bytearray(字符串, encoding='utf-8') 用字符串的转换编码生成一个字节数组 索引和切片 (字节数组支持索引和切片的赋值操作,规则同列表的索引和切片赋值规则) bytearray的方法: BA.clear() 清空 BA.append(n) 追加一个字节(n为0~255的整数) BA.remove(value) 删除第一个出现的字节,如果没有出现,则触发ValueError错误 BA.reverse() 字节顺序反转 BA.decode(encoding='utf-8') # 解码为字符串 BA.find(sub[, start[,end]]) # 查找 sub

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

Python全栈工程师(每周总结:2)

ParisGabriel 感谢 大家的支持 每天坚持 一天一篇 点个订阅吧灰常感谢 当个死粉也阔以 week summer: Python人工智能从入门到精通 字符串 str # 不可变序列,只能存字符 列表 list # 可变的序列,可以存任意数据 元组 tuple # 不可变序列,可以存任意数据 字典dict # 可变无序,可以存任意数据 集合set #可变无序,只能存不可变数据 (可变就是id不变的情况下改变数据) 序列相关函数: len(x), max(x), min(x), sum(x), any(x), all(x) 序列有5种: star 字符串 list 列表 tuple 元组 bytes bytearray 列表 list: L = [ ] L = list() 创建函数 括号内放可迭代对象、可以空 L [ ] 括号内放下标 L [:: ] 第一个参数开始位置,第二个结束、第三个步长(步长决定方向) 列表推导式: [表达式 for 变量 in 可迭代对象](可以嵌套) del L[ ] 删除指定下表索引 列表可以索引下标 、切片 可以增、删、改、查 可以索引赋值、切片赋值(不是顺序切片时赋值一定要个数相等) 潜拷贝 浅拷贝是指在复制过程中,只复制一层变量,不会复制深层变量绑定的对象的复制过程 深拷贝 深拷贝通常只对可变对象进行复制,不可变对象通常不会复制 元组 type t = (1, ) 低于连个元素必须用, 号 t = type(x) 同列表一样 元组可以索引和切片和列表一样 但是但是不能赋值 T.index(v[, begin[, end]]) 返回对应元素的索引下标 T.count(x) 返回元组中对应的元素个数字典 dict: d = { } d = {“a”:1} 键值对形式存在 d[ ] 括号里放键 ,字典索引只索引键(key)索引赋值 : 只能修改值 ,存在修改 否者添加 dict() 生成一个字的字典 等同于 {} dict(iterable) 用可迭代对象初始化一个字典 dict(**kwargs) 用关键字传参形式创建一个字典 字典的键(key) 必须为不可变类型 且不能重复不可变类型:bool, int, float, complex, str, tuple, frozenset, bytes(后面再讲) in 在什么什么里面 not in 不在什么什么里面(判断键存在:只判断键) is 是 is not 不是 所有可迭代对象都可以用for 遍历 (字典只访问键)字典推导式 : d = {x : x ** 2 for x in range(10)} {键表达式 : 值表达式 for 变量 in 可迭代对象 if 真值表达式}(可嵌套) 字典 VS 列表 1. 都是可变对象 2. 索引方式不同,列表用整数索引,字典用键索引 3. 字典的插入,删除,修改数据的速度可能会快于列表(重要) 4. 列表的存储是有序的,字典的存储是无序的可变的数据类型有四种: list 列表、dict 字典 set 集合、bytearray 字节数组集合 set: s = set( ) s = set( ) 构造函数 数据不可重复 相当于只有键的字典 集合运算: & 生成两个集合的交集 | 生成两个集合的并集 - 生成两个集合的补集 ^ 生成两个集合的对称补集 > 判断一个集合是另一个集合的超集 < 判断一个集合是另一个集合的子集 (包含关系) == != 集合相同/不同 (与顺序无关)集合推导式:{表达式 for 变量 in 可迭代对象 [if 真值表达式]}(可嵌套)固定集合 frozenset: 固定集合是不可变的,无序的, 含有唯一元素的集合 (可以做字典键也可以做集合的值) frozenset() f = frozenset() 括号内放可迭代对象 相当于集合的全部方法(包括运算符)去掉修改集合的方法 常用字符串方法方法 说明S.isdigit() 判断字符串中的字符是否全为数字S.isalpha() 判断字符串是否全为英文字母S.islower() 判断字符串所有字符是否全为小写英文字母S.isupper() 判断字符串所有字符是否全为大写英文字母S.isspace() 判断字符串是否全为空白字符S.center(width[,fill]) 将原字符串居中,左右默认填充空格 width:所居中字符串的长度 fill:默认填充空格S.count(sub[, start[,end]]) 获取一个字符串中子串的个数 sub:所要获取的字符串 start:起始位置 end:结束位置S.find(sub[, start[,end]]) 获取字符串中子串sub的索引,失败返回-1 start:起始位置 end:结束位置S.strip() 返回去掉左右空白字符的字符串S.lstrip() 返回去掉左侧空白字符的字符串S.rstrip() 返回去掉右侧空白字符的字符串S.upper() 生成将英文转换为大写的字符串S.lower() 生成将英文转换为小写的字符串S.replace(old, new[, count]) 将原字符串的old用new代替,生成一个新的字符串 count:更换的次数S.startswith(prefix[, start[, end]]) 返回S是否是以prefix开头,如果以prefix开头返回True,否则返回False,S.endswith(suffix[, start[, end]]) 返回S是否是以suffix结尾,如果以suffix结尾返回True,否则返回False以下是不常用的 S.title() 生成每个英文单词的首字母大写字符串S.isnumeric() 判断字符串是否全为数字字符文本解析: S.split(sep=None) 拆分字符串 sep是拆分符号 S.join(iterable) S是分隔字符串 扩号内跟可迭代对象 列表的方法 :L.index(v [, begin[, end]]) 返回对应元素的索引下标, begin为开始索引,end为结束索引,当 value 不存在时触发ValueError错误L.insert(index, obj) 将某个元素插放到列表中指定的位置L.count(x) 返回列表中元素的个数L.remove(x) 从列表中删除第一次出现在列表中的值L.copy() 复制此列表(只复制一层,不会复制深层对象)L.append(x) 向列表中追加单个元素L.extend(lst) 向列表追加另一个列表L.clear() 清空列表,等同于 L[:] = []L.sort(reverse=False) 将列表中的元素进行排序,默认顺序按值的小到大的顺序排列L.reverse() 列表的反转,用来改变原列表的先后顺序L.pop([index]) 删除索引对应的元素,如果不加索引,默认删除最后元素,同时返回删除元素的引用关系 字典的方法 D代表字典对象 D.clear() 清空字典D.pop(key) 移除键,同时返回此键所对应的值D.copy() 返回字典D的副本,只复制一层(浅拷贝)D.update(D2) 将字典 D2 合并到D中,如果键相同,则此键的值取D2的值作为新值D.get(key, default) 返回键key所对应的值,如果没有此键,则返回defaultD.keys() 返回可迭代的 dict_keys 集合对象D.values() 返回可迭代的 dict_values 值对象D.items() 返回可迭代的 dict_items 对象 Python3 集合的方法: 方法 意义S.add(e) 在集合中添加一个新的元素e;如果元素已经存在,则不添加S.remove(e) 从集合中删除一个元素,如果元素不存在于集合中,则会产生一个KeyError错误S.discard(e) 从集合S中移除一个元素e,在元素e不存在时什么都不做;S.clear() 清空集合内的所有元素S.copy() 将集合进行一次浅拷贝S.pop() 从集合S中删除一个随机元素;如果此集合为空,则引发KeyError异常S.update(s2) 用 S与s2得到的全集更新变量SS.difference(s2) 用S - s2 运算,返回存在于在S中,但不在s2中的所有元素的集合S.difference_update(s2) 等同于 S = S - s2S.intersection(s2) 等同于 S & s2S.intersection_update(s2) 等同于S = S & s2S.isdisjoint(s2) 如果S与s2交集为空返回True,非空则返回FalseS.issubset(s2) 如果S与s2交集为非空返回True,空则返回FalseS.issuperset(...) 如果S为s2的子集返回True,否则返回FalseS.symmetric_difference(s2) 返回对称补集,等同于 S ^ s2S.symmetric_difference_update(s2) 用 S 与 s2 的对称补集更新 SS.union(s2) 生成 S 与 s2的全集 Python运算符优先级 运算符 描述(), [], {key: value}, {} 元组表达式、列表表达式、字典表达式、集合表达式x[index], x[index:index],x(arguments...), x.attribute 索引,切片,函数调用,属性引用** 指数 (最高优先级)~, +, - 按位翻转, 正号,负号*, /, %, // 乘,除,取模和地板除+, - 加法, 减法>>, << 右移, 左移运算符& 位与(AND)^ 位异或(XOR)| 位或(OR)<=, <, >, >=, ==, !=,is, is not, in, not in 比较,身份测试,成员资格测试not 布尔非and 布尔与or 布尔或if - else 条件表达式lambda lambda表达式 数据类型: 数值类型: int, float, complex, bool容器: 不可变的容器 str, tuple, frozenset, bytes(字节串) 可变的容器 list, dict, set, bytearray(字节数组)值: None, False, True 运算符 算术运算符 + - * / // % ** 比较运算符: < <= > >= == != in / not in is, is not 布尔运算: not, and, or +(正号) -(负号) & | ^ [] (索引,切片,键索引) 表达式: 1 1 + 2 max(1,2,3) # 函数调用是表达式 x if x > y else y, 条件表达式 三种推导式: 列表,字典,集合推导式(三种) 语句: 表达式语句: 所有的表达式都可以单独写在一行,形成一个语句,例: print("hello world") 1 + 2 赋值语句: a = 100 a = b = c = 100 x, y = 100, 200 a[0] = 100 dict['name'] = 'tarena' del 语句 if 语句 while 语句 for 语句 break 语句 continue语句 pass 语句 内建函数: len(x), max(x), min(x), sum(x), any(x), all(x)构造函数(用来创建同类型的数据对象) bool(x), int(x), float(x), complex(x), list(x), tuple(x), str(x), dict(x), set(x), frozenset(x) abs(x) round(x) pow(x, y, z=None) bin(x), oct(x), hex(x) chr(x), ord(x) range(start, stop, step) input(x), print(x) >>> help(__builtins__) 函数: 就是把语句块封装起来 形成一个语句块 利用函数变量直接调用语句块的方式 用户自定义级别的函数是为了提高代码的可用性 重用性 以及逻辑清晰 维护方便 (def 函数名(形参列表):冒号) 形参列表可以为空 函数是一个空间,空间内变量不重复就不会冲突 函数调用: 函数名(实参) return语句 用于返回非None对象语句 函数的参数传递: 传参方式:(2种) 位置传参(包含关系 ) 序列传参 关键字传参(包含关系) 字典关键字传参位置传参: 实参与形参的位置要对应序列传参: 用 * 将序列拆解 然后位置传参关键字传参 将字典用“**”拆解后 实参和形参必须按形参名复制 拆解后键名要在形参中存在必须一致 键名必须是字符串且标识符综合传参: 在能确定形参能唯一匹配到相应实参的情况下 所有传参方式可以任意组合 位置传参(序列传参)一定要在关键字传参(字典关键字传参)的左侧函数的缺省参数: 缺省参数必须从右至左依次存在的命名关键字形参: 语法: def 函数名(*, 命名关键字形参): 语句块 或 ef 函数名(*args, 命名关键字形参): 语句块 (关键字形参 必须用关键字传参) 作用: 收集多余关键字传参双星号字典传参: 语法: def 函数名(**字典形参名): 语句块 作用: 强制所有的参数都参数都必须用关键字传参或字典关键字传参函数的参数说明: 位置形参、星号元组形参、命名关键字形参、双星号字典形参可以混合使用函数自左到右的顺序为: 1.位置形参 2.星号元组形参 3.命名关键字形参 4.双星号字典形参 全局变量:global variable: 函数外,模块内的变量 全局变量所有函数都可以直接访问局部变量:local variable: 函数内的变量 调用时才被创建,在函数调用之后销毁传参的排序规则: 从左到右 1.位置形参 2.星号元组形参 3.命名关键字形参 4.双星号字典形参 函数: globals()/locals() globals()返回当前全局作用域内变量的字典 locals() 返回当前局部作用域内变量的字典 函数名是变量 创建时绑定函数 函数的变量名可以序列交换算法 函数可以作为另一个函数的实参 函数可以作为另一个函数返回值 函数可以嵌套python的4个作用域: 作用域: 英文解释 缩写 局部作用域(函数内) Local(function) L 外部嵌套函数作用域 Enclosing functio loc E 函数定义所在模块(文件)作用域 Global(module) G python内建模块作用域 Builtin(python) B 包含关系(内建>模块>外部嵌套函数>函数内)变量名查找规则: 访问变量时,先查找本地变量,然后是包裹此函数外的函数内部的变量 ,之后是全局变量,最后是内建变量 L ---> E ---> G ---> B 在默认情况下,变量名赋值会创建或者改变当前作用域的变量global语句: 声明一个全局变量nonlocal语句: 外部嵌套函数变量 调用不可修改外部嵌套函数作用域内的变量进行操作lambda表达式: 创建一个匿名函数对象 lambda[ 参数1, 参数...]: 表达式 函数: eval () / exec() 函数 eval(srouce,globals=None, locals=None) 把一个字符串srouce 当成一个表达式来执行,返回表达式结果 eval(source, globals=None, local=None) 把一个字符串 srouce 当成一个表达式来执行,返回表达式执行的结果 exec(source, globals=None, locals=None) 把一个字符串source 当成程序来执行 全部划重点 加粗 加长 加大 溜了 不吹NB了....

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

Python全栈工程师(每周总结:1)

ParisGabriel python今年9月份将被国家纳入计算机二级资格证 先学就是鼻祖 几年后你就是大牛 Python人工智能从入门到精通 week summer: 数字(整型int,浮点数float,复数complex,布尔型bool)字符串str 列表list 等bool(true=1、false=0)None 空值算数运算符:+ - * / // ** % 优先级:(), [], {key: value}, {} 元组表达式、列表表达式、字典表达式、集合表达式x[index], x[index:index],x(arguments...), x.attribute 索引,切片,函数调用,属性引用** 指数 (最高优先级)~, +, - 按位翻转, 正号,负号*, /, %, // 乘,除,取模和地板除+, - 加法, 减法>>, << 右移, 左移运算符& 位与(AND)^ 位异或(XOR)| 位或(OR)<=, <, >, >=, ==, !=, is, is not, in, not in 比较,身份测试,成员资格测试not 布尔非and 布尔与or 布尔或if - else 条件表达式lambda lambda 表达式变量命名:必须以字母或下划线开头(驼峰法则)序列赋值:a,b,c = 100, 200, 300变量交换:a,b = 200,100del 删除变量help(“__main__”) 查看变量 Q退出内存自动管理方式:引用计数is/is not 判断是否为同一个对象id(obj)函数: 返回对象在内纯中的id小整数对象值:-5 ~ 256比较运算符:< <= > >= == != 数值对象的构造函数:float(obj) 字符串转换浮点数 int 转换整数complex(r,i) 创建复数bool(true/false) 创建布尔值bool(obj) 所有0或 空值都会返回falseabs(x) 取x绝对值round(number,ndigits) 四舍五入 ndigits小数点个数(可以是负数:反向取整)help(函数对象) 函数或查看详细帮助“\” 折行符() [ ] {} 隐式折行符 sep 两个值之间的分隔符默认空格print(sep = “”,end = “”){ end行位默认换行符not 布尔非or 布尔或 { 短路运算and 布尔与+ 表达式只有一个数据参加(一元运算符)- 表达式 如:a = 5 ,b = -a ,c = +a转移符:\' 单引号\" 双引号\\ 单反斜杠\n 换行\r 返回光标至行首\t 水平制表符\v 垂直制表符\f 换页\b 倒退\0 空字符,字符值为0\xXX XX为两位16进制表示的自符\uXXXX XXXX为4个16进制的Unicode16字符\UXXXXXXXX 8个16进制表示的Unicode32字符man ASCII 查看帮助文档命令常用ASCII编码:字符 十进制 十六进制 0 48 0x30 A 65 0x41 a 97 0x61len() 返回字符串的个数raw 让转义符无效(原始字符)(r“hello world”)+= *= 与其他符合运算符相同in/not in 判断字符串是存在字符串的比较运算:> >= < <= == != 依次按照编码进行比较,直到最短字符串结束为止s[int] 索引 index Python的字符串是不可以改变字符序列的Python序列都可以用索引来访问序列中的对象Python的序列正向索引是从0开始的最后一个索引为len(s)-1Python序列的反向索引是从-1开始的 -1是最后一个 第一个是 -len(s)切片 slice :s[(开始索引b):(结束索引e):(步长s)] 步长等于偏移量默认1 索引从0开始 顾头不顾尾 步长为负时反向切片(步长决定方向)python3 中常用函数;len (s) 返回序列长度max(s) 返回序列最大值元素min(s) 返回序列最小值元素ord(a) 返回一个字符的Unicode值(10进制)chr(i) 返回一个整数的Unicode字符bin(i) 将整数转换为二进制字符串oct(i) 将整数转换为八进制字符串hex(i) 将整数转换为十六进制字符串常用的字符串方法:文档参见:对象.方法名(方法传参)"abc".isalpha() # 语法是对的123.isalpha() # 语法是错的方法 说明S.isdigit() 判断字符串中的字符是否全为数字S.isalpha() 判断字符串是否全为英文字母S.islower() 判断字符串所有字符是否全为小写英文字母S.isupper() 判断字符串所有字符是否全为大写英文字母S.isspace() 判断字符串是否全为空白字符S.center(width[,fill]) 将原字符串居中,左右默认填充空格 width:所居中字符串的长度 fill:默认填充空格S.count(sub[, start[,end]]) 获取一个字符串中子串的个数 sub:所要获取的字符串 start:起始位置 end:结束位置S.find(sub[, start[,end]]) 获取字符串中子串sub的索引,失败返回-1start:起始位置 end:结束位置S.strip() 返回去掉左右空白字符的字符串S.lstrip() 返回去掉左侧空白字符的字符串S.rstrip() 返回去掉右侧空白字符的字符串S.upper() 生成将英文转换为大写的字符串S.lower() 生成将英文转换为小写的字符串S.replace(old, new[, count]) 将原字符串的old用new代替,生成一个新的字符串 count:更换的次数S.startswith(prefix[, start[, end]]) 返回S是否是以prefix开头,如果以prefix开头返回True,否则返回False,S.endswith(suffix[, start[, end]]) 返回S是否是以suffix结尾,如果以suffix结尾返回True,否则返回False以下是不常用的 S.title() 生成每个英文单词的首字母大写字符串S.isnumeric() 判断字符串是否全为数字字符ASCII 用8个位表示 最高位一定是0Unicode用16位表示 最高位也一定是0占位符和其的类型码:%s 字符串 使用shr(obj)转为字符串%r 字符串 使用repr(obj)转为字符串%c 整数转为字符串,使用chr(i)函数%d 10进制整数%o 8进制整数%x 16进制整数(字符a-f)%X 16进制整数(字符A-F)%e 浮点数(e)如 2.9e+10%E 浮点数(E)如2.9E+10%f %F 浮点数10进制形式%g %G 进制进形式浮点数或指浮点数自动转换%% 等同于一个 % 字符 占位符与类型码之间的格式语法:%[- + 0 宽度.精度]类型码- 左对齐+ 右对齐0 左右空白位置补0宽度:整个数据输出的宽度精度:保留小数点后多少位,默认6位可迭代对象包括:字符串 str 列表 list元组 tuple字典 dictrange()函数: 可迭代对象创建 也叫整数序列生成器 (顾头不顾尾)列表 list:(列表的id是不可变的 除非重新定义)列表是一种容器(通常用来储存计算机的数据对象)列表是可以被改变的序列是由一系列特定元素组成的 元素与元素之间可能没有任何关联关系但他们有先后顺序关系列表的运算:+ 用于拼接列表+= 用于将右侧的可迭代对象的数据追加到原列表中* 用于生成重复列表*= L * = 2 (L = L * 2)列表的比较运算:< <= > >= == !=比较规则和字符串完全相同列表的in、notin:判断一个元素是否存在于列表中 如果纯在返true否则falsein 和 nat in 返回值相反(只能判断列表元素 不能判断元素内字符) week summerkey word: print: print(“hello world”) 输出打印语句 input: input(“plaese input :”) 输入函数 提示可以为空 if : if 1 >2 : print("1>2") elif 1>3: print("1>3") else: print("1<2") if:如果 else:否则 elif:否者如果 (单if不加else:如果真) while: i = 0 while i < 5: print(i) i += 1 else: print("6") i:循环变量 while可以加或不加else 条件不成时立执行else若条件成立 循环结束后将继续执行else for: for x in ramge(10): print(x) else: print(11) x:循环取出可迭代对象的值 for可以加或不加else 条件不成时立执行else若条件成立 循环结束后将继续执行else 死循环: while True; a = int(input()) print("123") if a = “” break 死循环: 无限循环 配合break跳出循环死循环不能加else break 终止循环一般配合if语句使用 终止循环 若循环套用是只会在本循环作用域有效不影响外部循环 若break跳出循环 else将不再执行continue 跳过本次循环一般配合if语句使用 跳过本次循环 若循环套用是只会在本循环作用域有效不影响外部循环 continue 用法需注意 细节不当将形成死循环复合语句的嵌套: for x in range(10) for y in range(5) print(x , y) if x == 10: break else: for x in range(50) print(x) i = 0 while i < 10: peint(i) x = 0 while x < 10: print(x) if i == 10: break else: while i <10: print(i * i) if a > 5: if a < 10: peint(a) else: if a > 0 : print(a) else: print(a) if while for 可以任意嵌套配合使用

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

Python全栈工程师(while、占位符)

ParisGabriel Python 入门基础 UnicodeASCII 用8个位表示文字 ,最高位一定是零,低七位表示数值Unicode是由16个位组成的(65535) 最高位也是0x0000~0xfffhelp(str) 查看所有str函数 字符串的格式化表达式:生成一定格式的字符串格式字符串中以 % 开头的为占位符,占位符的位置将参数值替换语法:格式字符串 % 参数值格式字符串 % (参数值1,参数值2,...)占位符和其的类型码:%s 字符串 使用shr(obj)转为字符串%r 字符串 使用repr(obj)转为字符串%c 整数转为字符串,使用chr(i)函数%d 10进制整数%o 8进制整数%x 16进制整数(字符a-f)%X 16进制整数(字符A-F)%e 浮点数(e)如 2.9e+10%E 浮点数(E)如2.9E+10%f %F 浮点数10进制形式%g %G 进制进形式浮点数或指浮点数自动转换%% 等同于一个 % 字符 占位符与类型码之间的格式语法:%[- + 0 宽度.精度]类型码- 左对齐+ 右对齐0 左右空白位置补0 宽度:整个数据输出的宽度精度:保留小数点后多少位,默认6位"%10d" %123 #" 123""%+10d"%123 #" +123""%-10d"%123 #"123 ""%10s"%"abc" #" abc""%010d"%123 #"0000000123" "%f"%3.14159625358 # "3.141593""%7.2f"%3.14159265358#" 3.14" 循环语句:while:根据一定的条件,重复执行一些相同或相似的内容先判断真值表达式是否成立在执行执行完内容继续返回真值表达式判断是否成立 直到真值表达式为false时 判断是否有else有则执行else的内容没有则循环结束注意事项:要控制真值表达式的值来防止死循环通常用真值表达式内的循环变量来控制真值表达式的值通常在循环语句块内改变循环变量来控制循环次数和变量走向while的嵌套:while语句和其他语句一样,可以嵌套放入任何复合语句当中break:用于循环语句(while、for)中用来终止当前循环(跳出循环)当break语句执行后此循环以后的语句将不再执行break终止循环时 else语句块将不再执行break语句通常和if组合使用break只能终止当前作用域 如循环嵌套时,不会跳出外循环break只能在循环语句(while、for)内使用死循环:死循环是指循环条件一直成立的循环死循环通常用break语句来终止循环死循环的else语句块永远不会执行 练习:1.输入一行字符串,将字符串中Unicode编码值最大的一个字符打印出来(不允许用max函数)提示:while内可以嵌套if 答案: print("Answer to question 1:", "\n") s = input("plaese input at will string:") i = 0 top = s[0] while i < len(s): if ord(top) < ord(s[i]): top = s[i] i += 1 print("you input string in top1:", top, ord(top)) 2.打印 从零开始的浮点数,每个数增加0.5,打印出10以内的这样的数:0.00.51.00.52.0...10 答案: print("Answer to question 2:", "\n") i = 0 while i < 10: i += 0.5 print(i) 3.打印输出1~20在同一行内 结束后换行 答案: s = 0 while s < 20: s += 1 print(s, end = " ") else: print() 4.打印输出1~20在同一行内 打印10行 i = 0 while i < 10: s = 0 while s < 20: s += 1 print(s, end = " ") else: print() i += 1 5.当输入一些数字,输入负数时结束输入当完成输入完后,打印输入的数时多少 答案: s = 0 while True: a = int(input("plaese input at will integer:")) s += a if a < 0: break print(s) 6.Sn = 1/2+1/4+1/8....+1/(2**n)求当n等同于100时Sn的值是多少 答案: Sn = 1 i = 0 while i < 100: i += 1 Sn += 1 / 2 ** i print(Sn) 7.输入一个整数打印出矩形 若输入1则输出1个# 例如: 输入1:# 输入2:#### 输入6:####### ## ## ## ## ####### 答案: s = int(input("plaese input at will integer:")) if s > 1: print("#" * s) i = 2 while i < s: i += 1 print("#" + " " * (s - 2) + "#") print("#" * s) else: print("#") 8.用while语句实现打印三角形,输入一个整数表示三角形的宽度和高度,打印出相应的三角形如:1)**********2)******* ** *3) * *********4)********** 答案: a = int(input("plaese input at will ingeger:")) i = 0 b = a c = a d = a while i < a: i += 1 print("*" * i) print() i = 0 while i < d: print((a - d) * " " + "*" * d) d -= 1 print() i = 0 while i < c: i += 1 print((c - i) * " " + "*" * i) print() i = 0 while i < b: print("*" * b) b -= 1 a = int(input("plaese input at will ingeger:")) i = 0 d = a while i < a: while i < d: print((a - d) * " " + "*" * d) d -= 1 print("*" * (i + 1)) i += 1 print()

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

Python全栈工程师(运算符、if)

ParisGabriel Python 入门基础 比较运算符:< 小于<= 小于等于> 大于>= 大于等于== 等于!= 不等于 语法: 表达式1>表达式2 返回布尔类型 数值对象的构造函数: float(obj) 用字符串或数字转换为浮点数,如果不给出实参,则返回0.0 int(x=0,base=10) 用数字或者字符串转换为整数,如果不给出实参,则返回0.0 bas表示是进制 complex(r=0.0,i=0.0) 用数字创建一个复数 bool(x) 用x创建一个布尔值(true/false) bool(obj)返回假值的情况:None 空值false 假值00.00j所有的数字零‘’ 空字符串[ ] 空列表{ }空词典() 空原组... 函数调用表达式:函数名(传参列表)说明:函数调用表达式时,此表达式一定是会返回一个对象的引用关系如果不需要返回值时,通常返回none对象的引用关系 内建数值型函数:abs(x) 取x的绝对值 round(number,ndigits=0) 对数值进行四舍五入 ,ndigits是小数向右取整的位数,负数表示像左取整 pow(x,y,z=none) 相当于x**y或x**y%z help()查看帮助 help(函数或对象名) help(int) 语句: 语句是由一些表达式组成,通常一条一句可以独立执行来完成一部分事情并形成结果Python建议一条语句写在一行内多条一句子写在一行内需要用“;”分开 print("hello") x = 100 + 200 print(x) print("hello"); x = 100 + 200; print(x) 显示换行:折行符“\”折行符必须一行的末尾,来告诉解释执行器下一行也是本行的语句 隐式折行符:所有的括号的内容换行,成为隐式折行符()、{}、[] 函数的使用:基本输入函数input从标准输入设备上读取一个字符串(末尾的换行符会被删除)返回输入的字符串(仅Python3) 提示字符可以为空 基本输出函数:print将一系列的值一字符串的形式输出到标准输出设备上,默认为终端选项的关键字参数:sep:两个值之间的分隔符,默认为一个空格end:输出完毕后在末尾自动加一个字符串,默认为换行符(\n) 练习:1.输入两个整数,分别用变量x,y绑定1)打印输出计算这两个数的和2)打印输出计算这两个数的积3)打印输出计x的y次方 答案: x = int(input("plwase input integer:")) y = int(input("plwase input integer:")) print(x + y, "\n", x * y, "\n", x ** y) 2.今天是小明的20岁生日,假设每年都有365天,计算他过了多少个星期天,剩余多少天 答案: print((20 * 365) // 7, "星期天 剩余", (20 * 365) % 7, "天") 3.本别输入当前时间的时、分、秒 在终端打印输出当前距离0:0:0过了多少少天 答案: h = int(input("plwase input hour:")) m = int(input("plwase input minute:")) s = int(input("plwase input second:")) print(h * 3600 + m * 60 + s, "second") if语句: 让程序根据条件选着性的执行某条语句或某些语句 语法: a = int(input("plaese input integer:")) if a > 0: print(a, ">0") elif a > 6: print(a, ">6") elif a > 100: print(a, ">100") else: print(a, "<0") elif可以有0个或多个else可以有零个或1个 并且所有语句当中只能执行一个 if的嵌套:if语句本身是由多条子句组成的一条复合语句if语句可以作为语句嵌套到另一个语句内部 条件表达式:表达式1 if 真值表达式 else 表达式2根据真值表达式的取值(true、false)来决定执行表达式1或2,并返回结果 money = int(input("100")) pay = money - 20 if money >= 100 else money pass语句:通常用来填充语法空白又名空语句 布尔运算符:not and or布尔非 not如果为true返回false否则为反布尔或 or优先返回真值见true得true 布尔与 and优先返回假值对象见false得false 正负号运算符:+ 表达式- 表达式这是一个一元运算符(只有一个数据参加运算) 练习:1.北京出租车价格 3公里以内13元基本单价:2.3元/公里(超出3公里以外)回空费:超过15公里 每公里 加收单价的50%的会空费(3.45元/公里)输入公里数 打印费用金额 答案: kilometre = int(input("plaese input kilometre:")) if kilometre < 0: if kilometre > 15: money = (kilometre - 15) * 3.45 + (15 - 3) + 13 print("money:", money, "$") elif 3 < kilometre < 15: money = (kilometre - 3) * 2.3 + 13 print("money:", money, "$") else: print("money:13$") else: print("not'is kilonetre") 2.输入一个学生的三科成绩(3个整数:打印出最高分、最低分、平局分是多少 答案: a = int(input("plaese input english mark:")) b = int(input("plaese input language mark:")) c = int(input("plaese input mathematisc mark:")) if 100 > a > 0 and 100 > b > 0 and 100 > c > 0: if a > b and a > c: print("top score english:", a) elif b > c and b > a: print("top score language:", b) elif c > a and c > b: print("top score mathematisc:", c) if a < b and a < c: print("lowest english:", a) elif b < c and b < a: print("lowest language:", b) elif c < a and c < b: print("lowest mathematisc:", c) print("mean:", (a + b + c)/3) else: print("not'is mark") 3.bmi指数(body、mass、index)以称身体质量指数bmi的计算公式: bmi = 体重(公斤)/身高的平方标准表: bmi< 18.5 体重过轻18.5<=bmi<24 体重正常bmi> 24 体重过重输入公斤体重、身高 打印出 bmi的值 并打印体重状况 答案: z = int(input("plaese input your weigh:")) g = float(input("plaese input your height:")) if z < 0 and g < 0: bim = (z / g) ** 2 if bim < 18.5: print("your bim qing") elif 24 > bim > 18.5: print("your bim normal") else: print("your bim serious") else: print("your inuput error")

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

Python全栈工程师(Linux基本操作)

ParisGabriel Python 入门基础 Linux :Ubuntu操作系统 首先我们说的是Linux操作系统常用的快捷键以及终端命令 一. VMware Workstation 虚拟机 快捷键: Ctrl+Alt+Ent 调节虚拟机内操作系统的全屏以及窗口 Ctrl+Alt 释放虚拟机占用鼠标 二. 终端命令: 命令格式:命令名+选项+参数 1.打开终端: 手动找到终端打开 Alt+F2 打开搜索窗口输入:gnome-terminal Ctrl+Alt+T 打开终端(推荐) 2.终端窗口快捷键 Ctrl+Shift+“+” 放大终端 Ctrl+“-” 缩小终端 Ctrl+L 清屏 Ctrl+d (exit) 退出 关闭 Ctrl+C 终止当前命令的执行 Ctrl+S 隐藏终端输出 Ctrl+Q 恢复终端输出 3.终端命令行 “.” 代表当前目录 “..” 代表上一级目录 “~” 代表用户主目录 “/” 代表根 (最高目录) Windows有 C: D: F: 盘符之分 Linux系统不分盘 / 就是最高盘 最高根目录 相当于Windows的计算机 是以目录树形式的储存 Linux系统划分用户 开机时如果有多个目录可以选择账户 其实这个账户和Windows的分盘也差不多 。 tarena代表用户 home/tarena 就是tarena用户的 主目录 ① sudo命令 获取root权限(获得系统最高权限) 语法:sudo+“Linux终端命令” tarena@tedu:~$ sudo mkdir test [sudo] tarena 的密码: 输入账户密码获得最高权限既可后续操作, pwd 查看当前所在目录 tarena@tedu:~$ pwd /home/tarena ② ls 命令 ls -l 当前目录所有内容详细信息(黑色:文件 蓝色:文件夹 红色:压缩包) ls - “文件名 ” 查看指定文件详细信息 ls -a 查看当前目录所有文件 包括隐藏文件 语法: ls命令可以连着使用 例如 ls -la (后面有点的都是隐藏文件) tarena@tedu:~$ ls -la 总用量 269436 drwxr-xr-x 31 tarena tarena 4096 6月 29 20:14 . drwxr-xr-x 3 root root 4096 7月 17 2017 .. drwxrwxr-x 20 tarena tarena 4096 7月 17 2017 anaconda3 -rw------- 1 tarena tarena 6466 6月 29 20:14 .bash_history -rw-r--r-- 1 tarena tarena 220 7月 17 2017 .bash_logout -rw-r--r-- 1 tarena tarena 4122 1月 26 15:43 .bashrc -rw-r--r-- 1 tarena tarena 3771 7月 17 2017 .bashrc-anaconda3.bak drwx------ 18 tarena tarena 4096 10月 27 2017 .cache drwxrwxr-x 3 tarena tarena 4096 10月 27 2017 .conda drwx------ 26 tarena tarena 4096 6月 29 20:13 .config ③ mkdir touch 命令 mkdir “目录名” 创建目录 mkdir -p 目录1/目录2/目录3 创建多层目录 语法:mkdir 也可以连着用 例如 mkdir a b c d mkdir -p a/b/c/d tarena@tedu:~$ mkdir a b c d tarena@tedu:~$ cd a tarena@tedu:~/a$ mkdir -p a/b/c/d tarena@tedu:~/a$ cd a/b/c/d tarena@tedu:~/a/a/b/c/d$ pwd /home/tarena/a/a/b/c/d tarena@tedu:~/a/a/b/c/d$ touch “文件名” 创建文件 Linux操作系统和Windows是文件性质不一样 Linux文件只是文件 没有后缀(扩展名) 下面 1 1.txt 1.doc 除了文件名不一样 其他的都一样 没有什么txt文件之分 ③rm命令 rm -i “文件名” 确认是否删除文件(y/n) rm -r “目录名” 删除目录 rm -f “文件名/目录名” 强制删除 语法:rm依然可以联合使用 例如 rm -rf (强制并且无提示删除一切文件) tarena@tedu:~$ rm -rf a Linux操作系统是目录树查看命令 ④tree 命令 tree 查看当前目录树 tree“目录名” 查看指定目录目录树 tarena@tedu:~$ ls anaconda3 d pycharm-professional-2017.1.5.tar.gz 视频 音乐 b examples.desktop PycharmProjects 图片 桌面 c my_env 公共的 文档 core pycharm-2017.1.5 模板 下载 tarena@tedu:~$ tree my_env/ my_env/ ├── get_env_details ├── initialize ├── postactivate ├── postdeactivate ├── postmkproject ├── postmkvirtualenv ├── postrmvirtualenv ├── preactivate ├── predeactivate ├── premkproject ├── premkvirtualenv └── prermvirtualenv 0 directories, 12 files ⑤ 压缩包tar命令 压缩 tar -zcvf “文件名”.tar.gz“要压缩的文件名” 解压 tar -zxvf “文件名”.tar.gz -C “要解压到的路径” z:gzip调用打包功能 c:打包 x:解包 v:执行细节 f:使用档案名字 tar zxf tar zcf 也可以不过语法不规范 tar -zxf tar -zcf v可以省略 ⑥压缩包mv命令 mv “文件名” “路径” 剪切到指定文件 mv “文件名” “文件名” 重命名文件 tarena@tedu:~$ mv b.tar.gz b tarena@tedu:~$ cd b tarena@tedu:~/b$ ls b.tar.gz tarena@tedu:~/b$ mv b.tar.gz best.tar.gz tarena@tedu:~/b$ ls best.tar.gz ⑦ 复制 cp 命令 语法: cp “源文件” “路径” ⑧ cd目录命令 cd “目录名” 进入单目录 cd “相对路径” 一次进入多个目录 cd “绝对路径” 跳转到绝对路径 cd .. 跳转到上一级目录 cd 回到用户主目录 ~ 回到用户主目录 init0 关机 init6 重启 Python --version 查看Python2版本 tarena@tedu:~$ python --version Python 2.7.12 Python3 --version 查看Python3版本 tarena@tedu:~$ python3 --version Python 3.5.2 很多命令都是可以混合 组合使用 例如 “.”可以代表当前目录 解压到当前目录 “~”代替用户主目录 输入时用TAB会自动补全文件名 名字前部分相同再按一次会显示有几那个 然后在输入TAb就可以 tarena@tedu:~$ ls 1 core pycharm-professional-2017.1.5.tar.gz 文档 1.doc d PycharmProjects 下载 1.txt examples.desktop 公共的 音乐 anaconda3 examples.desktop.tar.gz 模板 桌面 b my_env 视频 c pycharm-2017.1.5 图片 tarena@tedu:~$ cd b tarena@tedu:~/b$ ls 1.txt best.tar.gz tarena@tedu:~/b$ tar -zxvf best.tar.gz -C ~/d examples.desktop tarena@tedu:~/b$ cd ~/d tarena@tedu:~/d$ ls examples.desktop tarena@tedu:~/d$ cd tarena@tedu:~$ cd b tarena@tedu:~/b$ ls 1.txt best.tar.gz tarena@tedu:~/b$ tar -zxvf best.tar.gz -C . examples.desktop tarena@tedu:~/b$ ls 1.txt best.tar.gz examples.desktop tarena@tedu:~/b$

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

1.全栈工程师Python基础

Python基础¶ Python概述 计算机语言概述 语言: 交流的工具,沟通媒介 计算机语言: 人跟计算机交流工具,翻译官 Python是计算机语言里的一种 Python编程语言 代码: 人类语言,通过代码命令机器,跟机器交流 Python解析器: 就是那个担任翻译官工作的 流程: 写代码 执行: 由翻译官(Python解析器)把命令(Code) 翻译给机器, Python 简史 1989年, Guido van Rossum 2014: 宣布2.7支持到2020 2017: AI 元年, Pyhton崛起 Python特点: 速度问题 Python的应用领域 全能 设计哲学: 平衡发展,样样通,简洁明了 Python 为什么这么火 环境问题 anaconda+pycharm python3.6 环境 学习环境: 直播课: 网易云课堂 讲义+代码: github 教科书: gitbook 工作环境 环境安装: gitbook上有 http://www.cnblogs.com/zhouzhishuai/p/8401103.html 操作系统 windows Linux 我们的标准系统: windows下开虚拟机,虚拟机安装uabntu 软件环境 使用anaconda3+pycharm代替 Python的执行方式 本质上Python是一堆命令的集合 执行过程是逐行执行,遇到问题即刻终止 打印 Hello world jupyter notebook 快捷键: - alt+Enter 切换代码模式 - Shift+# 笔记 或 文本输入 - alt+Enter 也能运行代码

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

面试总结——Java高级工程师

试前面也总结了一和二, 这第三篇可能更偏向于是内心的独白篇和面试技巧总结吧..... 一、独白 之前也面试别人,现在轮到自己找工作,怎么说呢,每个面试官的看法不一样,面试的方式就不一样,比如我面试别人我喜欢问项目中他用到了那些,然后针对用到的技术去问一些问题,或者说对于某些场景的一些技术实现方案是我特别喜欢问的,比如当你的接口服务数据被人截包了,你如何防止数据恶意提交? 相对来说,Java的底层和基础会问的少一点,当然问的少不是代表不问,而是说侧重点在于你的所做过的项目和你的设计思路如何。当然,懂基础和底层更好,这样能让你知其然,更知其所以然,写出来的代码和程序更具有健壮性和可维护性。所以说,基础还是很重要的。 现在轮到自己出去面试,怎么说呢,其实还是挺紧张的,原以为自己不会因此紧张或者焦虑,实际上,还是有的,在没找到合适的工作的时候,甚至晚上有点睡不着觉,总觉着有什么事压在心头,睡觉都不安心。既然睡不着,那还是看看资料吧,我有个习惯,睡前看点问题,第二天早上就能想到答案,睡前记点资料,第二天早上就能记得特别深刻,不说废话了,直接进入正题吧。 二、面试技巧 1、背熟你的简历 原因:面试的第一个问题,一般都是让你简单介绍下你自己,或者介绍一下你最近的项目,而一个面试者,如果连自己的简历都无法熟知,对里面提到的项目、技术都无法描述清楚的话,我想没有哪家公司会接受这样的,哪怕你是超级人才,你自我表述不行,估计也会为此头疼,所以,切记:一定要背好自己的简历,不要求你能全部记下,至少要熟记你最近所待过的两家公司,这两家公司里面你做过的项目,你负责的模块,项目里面用到的技术以及相对应的技术实现方案(这个尤为重要)。 2、深入了解并熟记部分java基础知识 原因:大部分公司无论面试初级还是高级,无论是笔试还是面试,都会问到一系列基础题,这些基础题大概涵括jvm、字符串、集合、线程等等,如果说每一个让你死记硬背你肯定记不住,那么就是理解中记忆了,拿jvm来说 ,如果让你谈谈你对jvm的理解, 那么你首先得知道JVM有哪些结构组成,每个结构用来做什么的,然后考虑一个Java对象从创建到回收,如何途径JVM这些结构的。如果你从这些方面来综合记忆,相信事半功倍,并且你理解的更透彻。 至于如果让你谈集合,举例List集合下面ArryList、LinkedList、Vector等集合的区别,那么同样的方法,你需要理解每一个的结构组成是什么,你才能知道他有什么作用,这样你在平时的用法上会更精炼,而且在面试过程中,也不至于哑口无言。 3、保持自信心和沉重冷静的心态 原因:面试过程中,自信是少不了的,相信你可以, 面试的路上可以自己对自己说一句: I belive I can ! 反正我就是这么做的,自我的心里暗示吧,其实面对面试官的时候,你自信的状态也会让面试官觉得你是个很有底气的人,至少从感觉上会给你打个高分。另外还有就是保持沉重冷静,如果是让你提供技术方案或者说说某个技术原理,没必要一紧张一咕噜的什么都说,你可以对面试官说:我先想想,然后自己组装记忆中的知识,组装下语言,有条理的说出来,这样能更好的表现你的才能,不是吗? 面试谁都会紧张,我也会紧张,有时候明明记得的知识点忘了,没关系,大胆的说忘了,或者直接说不知道。 要记住,有部分不知道没关系,如果全都知道,那你应该是CTO级别了(开个玩笑)。 4、尽量记住面试过程中你回答不出来或者回答存在不妥的问题 原因:面试失败了没关系,毕竟每个公司的要求不一样,问的问题和你擅长的方面可能有所出入,但是请记住一点:面试过程中那些你回答不出来问题,或者你自己感觉回答不太准确的问题,自己记下来,如果不会的,你可以当场问问面试官有没有好的解答,如果面试官不愿意告诉你(一般是基础方面面试官就懒得答你),那么你就自己回家慢慢查资料,如果是某些特定的技术,也可以自己写写案例什么的,毕竟知识点就那么多,问题百变,原理不变,面试也是一个学习知识的过程,让你了解大部分公司目前需要或者要求的技术。这次不知道,下次就知道了 5、去面试之前,最好先了解你要去面试公司的情况(包括产品、项目情况) 原因:俗话说,知己知彼,百战不殆,面试就是一场战斗,你需要了解你面试公司基本情况,包括岗位要求,这样你就能大概知道你需要面试的这家公司的技术要求情况。 为何让你去了解这家公司的主营产品和项目呢,就是让你大概了解这家公司的一个技术架构的情况,包括你可能对他们的一种实现方式提出质疑和疑惑,相信面试官很愿意帮你解答这些问题的。这样你既图了表现,也学到了知识,何乐而不为。 6、合理安排你的面试时间(如果有多家公司的面试机会,尽量把你想去的公司放到最后去面试) 原因:估计很多人都不理解这个,可能大部分的人对于如何安排面试时间比较迷茫,随意安排。可是这里有个技巧,如果同时有多个面试机会,你把你最想去的公司放到最末尾去面试,这样你经历过了前面的这些公司筛选,如果成功了是个机会,如果没成功,也是为最后做铺垫。 不过这里就需要考虑两点:1、你需要记住你投简历的公司和基本情况(这说明你不是海投的) 2、如果记不住,那么可以先应答一个时间,后续了解公司信息之后,通过邮件或者其他方式与其约定,调整面试时间。而且建议安排一天的面试公司不要超过两家,最好的是上午一家,下午一家,这样你能有充足的时间调整状态。 三、面试题基础总结 1、 JVM结构原理、GC工作机制详解 答:具体参照:JVM结构、GC工作机制详解,说到GC,记住两点:1、GC是负责回收所有无任何引用对象的内存空间。 注意:垃圾回收回收的是无任何引用的对象占据的内存空间而不是对象本身,2、GC回收机制的两种算法,a、引用计数法 b、可达性分析算法( 这里的可达性,大家可以看基础2 Java对象的什么周期),至于更详细的GC算法介绍,大家可以参考:Java GC机制算法 2、Java对象的生命周期 答:创建阶段 、 应用阶段 、不可见阶段 、不可达阶段 、收集阶段 、终结阶段、 对象空间重新分配阶段等等,具体参照:Java 对象的生命周期 3、Map或者HashMap的存储原理 答:HashMap是由数组+链表的一个结构组成,具体参照:HashMap的实现原理 4、当数据表中A、B字段做了组合索引,那么单独使用A或单独使用B会有索引效果吗?(使用like查询如何有索引效果) 答:看A、B两字段做组合索引的时候,谁在前面,谁在后面,如果A在前,那么单独使用A会有索引效果,单独使用B则没有,反之亦然。同理,使用like模糊查询时,如果只是使用前面%,那么有索引效果,如果使用双%号匹配,那么则无索引效果 5、数据库存储日期格式时,如何考虑时区转换问题? 答:使用TimeStamp , 原因参照:java编程中遇到的时区转换问题 6、JavaObject类中有哪些方法? 答:Object有哪些方法 7、HTTP协议,GET和POST 的区别 答:浅谈HTTP中GET和POST的区别 四、线程、设计模式、缓存方面 1、SimpleDataFormat是非线程安全的,如何更好的使用而避免风险呢 答:关于SimpleDateFormat安全的时间格式化线程安全问题 2、如何看待设计模式,并简单说说你对观察者模式的理解 答:1、设计模式有神马用2、观察者模式类图及实现 3、集群环境中,session如何实现共享 答:1、Java集群之session共享2、session多服务器共享方案,还有一种方案就是使用一个固定的服务器专门保持session,其他服务器共享 4、分布式、集群环境中,缓存如何刷新,如何保持同步? 答:A、缓存如何刷新?1、定时刷新 2、主动刷新覆盖,每个缓存框架都有自带的刷新机制,或者说缓存失效机制,就拿Redis和 Ehcache举例, 他们都有自带的过期机制,另外主动刷新覆盖时,只需获取对应的key进行数据的覆盖即可 B、缓存如何保持同步? 这个redis有自带的集群同步机制,即复制功能,具体参考:基于Redis分布式缓存实现,Ehcache也有分布式缓存同步的配置,只需要配置不同服务器地址即可,参照:Ehcache分布式缓存同步 5、一条sql执行过长的时间,你如何优化,从哪些方面? 答:1、查看sql是否涉及多表的联表或者子查询,如果有,看是否能进行业务拆分,相关字段冗余或者合并成临时表(业务和算法的优化) 2、涉及链表的查询,是否能进行分表查询,单表查询之后的结果进行字段整合 3、如果以上两种都不能操作,非要链表查询,那么考虑对相对应的查询条件做索引。加快查询速度 4、针对数量大的表进行历史表分离(如交易流水表) 5、数据库主从分离,读写分离,降低读写针对同一表同时的压力,至于主从同步,MySQL有自带的binlog实现 主从同步 6、explain分析sql语句,查看执行计划,分析索引是否用上,分析扫描行数等等 7、查看mysql执行日志,看看是否有其他方面的问题 个人理解:从根本上来说,查询慢是占用mysql内存比较多,那么可以从这方面去酌手考虑 五、设计方案相关 面试还会问到一些关于设计方案相关的问题,比如 1、你的接口服务数据被人截包了,你如何防止数据恶意提交? 答:我们可以在接口传输参数里面设置一个业务编号,这个编号用来区分是否重复提交。这样即使数据被抓包了,对方也无法区分每个字段你的含义,这时,这个业务编号的作用就来了 2、假设服务器经常宕机,你从哪些方面去排查问题? 答:这个就留个各位看官补充了,可评论回复 总而言之该看的还是得看,还学的还是得学。再次强调,基础很重要!面试技巧同样很重要,还是那句话:祝愿各位看官都能找到心仪的工作吧~~ 另外,奉劝大家不要频繁跳槽,这些知识点能提升固然好,不要盲目跳槽,找工作很累的,而且没有哪家公司喜欢频繁跳槽的员工 java程序猿跳槽应该学哪些方面的技术 互联网产品、大型企业级项目常会用到的: 并发处理技术。具体到Java上通常是涉及java.util.concurrent、并发锁机制、NIO等方面,当然最近比较火爆的Netty框架也可以作为高并发处理的备选方案之一,这需要对Java的线程调度机制有着比较深的理解。不过这些可能会涉及并发控制的对象(比如reentrantlock等)只能存在于一个JVM里的问题,一旦系统规模大到需要部署多个JVM来处理并发的情况,则需要采用共享session的技术(比如spring-session),或者尽可能将系统后台设计为无状态的服务,这需要对RESTful有着较深的理解。 高可用、负载均衡技术。互联网产品、企业级应用通常要求一年里的Downtime控制在很小的范围内,这需要足够的高可用和负载均衡架构来支撑,这个一般和Java技术本身没太大关系,但却是一名初级程序员向高级程序员甚至是架构师CIO进阶的必备技术,因此可以适当了解一下Nginx、HAProxy等对这方面的支持。另外现在最“时髦”的做法是将应用docker化,配合ETCD、kubernetes等工具在容器的层面上实现高可用和负载均衡,当然这需要看实际的需求,最时髦的不见得是最适用的,要考虑构建成本。 缓存技术。缓存应该是大型系统中或高并发条件下提高响应速度的亘古不变的真理(虽然也看到过淘宝搜索商品功能采用的大数据处理技术实现的零缓存的文章,但能达到淘宝的体量和技术水平一般不太可能),这方面的工具太多了,ehcache、memcached、redis……从Java的角度来讲,需要了解的一是Java对这些工具的连接器,二是缓存技术背后的JSR-107标准,可以参考spring-cache的实现,阅读一下源码加深理解。 异步处理技术。这通常也是抵消高并发的处理手段之一,从Java的角度看最简单的异步处理就是新启动一个异步线程,这同样也需要对Java的线程调度有所了解,当然也可使用Spring中的@Async之类的也可以简单实现异步线程的处理。如果是非常消耗资源的业务处理,简单的异步线程是满足不了需求的,这就需要一些消息中间件来做这些异步处理了,消息中间件有很多,activemq、rabbitmq、kafka……需要了解的是Java对这些中间件的连接器。不过异步处理中最关键的是事务保证的问题,这可能需要对事务的两步提交有所了解。 在这里我有一个专门为跳槽java开发人员想要跳槽准备的一个线路图: 一共分为5大专题: 工程化专题: 源码分析: 分布式/高可用/高并发专题: 双十一架构: 性能优化: 工作一到五年的程序员朋友面对目前的技术无从下手,感到很迷茫可以加群744677563,里面有阿里Java高级大牛直播讲解知识点,分享知识,课程内容都是各位老师多年工作经验的梳理和总结,带着大家全面、科学地建立自己的技术体系和技术认知!

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

高级Linux工程师常用软件清单

作为Linuxer,你一定很好奇别人在玩Linux的时候系统里面都装了什么软件,我曾经也是这样,今天为了打开这个脑洞的尴尬局面,我把我在ubuntu的使用过并觉得值得推荐的应用或工具推荐给你,当然如果你有更好的工具欢迎你留言。 目录 日常工具 系统工具 开发工具 终端工具 一、日常工具篇 1.1、Google Chrome Google Chrome是一个由Google公司开发的免费网页浏览器,其应用商店有众多出色的应用以及插件,此应用属于跨平台于Mac、Linux、Windows、Android等,因而数据的同步就okay了;此外它还拥有一个开源的兄弟Chromium。强烈推荐 方法一:在官网下载对应版本的deb后执行 sudodpkg-i*.deb&&sudoapt-getinstall-fy 方法二:包管理apt-get安装 sudoapt-getinstallgoogle-chrome-stable 刚说了Google Chrome有众多的出色的插件,那还是得说几个我常用的AdBlock:最受欢迎的Chrome扩展,拥有超过4000万用户!屏蔽整个互联网上的广告The QR Code Extension:允许当前页面生成QR码,并使用网络摄像头扫描QR码。Window Resizer:调节屏幕的分辨率,诸多时候用户开发Vimium:vim的分身Proxy SwitchyOmega:轻松快捷地管理和切换多个代理设置Wechat:微信马克飞象:使用印象笔记扩展程序一键保存精彩网页内容到印象笔记帐户惠惠购物助手:【网易出品】在您网购浏览商品的同时,自动对比其他优质电商同款商品价格,并提供商品价格历史,帮您轻松抄底,聪明网购不吃亏JSON-handle:顾名思义就是处理JSON数据的工具 ... ... 1.2、FirefoxFirefox即火狐浏览器,它是一个安全高效且体积小的浏览器,它具有速度快、隐私保护、不同设备之间同步数据、个性化定制等特性,对于我来说呢,Firefox具有众多的开发插件。 sudoapt-getinstallfirefox-y 1.3、Gparted GParted是一个分区工具,它可以用于创建、删除、移动分区,调整分区大小,检查、复制分区等操作。可以用于调整分区以安装新操作系统、备份特定分区到另一块硬盘等 sudoapt-getinstallgparted-y 1.4、搜狗输入法 搜狗输入法顾名思义,它就是一个输入法。 在官网下载deb后,执行 sudodpkg-i*.deb&&sudoapt-getinstall-fy 1.5、FileZilla FileZilla是一个免费开源的FTP软件,分为客户端版本和服务器版本,具备所有的FTP软件功能。可控性、有条理的界面和管理多站点的简化方式使得Filezilla客户端版成为一个方便高效的FTP客户端工具。 sudoapt-getinstallfilezilla 1.6、WPS WPS是由金山软件股份有限公司自主研发的一款办公软件套装,可以实现办公软件最常用的文字、表格、演示等多种功能。具有内存占用低、运行速度快、体积小巧、强大插件平台支持等特点。 在官网下载对应版本的deb后执行 sudodpkg-i*.deb&&sudoapt-getinstall-fy 顺便路过提提LibreOffice,它也是是一款功能强大的办公套件,默认在ubuntu自带,强迫症看起来不舒服不使用。 1.7、有道翻译 有道词典是由网易有道出品的全球首款基于搜索引擎技术的全能免费语言翻译软件,为全年龄段学习人群提供优质顺畅的查词翻译服务 #在官网下载对应版本的deb后执行 sudodpkg-i*.deb&&sudoapt-getinstall-fy 1.8、网易云音乐 网易云音乐是一款专注于发现与分享的音乐产品,依托专业音乐人、DJ、好友推荐及社交功能,为用户打造全新的音乐生活。 #在官网下载对应版本的deb后执行 sudodpkg-i*.deb&&sudoapt-getinstall-fy 网易云音乐最小化托盘问题 ,解决方案:把原来的Exec那行改为 Exec=env XDG_CURRENT_DESKTOP=Unity netease-cloud-music %U 1.9、VLC VLC是一款自由、开源的跨平台多媒体播放器及框架,可播放大多数多媒体文件,以及 DVD、音频 CD、VCD 及各类流媒体协议。 sudoapt-getinstallvlc-y 附带暗转媒体解码框架 sudoapt-add-repositoryppa:mc3man/trusty-media sudoapt-getupdatesudoapt-getinstallUbuntu-restricted-extrasffmpeggstreamer0.10-plugins-uglylibavcodec-extra-54libvdpau-va-gl1libmad0mpg321gstreamer1.0-libav 1.10、Kazam Kazam是 Ubuntu 上一款简易的桌面屏幕录制工具,它只能录制整个屏幕,可以录制声音,并可以快速上传录制好的视频到 YouTube 及 VideoBin 视频分享网站上。 sudoadd-apt-repositoryppa:and471/kazam-daily-builds sudoapt-getupdate sudoapt-getinstallkazam 1.11、Silentcast Silentcast是一款专注于GIF录制工具。 sudoadd-apt-repositoryppa:sethj/silentcast sudoapt-getupdate sudoapt-getinstallsilentcast 1.12、Smplayer Smplayer是一款开源的跨平台软件,其在Linux、Windows系统中有重要地位,影音播放能力很强大。 sudoapt-getinstallsmplayer 1.13、Audience Audience是一款简洁而强大的视频播放器,怎么说呢:简洁到不能再简洁。它是ElementaryOS系统默认的视频播放器,强烈推荐! sudoapt-getinstallaudience 1.14、Gimp Gimp是一个图片编辑器,优雅地取代windows、mac下的另一个ps软件。 sudoadd-apt-repositoryppa:otto-kesselgulasch/gimp sudoapt-getinstallgimp 1.15、Krita Krita是一个位图形编辑软件,包含一个绘画程式和照片编辑器。Krita是开源软件软件,Krita和gimp是有很大区别的,一句通俗的言语来表名:gimp是编辑图像用的,krita是画画用的。 sudoadd-apt-repositoryppa:kubuntu-ppa/backports sudoapt-getinstallkdelibs-binkbuildsycoca4--noincrementalkrita-y 1.16、gedit gedit是一个基于GNOME桌面环境下兼容UTF-8的文本编辑器。它使用GTK+编写而成,因此它十分的简单易用,有良好的语法高亮,对中文支持很好,支持包括gb2312、gbk在内的多种字符编码。甚至你可以配置成用于开发的IDEA,我才不折腾这个呢。 sudoapt-getinstallgedit 我还是经常习惯使用ElementaryOS自带的scratch-text-editor编辑器,不过它在ElementaryOS中使用搜狗输入法有一个bug:就是在非root下不能输入中文。 解决方案: #将原来的 Exec=scratch-text-editor%U X-GNOME-Gettext-Domain=scratch-text-editor#改成如下 Exec=envGTK_IM_MODULE=ximscratch-text-editor%U X-GNOME-Gettext-Domain=envGTK_IM_MODULE=ximscratch-text-editor 既然讲到了文本编辑器,肯定少不了vim,接触过linux的几乎都认识这家伙,我也不多说。Vim最少必要知识 1.17、x11vnc客户端 x11vnc是一种 位图显示的 视窗系统 。它是在 Unix 和 类Unix 操作系统 ,以及 OpenVMS 上建立图形用户界面的标准工具包和协议。x11vnc服务端可以实现Windows远程Linux桌面系统。 sudoapt-getinstallx11vnc 1.18、Shadowsocks-qt5 Shadowsocks-qt5是一个科学上网利器工具。在天朝莫谈国情,说说Shadowsocks原理就好,它是将原来 ssh 创建的 Socks5 协议拆开成 Server 端和 Client 端,两个端分别安装在境外服务器和境内设备上。 sudoadd-apt-repositoryppa:hzwhuang/ss-qt5 sudoapt-getupdate sudoapt-getinstallshadowsocks-qt5-y 1.19、VirtualBox VirtualBox是一款由德国 Innotek 公司开发的开源虚拟机软件。号称是最强的免费虚拟机软件,它不仅具有丰富的特色以及轻量级的体积,而且性能也很优异!可虚拟的系统包括所有的Windows系统、Mac OS X、Linux、OpenBSD、Solaris、IBM OS2甚至Android等操作系统!为了完整地使用VirtualBox,尽量安装VirtualBox Extension Pack。 #在官网下载对应版本的deb后执行 sudodpkg-i*.deb&&sudoapt-getinstall-fy 1.20、Steam Steam是一个整合游戏下载平台,很少玩游戏也不多少了#_# sudoapt-getinstallsteam 1.21、electronic-wechat electronic-wechat是一个基于nodeJS开发的Linux系统微信。 gitclonehttps://github.com/geeeeeeeeek/electronic-wechat.git cdelectronic-wechat npminstall&&npmstart 1.22、Skype Skype 是一款即时通讯软件,具备视频聊天、多人语音会议、传送文件、文字聊天等功能。它允许用户进行跨平台的视频呼叫,可与使用电脑、手机、电视、PSV 等多种终端的 Skype 用户进行视频通话。 1.23、 Transmission Transmission 是一个 BitTorrent 客户端软件,它支持速度限制、制作种子、远程控制、磁力链接、数据加密、损坏修复、数据来源交换等功能。 sudoapt-getinstalltransmission 1.24、 thunderbird thunderbird是又是一个简洁易用的邮箱客户端。 sudoapt-getinstallthunderbird 1.25、XMind XMind是一款实用的思维导图软件,简单易用、美观、功能强大,拥有高效的可视化思维模式,具备可扩展、跨平台。但是对于稳定性和性能还是欠佳,在ubuntu上使用占用很大的CPU资源。 #在官网下载对应版本的deb后执行 sudodpkg-i*.deb&&sudoapt-getinstall-fy 1.26、Okular Okular 是一个 PDF 文档阅读软件,支持 PDF、TIFF、CHM、ODF、EPUB、mobi 等文档格式。 sudoaptinstallokular-y 1.27、FocusWriter FocusWriter 是一款写作软件,为了让您的写作空间尽可能的多且不受打扰,FocusWriter 将几乎所有的工具栏都自动隐藏在屏幕边缘。利用 FocusWriter 写作便利流畅,您还可以设置闹钟和每日任务,非常适合撰稿人、小说写手、剧本作家使用。左蓝推荐! sudoaptinstallfocuswriter 1.28、Typora Typora是极简的Markdown编辑器,合并了写作和预览。支持表格、代码编辑,拖拽插图等,非常好用;喜欢它的原因也就是:美观、免费。 sudoapt-keyadv--keyserverkeyserver.ubuntu.com--recv-keysBA300B7755AFCFAE sudoadd-apt-repository'debhttps://typora.iolinux/' sudoapt-getupdate sudoapt-getinstalltypora 1.29、OBS Studio OBS Studio是一款跨平台的,开源的视频录制和在线直播客户端软件。我觉得一点不好的体验就是不能刻录整个屏幕。ymengyue推荐 sudoapt-getinstallffmpeg sudoadd-apt-repositoryppa:obsproject/obs-studio sudoapt-getupdate&&sudoapt-getinstallobs-studio 其他系统安装查看 1.30、Pencil Pencil是一款开源的原型图绘制工具,手绘风格的,就像自己在纸上画的那样。还可以用来绘制各种架构图和流程图,同时还提供 Firefox 的插件。对于经常做设计的人来说是一个不错的软件,可谓是linux下的visio。 wget-chttp://pencil.evolus.vn/dl/V3.0.1/Pencil_3.0.1_i386.deb sudodpkg-iPencil_3.0.1_i386.deb 1.31、Remmina Remmina是一个用远程桌面软件,提供了RDP、VNC、XDMCP、SSH等远程连接协议的支持。这个客户端最大的优点在于界面清爽,方便易用,创建远程连接的界面与Windows自带的远程桌面十分相近。可以到Linux软件管理器中搜索下载安装,十分方便. sudoapt-getinstallremmina 1.32、Meld Meld是针对开发者的视觉差异和合并工具。MELD帮助您比较文件、目录和版本控制的项目。它提供了两个和三个比较的文件和目录,并支持许多流行的版本控制系统。既可以查看差异有可以同步! sudoapt-getinstallmeld 二、系统工具篇 2.1、deepin-scrot deepin-scrot是深度团队开发的一个截图工具。在deepin深度系统作为默认的截图软件,在debian系统安装需要在终端命令使用,为了方便推荐定义快捷键配合使用。强烈推荐! #安装wgethttp://packages.linuxdeepin.com/deepin/pool/main/d/deepin-scrot/deepin-scrot_2.0-0deepin_all.deb sudodpkg-ideepin-scrot_2.0-0deepin_all.deb sudoapt-getinstall-f#使用deepin-scrot 2.2、Albert Spotlight Albert Spotlight是 Ubuntu的一项快速、随打即找、系统支援的桌面搜寻特色。spotlight 被设计为可以找到任何位于电脑中广泛的项目,包含文件、图片、音乐、应用程式、系统喜好设定控制台,也可以是文件或是PDF中指定的字。优雅地取代了Mac中的mac Spotlight。 sudoadd-apt-repositoryppa:noobslab/macbuntu sudoapt-getupdate sudoapt-getinstallalbert 2.3、Guake Terminal Guake是一个下拉式的gnome桌面环境下的终端程序,因此你只需要按一个键就可以调用他,然后再按一次以便隐藏他。Guake支持快捷键、标签、背景透明等特性。一句话:GuakeTerminal是linux下完美帅气的终端! sudoadd-apt-repositoryppa:webupd8team/unstable sudoapt-getupdate sudoapt-getinstallguake 2.4、bleachbit bleachbit是系统ubuntu系统减肥的一门"中药",用于清理系统没用的垃圾文件。 sudoadd-apt-repositoryppa:n-muench/programs-ppa sudoapt-getupdate sudoapt-getinstallbleachbit-y 2.5、psensor psensor是监控系统硬件实时状况的一款软件,使用psensor可视化显示系统温度,需要基于lm-sensors和hddtemp等获得的数据。因此你需要在安装psensor的同时,一并安装这两款工具。 sudoadd-apt-repositoryppa:jfi/ppa sudoapt-getupdate sudoapt-getinstalllm-sensorshddtemppsensor-y 2.6、Indicator Netspeed Indicator Netspeed是一款基于Unity的用于显示软件上传和下载网络流量的软件。 sudoadd-apt-repositoryppa:nilarimogard/webupd8 sudoapt-getupdate sudoapt-getinstallindicator-netspeed 2.7、gnome-system-monitor gnome-system-monito是一款基于GNOME桌面的系统监视器软件。不过使用它有点占内存,我还是习惯终端处理。 sudoapt-getinstallgnome-system-monitor 2.8、catfish catfish简称文件搜索神器。 sudoapt-getinstalcatfish 2.9、docky dockey是一款一个号称花钱也买不到的菜单启动器。为什么这麽说的?很简单:它是开源的,很简洁更美观。就连Mac下的docky都是模仿它的,O(∩_∩)O哈哈~,不要傻了,开玩笑的。 sudoapt-getinstalldocky 2.10、TLP TLP 是一款Linux流行的电源工具软件。你可以使用TLP来调整系统电池,有助于有更好延长电池寿命。 sudoadd-apt-repositoryppa:linrunner/tlp sudoapt-getupdate sudoapt-getinstalltlptlp-rdw sudotlpstart 2.11、menulibre menulibre是一个简洁易用的菜单编辑器。 sudoadd-apt-repositoryppa:menulibre-dev/devel sudoapt-getupdate sudoapt-getinstallmenulibre 2.12、indicator-sysmonitor indicator-sysmonitor是一个系统动态信息监控工具。可以实时查看电脑的cpu,内存占用率,更可以查看网速,非常方便 sudoadd-apt-repositoryppa:fossfreedom/indicator-sysmonitor sudoapt-getupdate sudoapt-getinstallindicator-sysmonitor 三、开发工具篇 3.1、Jetbrains 全家桶 Jetbrains_IDEA全家桶基基于java语言开的一个工具套餐,而且基本覆盖了主流的开发编程语言,还包含了开发ios/macOS的工具。Jetbrains_IDEA包含了哪些工具呢,看图、手累截图! Jetbrains 全家桶 3.2、Brackets Brackets是一款使用 HTML,CSS,JavaScript 创建的开源的针对 Web 开发的编辑器。它具有什么优秀的特性的呢:实时预览,快速编辑,跨平台,可扩展,开源,Brackets是一款非常优秀的编辑器,但是我就是不用它O(∩_∩)O哈哈~。 #天朝问题,漫长的等待,推荐下载安装sudoadd-apt-repositoryppa:webupd8team/brackets sudoapt-getupdate sudoapt-getinstallbrackets sudoadd-apt-repository-rppa:webupd8team/brackets 3.3、Android Studio Android Studio是啥我也就不说了,怕挨揍(^o^)/~用来开发安卓的~~~ 顺手推荐几个网站 镜像源androiddevtools 开源库codekk 3.4、Sublime Text Sublime Text是一个轻量、简洁、高效、跨平台的编辑器。不能再多解释了,只能简单说说它的优点: 可以编辑诸多主流的编程语言 语法高亮、代码提示补全、代码折叠、自定义皮肤/配色方案、多便签 代码地图、多种界面布局与全屏免打扰模式 完全开放的用户自定义配置与神奇实用的编辑状态恢复功能 雷电般快速的文件切换 随心所欲的跳转:快速罗列与定位函数/HTML的元素、跳转到指定行 集所有功能于一身的命令面板 Package Contro扩展包管理器 3.5、Atom Atom是GitHub推出的一款基于Web技术开发的桌面端的编辑器,其主要的特点是现代, 易用, 可定制。被称为21世纪的黑客编辑器我就笑笑O(∩_∩)O哈哈~ sudoadd-apt-repositoryppa:webupd8team/atom sudoapt-getupdate sudoapt-getinstallatom 3.6、sqliteman sqliteman是一款小巧的图形化管理SQLite数据库的软件。轻量级、小巧、功能全面。为它点个赞,推荐! sudoapt-getinstallsqliteman 3.7、Git、GitG Git是一个开源的分布式版本控制系统,可以有效、高速的处理从很小到非常大的项目版本管理。简而言之就是代码管理工具,常用Git命令记录。既然提到了Git,那么也要说说它的朋友SVN,同样它俩的性质是一样的不必多说,SVN的安装与基本使用 sudoapt-getinstallgit gitg是一个用于查看Git版本控制系统的工具,基于Gnome桌面环境。我还是习惯在终端干这些活。 sudoapt-getinstallgitg 3.8、MySQL workbench MySQL workbench是一款专为MySQL设计的ER/数据库建模工具,但是在ElementaryOS还是存在不少的问题的。 #在官网下载对应版本的deb后执行 sudodpkg-i*.deb&&sudoapt-getinstall-fy 3.9、monodevelop MonoDevelop 是个适用于Linux、Mac和Windows的开放源代码集成开发环境,目前支持的语言有Python、Vala、C#、Java、BOO、Nemerle、Visual Basic .NET、CIL、C与C++。 sudoapt-getinstallmonodevelopg++xterm-y 3.9、Genymotion Genymotion是一套完整的工具,它提供了Android虚拟环境,支持Windows、Linux和Mac OS等操作系统,容易安装和使用。开发安卓选择Genymotion模拟器是最佳的选择,除非你使用真机,其实后来我就是选择真机的——笑:-D。 #在官网下载对应版本的deb后执行,需要注册后才能下载 sudodpkg-i*.deb&&sudoapt-getinstall-fy 3.10、Android Screen Monitor Android Screen Monitor简称ASM,是一款监视手机或者模拟器屏幕的工具。 时光机传送安装与使用教程 四、Terminal Tools 4.1、enca、iconv enca、iconv都是文件编码转换工具。 #安装sudoapt-getencaiconv 简单使用 #enca查看文件编码encafilename#iconv将一个GBK编码的文件转换成UTF-8编码enconv-Lzh_CN-xUTF-8filename 4.2、Figlet 一句话:Figlet是一个将字符串在终端生成一个logo的终端工具。 sudoapt-getinstallfiglet 4.3、oh-my-zsh oh-my-zsh是终极Shell,就这么一句话! sudoapt-getinstallgit-ywgethttps://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh-O-|sh zsh的配置文件位于用户目录/home/$USER/.zshrc,zsh主题,我的配置文件部分如下: #oh-my-zsh的安装路径exportZSH=/home/alic/.oh-my-zsh#主题设置ZSH_THEME="robbyrussell"#大小写是否敏感CASE_SENSITIVE="false"#连字符敏感HYPHEN_INSENSITIVE="true"#zsh是否自动不更新DISABLE_AUTO_UPDATE="true"plugins=(git) source$ZSH/oh-my-zsh.sh#语言环境exportLANG=en_US.UTF-8 4.4、Asciinema Asciinema是一个用 ClojureScript 编写的开源命令行录屏工具。对于详细的终端刻录工具可以查看Linux 终端录制工具。 sudoapt-add-repositoryppa:zanchey/asciinema sudoapt-getupdatesudoapt-getinstallasciinema 录制使用 asciinemarec 使用 exit 或者 Ctrl+D快捷键结束录制。它会在结束录制的时候提示,如果要上传的话,敲回车。上传之后,Asciinema 会给出一个网址。 #想嵌入网页<scripttype="text/javascript"src="https://asciinema.org/a/2xcuc0651qtirbj8dkmmtf2nf.js"id="asciicast-https://asciinema.org/a/2xcuc0651qtirbj8dkmmtf2nf"async></script> 4.5、Aria2 aria2是 Linux 下一个命令行下轻量级、多协议、多来源的高速下载工具。 sudoapt-getinstallaria2 使用说明 #简单使用:只需要加上下载链接即可aria2c${link}#分段下载aria2c-s2${link} Aria2 在百度云环境可以不限速下载,传送Aria2 - 可能是现在下载百度云资料速度最快的方式 4.6、Proxychains4 Proxychains4是一个终端挂代理的工具,可自由切换代理。使用简单只需要在命令前加上proxychains4即可! gitclonehttps://github.com/rofl0r/proxychains-ng.gitcdproxychains-ng sudo./configure–prefix=/usr–sysconfdir=/etc sudomake&&sudomakeinstall&&sudomakeinstall-configcd..&&rm-rfproxychains-ng 配置文件位于/usr/local/etc/proxychains.conf 将socks4 127.0.0.1 9095改为 socks5 127.0.0.1 ${port} {$user} ${pwd} 4.7、Ubuntu Make Ubuntu Make 原名 Ubuntu Developer Tools Center,是一款开源的命令行工具软件,主要是针对开发者,它可以安装大量的开发工具。 sudoadd-apt-repositoryppa:ubuntu-desktop/ubuntu-make sudoapt-getupdate sudoapt-getinstallubuntu-make 比如安装Webstorm sudoumakeidewebstorm 4.8、sshfs SSHFS最炫的地方在于可在本地安装的文件系统中,通过SSH获得所有加密的通信优势。sshfs 是基于 FUSE构建的 SSH 文件系统客户端程序,通过它远程主机的配置无需作任何改变,就可以透过 SSH 协议来挂载远程文件系统了,非常方便及安全。 sudo apt-getinstall sshfs 文章摘自运维派 微信 转载请注明出处 本文转自 ChinaUnicom110 51CTO博客,原文链接:http://blog.51cto.com/xingyue2011/1948651

资源下载

更多资源
Mario

Mario

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

Spring

Spring

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

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册