https://www.suse.com/documentation/sles11/book_sle_tuning/data/part_tuning_kernel.html

http://blog.csdn.net/maimang1001/article/details/34941471

https://www.suse.com/documentation/sles11/book_sle_tuning/data/sec_tuning_network_buffers.html

http://dirtysalt.info/os.html

Linux

1 vmlinuz

vmlinuz是可引导的、压缩的内核。“vm”代表“Virtual Memory”。Linux 支持虚拟内存,不像老的操作系统比如DOS有640KB内存的限制。Linux能够使用硬盘空间作为虚拟内存,因此得名“vm”。vmlinuz是可执行的Linux内核,它位于/boot/vmlinuz,它一般是一个软链接。vmlinux是未压缩的内核,vmlinuz是vmlinux的压缩文件。

vmlinuz的建立有两种方式。一是编译内核时通过“make zImage”创建,然后通过:“cp /usr/src/linux-2.4/arch/i386/linux/boot/zImage /boot/vmlinuz”产生。zImage适用于小内核的情况,它的存在是为了向后的兼容性。二是内核编译时通过命令make bzImage创建,然后通过:“cp /usr/src/linux-2.4/arch/i386/linux/boot/bzImage /boot/vmlinuz”产生。bzImage是压缩的内核映像,需要注意,bzImage不是用bzip2压缩的,bzImage中的bz容易引起误解,bz表示“big zImage”。 bzImage中的b是“big”意思。

zImage(vmlinuz)和bzImage(vmlinuz)都是用gzip压缩的。它们不仅是一个压缩文件,而且在这两个文件的开头部分内嵌有gzip解压缩代码。所以你不能用gunzip 或 gzip –dc解包vmlinuz。内核文件中包含一个微型的gzip用于解压缩内核并引导它。两者的不同之处在于,老的zImage解压缩内核到低端内存(第一个640K),bzImage解压缩内核到高端内存(1M以上)。如果内核比较小,那么可以采用zImage或bzImage之一,两种方式引导的系统运行时是相同的。大的内核采用bzImage,不能采用zImage。

2 TCP IO

2.1 create connection

下面摘自 "Linux TCP队列相关参数的总结":

简单看下连接的建立过程,客户端向server发送SYN包,server回复SYN+ACK,同时将这个处于SYN_RECV状态的连接保存到半连接队列。客户端返回ACK包完成三次握手,server将ESTABLISHED状态的连接移入accept队列,等待应用调用accept()。可以看到建立连接涉及两个队列:

  • 半连接队列,保存SYN_RECV状态的连接。队列长度由net.ipv4.tcp_max_syn_backlog设置。
  • accept队列,保存ESTABLISHED状态的连接。队列长度为min(net.core.somaxconn, backlog). # listen(sockfd, backlog)

另外,为了应对SYN flooding(即客户端只发送SYN包发起握手而不回应ACK完成连接建立,填满server端的半连接队列,让它无法处理正常的握手请求),Linux实现了一种称为SYN cookie的机制,通过net.ipv4.tcp_syncookies控制,设置为1表示开启。简单说SYN cookie就是将连接信息编码在ISN(initial sequence number)中返回给客户端,这时server不需要将半连接保存在队列中,而是利用客户端随后发来的ACK带回的ISN还原连接信息,以完成连接的建立,避免了半连接队列被攻击SYN包填满。对于一去不复返的客户端握手,不理它就是了。

2.2 packet reception

整个流程大致如下:

  • linux里面使用sk_buff数据结构来描述packet.
  • NIC检测到packet到达,从Kernel Memory(sk_buffs)分配sk_buff数据结构,调用DMA Engine将packet放到sk_buff数据结构里面 #note: NIC检测有packet到达和有packet发送,都不是触发而是主动poll的方式来完成的
  • 将sk_buff并且加入rx_ring这个ring_buffer里面。如果rx_ring满了的话那么将packet丢弃。
  • 当DMA Engine完成处理之后, NIC通过向CPU发起中断 通知kernel进行处理。
  • kernel将这个packet传递给IP层进行处理。IP层需要将信息组装成为ip packet。如果ip packet是tcp的话那么放到socket backlog里面。如果socket backlog满了的话那么将ip packet丢弃。 copy packet data to ip buffer to form ip packet #note: 这个步骤完成之后IP layer就可以释放sk_buffer结构
  • tcp layer从socket backlog里面取出tcp packet, copy ip packet tcp recv buffer to form tcp packet
  • tcp recv buffer交给application layer处理, copy tcp recv buffer to app buffer to form app packet
  • 其中内核参数有
    • /proc/sys/net/ipv4/tcp_rmem # tcp recv buffer大小
    • /proc/sys/net/core/netdev_max_backlog # 图中socket backlog大小,和accept系统调用的backlog区分开。

下面这些是从文章摘取出来的

Linux在2.6.17以后增加了recv Buffer自动调节机制,recv buffer的实际大小会自动在最小值和最大值之间浮动,以期找到性能和资源的平衡点,因此大多数情况下不建议将recv buffer手工设置成固定值。

当net.ipv4.tcp_moderate_rcvbuf设置为1时,自动调节机制生效,每个TCP连接的recv Buffer由下面的3元数组指定:net.ipv4.tcp_rmem = (min, default, max). 最初recv buffer被设置为<default>,同时这个缺省值会覆盖net.core.rmem_default的设置。随后recv buffer根据实际情况在最大值和最小值之间动态调节。在缓冲的动态调优机制开启的情况下,我们将net.ipv4.tcp_rmem的最大值设置为BDP(Bandwidth-Delay Product)。

当net.ipv4.tcp_moderate_rcvbuf被设置为0,或者设置了socket选项SO_RCVBUF,缓冲的动态调节机制被关闭。recv buffer的缺省值由net.core.rmem_default设置,但如果设置了net.ipv4.tcp_rmem,缺省值则被覆盖。可以通过系统调用setsockopt()设置recv buffer的最大值为net.core.rmem_max。在缓冲动态调节机制关闭的情况下,建议把缓冲的缺省值设置为BDP。

发送端缓冲的自动调节机制很早就已经实现,并且是无条件开启,没有参数去设置。如果指定了tcp_wmem,则net.core.wmem_default被tcp_wmem的覆盖。send Buffer在tcp_wmem的最小值和最大值之间自动调节。如果调用setsockopt()设置了socket选项SO_SNDBUF,将关闭发送端缓冲的自动调节机制,tcp_wmem将被忽略,SO_SNDBUF的最大值由net.core.wmem_max限制。

2.3 packet transmission

整个流程大致如下:

  • application layer将数据copy到tcp send buffer里面,如果空间不够的话那么就会出现阻塞。 copy app buffer to tcp send buffer as app packet
  • tcp layer等待tcp send buffer存在数据或者是需要做ack的时候,组装ip packet推送到IP layer copy tcp send buffer to ip send buffer as tcp packet
  • IP layer从kernel memory申请sk_buffer,将ip data包装成为packet data,然后塞到qdisc(txqueuelen控制队列长度)里面(指针)。如果队列满的话那么就会出现阻塞,反馈到tcp layer阻塞。copy ip send buffer to packet data as ip packet
  • NIC driver如果检测到qdisc有数据的话,调用NIC DMA Engine将packet发送出去。发送完成之后NIC向CPU发起中断释放packet data内存到Kernel Memory
  • 其中内核参数有:
    • /proc/sys/net/ipv4/tcp_wmem 这个和rmem非常类似
    • #note: 与上面类比,相关参数还有net.core.wmem_default和net.core.wmem_max.

#note: 在wangyx的帮助下, qdisc队列长度参数txqueuelen这个配置在ifconfig下面找到了. txqueuelen = 1000.

➜  ~  ifconfig
eth0 Link encap:Ethernet HWaddr 12:31:40:00:49:d1
inet addr:10.170.78.31 Bcast:10.170.79.255 Mask:255.255.254.0
inet6 addr: fe80::1031:40ff:fe00:49d1/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:13028359 errors:0 dropped:0 overruns:0 frame:0
TX packets:9504902 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2464083770 (2.4 GB) TX bytes:20165782073 (20.1 GB)
Interrupt:25

下面摘自: Linux TCP队列相关参数的总结

QDisc(queueing discipline )位于IP层和网卡的ring buffer之间。我们已经知道,ring buffer是一个简单的FIFO队列,这种设计使网卡的驱动层保持简单和快速。而QDisc实现了流量管理的高级功能,包括流量分类,优先级和流量整形(rate-shaping)。可以使用tc命令配置QDisc。

QDisc的队列长度由txqueuelen设置,和接收数据包的队列长度由内核参数net.core.netdev_max_backlog控制所不同,txqueuelen是和网卡关联

2.4 congestion control

  • 初始状态是slow start
  • cwnd(congestion window) 拥塞窗口,表示一次最多发送的数据包多少。
  • ssthresh(slow start threshold) 慢速启动阈值。
  • MSS(maximum segment size) 最大分节大小,和传输网络的MTU相关。
  • 为什么多 TCP 连接分块下载比单连接下载快?

3 kernel panic

5 程序返回值问题

首先看下面一段Java程序

/* coding:utf-8
* Copyright (C) dirlt
*/ public class X{
public static void main(String[] args) {
System.exit(1);
}
}

然后这个Java程序被Python调用,判断这个打印值

#!/usr/bin/env python
#coding:utf-8
#Copyright (C) dirlt import os
print os.system('java X')

返回值不为1而是256,对此解释是这样的

a 16-bit number, whose low byte is the signal number that killed the process, and whose high byte is the exit status (if the signal number is zero); the high bit of the low byte is set if a core file was produced.

但是下面这段Python程序,使用echo $?判断返回值为0而不是256

#!/usr/bin/env python
#coding:utf-8
#Copyright (C) dirlt code=256
exit(code)

6 dp8网卡问题

当时dp8的网络流量从一个非常大的值变为非常小的值,检查/proc/net/netstat,以下几个统计数值dp8和其他机器差距较大(相差1-2个数量级):

  • TCPDirectCopyFromPrequeue
  • TCPHPHitsToUser
  • TCPDSACKUndo
  • TCPLossUndo
  • TCPLostRetransmit
  • TCPFastRetrans
  • TCPSlowStartRetrans
  • TCPSackShiftFallback

之后在dmesg上面发现如下线索:

dp@dp8:~$ dmesg | grep eth0
[ 15.635160] eth0: Broadcom NetXtreme II BCM5716 1000Base-T (C0) PCI Express f
[ 15.736389] bnx2: eth0: using MSIX
[ 15.738263] ADDRCONF(NETDEV_UP): eth0: link is not ready
[ 37.848755] bnx2: eth0 NIC Copper Link is Up, 100 Mbps full duplex
[ 37.850623] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 1933.934668] bnx2: eth0: using MSIX
[ 1933.936960] ADDRCONF(NETDEV_UP): eth0: link is not ready
[ 1956.130773] bnx2: eth0 NIC Copper Link is Up, 100 Mbps full duplex
[ 1956.132625] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[4804526.542976] bnx2: eth0 NIC Copper Link is Down
[4804552.008858] bnx2: eth0 NIC Copper Link is Up, 100 Mbps full duplex

日志 [4804552.008858] bnx2: eth0 NIC Copper Link is Up, 100 Mbps full duplex 表明dp8上的网卡速度被识别成100 Mbps了。

可能的原因如下:

  • 网线、水晶头质量太差或老化、水晶头没压好,从而导致网线接触不良或短路等,可以重新压水晶头或更换网线,建议用质量可靠的六类网线六类水晶头
  • 本地连接―右键―属性―配置―高级―速度和双工,这里设置错误,改为自动感应或1000Mbps全双工即可
  • 网卡所接的交换机或路由器等硬件设备出现故障,或者这些设备是百兆的(千和百连在一起,千变百向下兼容)
  • 电磁场干扰有时也会变百兆,所以说网线尽量别与电线一起穿管(论坛会员tchack友情提供)

我们的网线都是由 世xx联 提供的,质量应该不错,有两种情况需要优先排除。

  • 网线问题(测试方法:换根网线试试)
  • 交换机dp8连接的口坏了(测试方法:把dp8的网线换一个交换机的口)

7 修改资源限制

临时的修改方式可以通过ulimit来进行修改,也可以通过修改文件/etc/security/limits.conf来永久修改

hadoop - nofile 102400
hadoop - nproc 40960

8 CPU温度过高

这个问题是我在Ubuntu PC上面遇到的,明显的感觉就是运行速度变慢。然后在syslog里面出现如下日志:

May  2 18:24:21 umeng-ubuntu-pc kernel: [ 1188.717609] CPU1: Core temperature/speed normal
May 2 18:24:21 umeng-ubuntu-pc kernel: [ 1188.717612] CPU0: Package temperature above threshold, cpu clock throttled (total events = 137902)
May 2 18:24:21 umeng-ubuntu-pc kernel: [ 1188.717615] CPU2: Package temperature above threshold, cpu clock throttled (total events = 137902)
May 2 18:24:21 umeng-ubuntu-pc kernel: [ 1188.717619] CPU1: Package temperature above threshold, cpu clock throttled (total events = 137902)
May 2 18:24:21 umeng-ubuntu-pc kernel: [ 1188.717622] CPU3: Package temperature above threshold, cpu clock throttled (total events = 137902)

9 sync hangup

10 更换glibc

@2013-05-23 https://docs.google.com/a/umeng.com/document/d/12dzJ3OhVlrEax3yIdz0k08F8tM8DDQva1wdrD3K49PI/edit 怀疑glibc版本存在问题,在dp45上操作但是出现问题。

我的操作顺序计划是这样的:

  1. 将dp20的glibc copy到自己的目录下面/home/dp/dirlt/libc-2.11.so
  2. 将dp45的glibc backup. mv /lib64/libc-2.12.so /lib64/libc-2.12.bak.so(补充一点,就是在lib64下面还有软链接 libc.so.6 -> libc-2.12.so,这个文件应该是被程序查找使用的)
  3. cp /home/dp/dirlt/libc-2.11.so /lib64/libc-2.12.so

但是进行到2之后就发现cp不可用了,并且ls等命令也不能够使用了。原因非常简单,就是因为2之后libc.so.6没有对应的文件了,而cp,ls这些基本的命令依赖于这个动态链接库。

~ $ ldd /bin/cp
linux-vdso.so.1 => (0x00007fff9717f000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f5efb804000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f5efb5fc000)
libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007f5efb3f3000)
libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007f5efb1ee000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5efae2f000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f5efac2a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5efba2d000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f5efaa0d000)

@2013-08-03

A copy of the C library was found in an unexpected directory | Blog : http://blog.i-al.net/2013/03/a-copy-of-the-c-library-was-found-in-an-unexpected-directory/

上面的链接给出了升级glibc的方法

  • sudo su - root # 首先切换到root账号下面
  • mv libc.so librt.so /root # 将glibc等相关的so移动到root账号下面,主要不要移动软连接文件。
  • LD_PRELOAD=/root/libc.so:/root/librt.so bash # 这个时候如果执行bash是找不到glibc等so了,所以需要使用LD_PRELOAD来预先加载
  • apt-get install # 在这个bash下面使用apt-get来安装和升级glibc.

11 允许不在tty上执行sudo

修改/etc/sudoers文件,注释掉

Defaults requiretty

12 ssh proxy

http://serverfault.com/questions/37629/how-do-i-do-multihop-scp-transfers

  • 目的机器是D,端口是16021,用户是x
  • 跳板机器是T,端口是18021,用户是y
  • client需要和x@D以及y@T建立信任关系
  • 方法A
    • 从T上和D建立链接并且配置转发端口p, 所有和T:p的数据交互都会转发到D:16021
    • 在T上执行 ssh -L "*:5502:D:16021" x@D # 转发端口是5502
      • -o ServerAliveInterval=60 # 我才想单位应该是s。这样每隔60s可以和server做一些keepalive的通信,确保长时间没有数据通信的情况下,连接不会断开。
    • ssh -p 5502 x@T 或者 scp -P 5502 <file> x@T:<path-at-D>
  • 方法B
    • scp可以指定proxyCommand配合D上nc命令完成
    • scp -o ProxyCommand="ssh -p 18021 y@T 'nc D 16021'" <file> x@D:<path-at-D>

13 修改最大打开文件句柄数

首先需要修改系统上限

  • /proc/sys/fs/file-max # 所有进程打开文件句柄数上限
  • /proc/sys/fs/nr_open # 单个进程打开文件句柄数上限
  • /proc/sys/fs/file-nr # 系统当前打开文件句柄数

然后修改用户(进程)使用上限

  • /etc/security/limits.conf
  • ulimit

14 apt-get hang

在使用ubuntu的apt-get时候,可能会出现一些异常的状况,我们直接终止了apt-get。但是这个时候apt-get软件本身出于一个不正常的状态,导致之后不能够启动apt-get。如果观察进程的话会出现下面一些可疑的进程

dp@dp1:~$ ps aux | grep "apt"
root 3587 0.0 0.0 36148 22800 ? Ds Oct08 0:00 /usr/bin/dpkg --status-fd 50 --unpack --auto-deconfigure /var/cache/apt/archives/sgml-data_2.0.4_all.deb
root 9579 0.0 0.0 35992 22744 ? Ds Oct19 0:00 /usr/bin/dpkg --status-fd 50 --unpack --auto-deconfigure /var/cache/apt/archives/iftop_0.17-16_amd64.deb
root 25957 0.0 0.0 36120 22796 ? Ds Nov05 0:00 /usr/bin/dpkg --status-fd 50 --unpack --auto-deconfigure /var/cache/apt/archives/iftop_0.17-16_amd64.deb /var/cache/apt/archives/iotop_0.4-1_all.deb
dp 30586 0.0 0.0 7628 1020 pts/2 S+ 08:59 0:00 grep --color=auto apt

这些进程的父进程都是init进程,并且状态是uninterruptible sleep,给kill -9也没有办法终止,唯一的办法只能reboot机器来解决这个问题。关于这个问题可以看stackoverflow上面的解答 How to stop 'uninterruptible' process on Linux? - Stack Overflow http://stackoverflow.com/questions/767551/how-to-stop-uninterruptible-process-on-linux

  • Simple answer: you cannot. Longer answer: the uninterruptable sleep means the process will not be woken up by signals. It can be only woken up by what it's waiting for. When I get such situations eg. with CD-ROM, I usually reset the computer by using suspend-to-disk and resuming.
  • The D state basically means that the process is waiting for disk I/O, or other block I/O that can't be interrupted. Sometimes this means the kernel or device is feverishly trying to read a bad block (especially from an optical disk). Sometimes it means there's something else. The process cannot be killed until it gets out of the D state. Find out what it is waiting for and fix that. The easy way is to reboot. Sometimes removing the disk in question helps, but that can be rather dangerous: unfixable catastrophic hardware failure if you don't know what you're doing (read: smoke coming out).

15 使用自选锁来实现信号量

typedef struct sema
{
lock_t lock;
int count;
queue q;
} sema_t; void init_sema(sema_t* sema, int init_cnt)
{
init_lock(&sema->lock);
init_queue(&sema->q);
sema->count=init_cnt;
} void p(sema_t* sema)
{
lock(&sema->lock);
sema->count--;
if (sema->count < 0) {
q.push(current_process_context());
unlock(&sema->lock);
swtch(); // switch to another process.
return;
}
unlock(&sema->lock);
} void v(sema_t* sema)
{
lock(&sema->lock);
sema->count++;
if (sema->count <= 0) {
pcs_ctx* ctx = q.pop();
unlock(&sema->lock);
enqueue(&running_queue, ctx);
return ;
}
unlock(&sema->lock);
}

linux 内核参数图解的更多相关文章

  1. Linux内核参数配置

    Linux在系统运行时修改内核参数(/proc/sys与/etc/sysctl.conf),而不需要重新引导系统,这个功能是通过/proc虚拟文件系统实现的. 在/proc/sys目录下存放着大多数的 ...

  2. 优化Linux内核参数/etc/sysctl.conf sysctl 《高性能Linux服务器构建实战:运维监控、性能调优与集群应用》

    优化Linux内核参数/etc/sysctl.conf  sysctl  <高性能Linux服务器构建实战:运维监控.性能调优与集群应用> http://book.51cto.com/ar ...

  3. 修改Linux内核参数提高Nginx服务器并发性能

    当linux下Nginx达到并发数很高,TCP TIME_WAIT套接字数量经常达到两.三万,这样服务器很容易被拖死.事实上,我们可以简单的通过修改Linux内核参数,可以减少Nginx服务器 的TI ...

  4. linux 内核参数优化

    Sysctl命令及linux内核参数调整   一.Sysctl命令用来配置与显示在/proc/sys目录中的内核参数.如果想使参数长期保存,可以通过编辑/etc/sysctl.conf文件来实现.   ...

  5. linux内核参数注释与优化

    目录 1.linux内核参数注释 2.两种修改内核参数方法 3.内核优化参数生产配置 参数解释由网络上收集整理,常用优化参数对比了网上多个实际应用进行表格化整理,使查看更直观. 学习linux也有不少 ...

  6. Linux 内核参数 arp_ignore & arp_announce 详解

    arp_ignore定义了对目标地址为本机IP的ARP询问的不同应答模式. arp_announce对网络接口(网卡)上发出的ARP请求包中的源IP地址作出相应的限制:主机会根据这个参数值的不同选择使 ...

  7. Linux Linux内核参数调优

    Linux内核参数调优 by:授客 QQ:1033553122 关于调优的建议: 1.出错时,可以查看操作系统日志,可能会找到一些有用的信息 2.尽量不要“批量”修改内核参数,笔者就曾这么干过,结果“ ...

  8. 转载:Linux内核参数的优化(1.3.4)《深入理解Nginx》(陶辉)

    原文:https://book.2cto.com/201304/19615.html 由于默认的Linux内核参数考虑的是最通用的场景,这明显不符合用于支持高并发访问的Web服务器的定义,所以需要修改 ...

  9. Linux内核参数基础优化

    web 服务负载均衡器常规网站服务器优化的基本配置: net.ipv4.tcp_fin_timeout =2 net.ipv4.tcp_tw_reuse =1 net.ipv4.tcp_tw_recy ...

随机推荐

  1. Chapter 7 Windows下pycaffe的使用之draw_net.py

    Chapter 6 中完成了在Windows下,对pycaffe的编译,如果编译存在问题,请参考:http://www.cnblogs.com/xiaopanlyu/p/6158902.html 本文 ...

  2. 《学习OpenCV》练习题第四章第二题

    #include <highgui.h> #include <cv.h> #pragma comment (lib,"opencv_calib3d231d.lib&q ...

  3. ruby 安装更新

    wget http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.2.tar.gz tar xfvz ruby-2.2.2.tar.gz cd ruby-2. ...

  4. openstack network

  5. 转自 处理老版PIL 到 pillow

    帮新同事部署开发环境, 由于项目代码里用到了PIL库处理图片, 导致一些图片在浏览器中无法正常显示.  几番折腾, 解决了问题, 这里记录一下报的问题, 及解决方法: 1. python版本不对, 6 ...

  6. 恢复HDFS误删数据

    [恢复HDFS误删数据] HDFS会为每一个用户创建一个回收站目录:/user/用户名/.Trash/,每一个被用户通过Shell删除的文件/目录,在系统回收站中都一个周期,也就是当系统回收站中的文件 ...

  7. 创建svn仓库脚本

    #!/bin/bash svnadmin create $1 cp /home/svndata/conf/svnserver.conf /home/svndata/$1/conf/svnserve.c ...

  8. POJ 3172 Scales (01背包暴力)

    题意:给定 n 个数,保证下一个数比上一个数和前一个数之和大,然后给定一个背包,问你最多放多少容积. 析:应该是很明显的01背包,但是可惜的是,数组开不出来,那就得考虑暴力,因为数不多,才几十而已,要 ...

  9. 代码中设置excel自定义格式为[红色]的处理方法

    有时候,excel的自定义格式设置时 ,会遇到需要设置为¥#,##0;[红色]¥-#,##0的格式. 其中会带一个颜色标记,但是如果这样的一句代码,放在英文版的Office里面,就失效了,因为英文版应 ...

  10. 解决sencha touch显示.JSON包含中文数据时显示乱码问题

    按照ST官方示例navigationview做的一个示例.数据源是一个.json文件.但是显示的时候如果.json文件里有中文则乱码.我知道是编码问题,但是不知道怎么改,如何改. 问了N个人最后解决方 ...